ActivityManagerService.java revision f5c5ac231dea02c8041d84ac006e0df878e3f28b
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.Looper;
174import android.os.Message;
175import android.os.Parcel;
176import android.os.ParcelFileDescriptor;
177import android.os.PersistableBundle;
178import android.os.PowerManager;
179import android.os.PowerManagerInternal;
180import android.os.Process;
181import android.os.RemoteCallbackList;
182import android.os.RemoteException;
183import android.os.ResultReceiver;
184import android.os.ServiceManager;
185import android.os.StrictMode;
186import android.os.SystemClock;
187import android.os.SystemProperties;
188import android.os.Trace;
189import android.os.TransactionTooLargeException;
190import android.os.UpdateLock;
191import android.os.UserHandle;
192import android.os.UserManager;
193import android.os.WorkSource;
194import android.os.storage.IMountService;
195import android.os.storage.MountServiceInternal;
196import android.os.storage.StorageManager;
197import android.provider.Settings;
198import android.service.voice.IVoiceInteractionSession;
199import android.service.voice.VoiceInteractionManagerInternal;
200import android.service.voice.VoiceInteractionSession;
201import android.text.format.DateUtils;
202import android.text.format.Time;
203import android.util.ArrayMap;
204import android.util.ArraySet;
205import android.util.AtomicFile;
206import android.util.DebugUtils;
207import android.util.EventLog;
208import android.util.LocaleList;
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.Set;
244import java.util.concurrent.atomic.AtomicBoolean;
245import java.util.concurrent.atomic.AtomicLong;
246
247import dalvik.system.VMRuntime;
248
249import libcore.io.IoUtils;
250import libcore.util.EmptyArray;
251
252import static android.Manifest.permission.INTERACT_ACROSS_USERS;
253import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
254import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
255import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
256import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
257import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
258import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
259import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
260import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.HOME_STACK_ID;
263import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
264import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
265import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
266import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
267import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
268import static android.content.pm.PackageManager.GET_PROVIDERS;
269import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
270import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
271import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
272import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
273import static android.content.pm.PackageManager.PERMISSION_GRANTED;
274import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
275import static android.provider.Settings.Global.DEBUG_APP;
276import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
277import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
278import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
279import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
280import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
281import static android.provider.Settings.System.FONT_SCALE;
282import static com.android.internal.util.XmlUtils.readBooleanAttribute;
283import static com.android.internal.util.XmlUtils.readIntAttribute;
284import static com.android.internal.util.XmlUtils.readLongAttribute;
285import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
286import static com.android.internal.util.XmlUtils.writeIntAttribute;
287import static com.android.internal.util.XmlUtils.writeLongAttribute;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
344import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
345import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
346import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
347import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
348import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
349import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
350import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
351import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
352import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
353import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
354import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
355import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
356import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
357import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
358import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
359import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
360import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
361import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
362import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
363import static org.xmlpull.v1.XmlPullParser.START_TAG;
364
365public final class ActivityManagerService extends ActivityManagerNative
366        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
367
368    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
369    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
370    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
371    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
372    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
373    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
374    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
375    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
376    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
377    private static final String TAG_LRU = TAG + POSTFIX_LRU;
378    private static final String TAG_MU = TAG + POSTFIX_MU;
379    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
380    private static final String TAG_POWER = TAG + POSTFIX_POWER;
381    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
382    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
383    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
384    private static final String TAG_PSS = TAG + POSTFIX_PSS;
385    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
386    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
387    private static final String TAG_STACK = TAG + POSTFIX_STACK;
388    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
389    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
390    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
391    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
392    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
393
394    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
395    // here so that while the job scheduler can depend on AMS, the other way around
396    // need not be the case.
397    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
398
399    /** Control over CPU and battery monitoring */
400    // write battery stats every 30 minutes.
401    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
402    static final boolean MONITOR_CPU_USAGE = true;
403    // don't sample cpu less than every 5 seconds.
404    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
405    // wait possibly forever for next cpu sample.
406    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
407    static final boolean MONITOR_THREAD_CPU_USAGE = false;
408
409    // The flags that are set for all calls we make to the package manager.
410    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
411
412    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
413
414    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
415
416    // Amount of time after a call to stopAppSwitches() during which we will
417    // prevent further untrusted switches from happening.
418    static final long APP_SWITCH_DELAY_TIME = 5*1000;
419
420    // How long we wait for a launched process to attach to the activity manager
421    // before we decide it's never going to come up for real.
422    static final int PROC_START_TIMEOUT = 10*1000;
423    // How long we wait for an attached process to publish its content providers
424    // before we decide it must be hung.
425    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
426
427    // How long we will retain processes hosting content providers in the "last activity"
428    // state before allowing them to drop down to the regular cached LRU list.  This is
429    // to avoid thrashing of provider processes under low memory situations.
430    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
431
432    // How long we wait for a launched process to attach to the activity manager
433    // before we decide it's never going to come up for real, when the process was
434    // started with a wrapper for instrumentation (such as Valgrind) because it
435    // could take much longer than usual.
436    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
437
438    // How long to wait after going idle before forcing apps to GC.
439    static final int GC_TIMEOUT = 5*1000;
440
441    // The minimum amount of time between successive GC requests for a process.
442    static final int GC_MIN_INTERVAL = 60*1000;
443
444    // The minimum amount of time between successive PSS requests for a process.
445    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
446
447    // The minimum amount of time between successive PSS requests for a process
448    // when the request is due to the memory state being lowered.
449    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
450
451    // The rate at which we check for apps using excessive power -- 15 mins.
452    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
453
454    // The minimum sample duration we will allow before deciding we have
455    // enough data on wake locks to start killing things.
456    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
457
458    // The minimum sample duration we will allow before deciding we have
459    // enough data on CPU usage to start killing things.
460    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
461
462    // How long we allow a receiver to run before giving up on it.
463    static final int BROADCAST_FG_TIMEOUT = 10*1000;
464    static final int BROADCAST_BG_TIMEOUT = 60*1000;
465
466    // How long we wait until we timeout on key dispatching.
467    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
468
469    // How long we wait until we timeout on key dispatching during instrumentation.
470    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
471
472    // This is the amount of time an app needs to be running a foreground service before
473    // we will consider it to be doing interaction for usage stats.
474    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
475
476    // Maximum amount of time we will allow to elapse before re-reporting usage stats
477    // interaction with foreground processes.
478    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
479
480    // This is the amount of time we allow an app to settle after it goes into the background,
481    // before we start restricting what it can do.
482    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
483
484    // How long to wait in getAssistContextExtras for the activity and foreground services
485    // to respond with the result.
486    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
487
488    // How long top wait when going through the modern assist (which doesn't need to block
489    // on getting this result before starting to launch its UI).
490    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
491
492    // Maximum number of persisted Uri grants a package is allowed
493    static final int MAX_PERSISTED_URI_GRANTS = 128;
494
495    static final int MY_PID = Process.myPid();
496
497    static final String[] EMPTY_STRING_ARRAY = new String[0];
498
499    // How many bytes to write into the dropbox log before truncating
500    static final int DROPBOX_MAX_SIZE = 256 * 1024;
501
502    // Access modes for handleIncomingUser.
503    static final int ALLOW_NON_FULL = 0;
504    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
505    static final int ALLOW_FULL_ONLY = 2;
506
507    // Delay in notifying task stack change listeners (in millis)
508    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
509
510    // Necessary ApplicationInfo flags to mark an app as persistent
511    private static final int PERSISTENT_MASK =
512            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
513
514    // Intent sent when remote bugreport collection has been completed
515    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
516            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
517
518    // Delay to disable app launch boost
519    static final int APP_BOOST_MESSAGE_DELAY = 3000;
520    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
521    static final int APP_BOOST_TIMEOUT = 2500;
522
523    // Used to indicate that a task is removed it should also be removed from recents.
524    private static final boolean REMOVE_FROM_RECENTS = true;
525    // Used to indicate that an app transition should be animated.
526    static final boolean ANIMATE = true;
527
528    // Determines whether to take full screen screenshots
529    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
530    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
531
532    private static native int nativeMigrateToBoost();
533    private static native int nativeMigrateFromBoost();
534    private boolean mIsBoosted = false;
535    private long mBoostStartTime = 0;
536
537    /** All system services */
538    SystemServiceManager mSystemServiceManager;
539
540    private Installer mInstaller;
541
542    /** Run all ActivityStacks through this */
543    final ActivityStackSupervisor mStackSupervisor;
544
545    final ActivityStarter mActivityStarter;
546
547    /** Task stack change listeners. */
548    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
549            new RemoteCallbackList<ITaskStackListener>();
550
551    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
552
553    public IntentFirewall mIntentFirewall;
554
555    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
556    // default actuion automatically.  Important for devices without direct input
557    // devices.
558    private boolean mShowDialogs = true;
559    private boolean mInVrMode = false;
560
561    BroadcastQueue mFgBroadcastQueue;
562    BroadcastQueue mBgBroadcastQueue;
563    // Convenient for easy iteration over the queues. Foreground is first
564    // so that dispatch of foreground broadcasts gets precedence.
565    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
566
567    BroadcastQueue broadcastQueueForIntent(Intent intent) {
568        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
569        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
570                "Broadcast intent " + intent + " on "
571                + (isFg ? "foreground" : "background") + " queue");
572        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
573    }
574
575    /**
576     * Activity we have told the window manager to have key focus.
577     */
578    ActivityRecord mFocusedActivity = null;
579
580    /**
581     * User id of the last activity mFocusedActivity was set to.
582     */
583    private int mLastFocusedUserId;
584
585    /**
586     * If non-null, we are tracking the time the user spends in the currently focused app.
587     */
588    private AppTimeTracker mCurAppTimeTracker;
589
590    /**
591     * List of intents that were used to start the most recent tasks.
592     */
593    final RecentTasks mRecentTasks;
594
595    /**
596     * For addAppTask: cached of the last activity component that was added.
597     */
598    ComponentName mLastAddedTaskComponent;
599
600    /**
601     * For addAppTask: cached of the last activity uid that was added.
602     */
603    int mLastAddedTaskUid;
604
605    /**
606     * For addAppTask: cached of the last ActivityInfo that was added.
607     */
608    ActivityInfo mLastAddedTaskActivity;
609
610    /**
611     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
612     */
613    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
614
615    /**
616     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
617     */
618    String mDeviceOwnerName;
619
620    final UserController mUserController;
621
622    final AppErrors mAppErrors;
623
624    boolean mDoingSetFocusedActivity;
625
626    public boolean canShowErrorDialogs() {
627        return mShowDialogs && !mSleeping && !mShuttingDown;
628    }
629
630    public class PendingAssistExtras extends Binder implements Runnable {
631        public final ActivityRecord activity;
632        public final Bundle extras;
633        public final Intent intent;
634        public final String hint;
635        public final IResultReceiver receiver;
636        public final int userHandle;
637        public boolean haveResult = false;
638        public Bundle result = null;
639        public AssistStructure structure = null;
640        public AssistContent content = null;
641        public Bundle receiverExtras;
642
643        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
644                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
645            activity = _activity;
646            extras = _extras;
647            intent = _intent;
648            hint = _hint;
649            receiver = _receiver;
650            receiverExtras = _receiverExtras;
651            userHandle = _userHandle;
652        }
653        @Override
654        public void run() {
655            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
656            synchronized (this) {
657                haveResult = true;
658                notifyAll();
659            }
660            pendingAssistExtrasTimedOut(this);
661        }
662    }
663
664    final ArrayList<PendingAssistExtras> mPendingAssistExtras
665            = new ArrayList<PendingAssistExtras>();
666
667    /**
668     * Process management.
669     */
670    final ProcessList mProcessList = new ProcessList();
671
672    /**
673     * All of the applications we currently have running organized by name.
674     * The keys are strings of the application package name (as
675     * returned by the package manager), and the keys are ApplicationRecord
676     * objects.
677     */
678    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
679
680    /**
681     * Tracking long-term execution of processes to look for abuse and other
682     * bad app behavior.
683     */
684    final ProcessStatsService mProcessStats;
685
686    /**
687     * The currently running isolated processes.
688     */
689    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
690
691    /**
692     * Counter for assigning isolated process uids, to avoid frequently reusing the
693     * same ones.
694     */
695    int mNextIsolatedProcessUid = 0;
696
697    /**
698     * The currently running heavy-weight process, if any.
699     */
700    ProcessRecord mHeavyWeightProcess = null;
701
702    /**
703     * All of the processes we currently have running organized by pid.
704     * The keys are the pid running the application.
705     *
706     * <p>NOTE: This object is protected by its own lock, NOT the global
707     * activity manager lock!
708     */
709    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
710
711    /**
712     * All of the processes that have been forced to be foreground.  The key
713     * is the pid of the caller who requested it (we hold a death
714     * link on it).
715     */
716    abstract class ForegroundToken implements IBinder.DeathRecipient {
717        int pid;
718        IBinder token;
719    }
720    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
721
722    /**
723     * List of records for processes that someone had tried to start before the
724     * system was ready.  We don't start them at that point, but ensure they
725     * are started by the time booting is complete.
726     */
727    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
728
729    /**
730     * List of persistent applications that are in the process
731     * of being started.
732     */
733    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
734
735    /**
736     * Processes that are being forcibly torn down.
737     */
738    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
739
740    /**
741     * List of running applications, sorted by recent usage.
742     * The first entry in the list is the least recently used.
743     */
744    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
745
746    /**
747     * Where in mLruProcesses that the processes hosting activities start.
748     */
749    int mLruProcessActivityStart = 0;
750
751    /**
752     * Where in mLruProcesses that the processes hosting services start.
753     * This is after (lower index) than mLruProcessesActivityStart.
754     */
755    int mLruProcessServiceStart = 0;
756
757    /**
758     * List of processes that should gc as soon as things are idle.
759     */
760    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
761
762    /**
763     * Processes we want to collect PSS data from.
764     */
765    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
766
767    private boolean mBinderTransactionTrackingEnabled = false;
768
769    /**
770     * Last time we requested PSS data of all processes.
771     */
772    long mLastFullPssTime = SystemClock.uptimeMillis();
773
774    /**
775     * If set, the next time we collect PSS data we should do a full collection
776     * with data from native processes and the kernel.
777     */
778    boolean mFullPssPending = false;
779
780    /**
781     * This is the process holding what we currently consider to be
782     * the "home" activity.
783     */
784    ProcessRecord mHomeProcess;
785
786    /**
787     * This is the process holding the activity the user last visited that
788     * is in a different process from the one they are currently in.
789     */
790    ProcessRecord mPreviousProcess;
791
792    /**
793     * The time at which the previous process was last visible.
794     */
795    long mPreviousProcessVisibleTime;
796
797    /**
798     * Track all uids that have actively running processes.
799     */
800    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
801
802    /**
803     * This is for verifying the UID report flow.
804     */
805    static final boolean VALIDATE_UID_STATES = true;
806    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
807
808    /**
809     * Packages that the user has asked to have run in screen size
810     * compatibility mode instead of filling the screen.
811     */
812    final CompatModePackages mCompatModePackages;
813
814    /**
815     * Set of IntentSenderRecord objects that are currently active.
816     */
817    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
818            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
819
820    /**
821     * Fingerprints (hashCode()) of stack traces that we've
822     * already logged DropBox entries for.  Guarded by itself.  If
823     * something (rogue user app) forces this over
824     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
825     */
826    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
827    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
828
829    /**
830     * Strict Mode background batched logging state.
831     *
832     * The string buffer is guarded by itself, and its lock is also
833     * used to determine if another batched write is already
834     * in-flight.
835     */
836    private final StringBuilder mStrictModeBuffer = new StringBuilder();
837
838    /**
839     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
840     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
841     */
842    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
843
844    /**
845     * Resolver for broadcast intents to registered receivers.
846     * Holds BroadcastFilter (subclass of IntentFilter).
847     */
848    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
849            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
850        @Override
851        protected boolean allowFilterResult(
852                BroadcastFilter filter, List<BroadcastFilter> dest) {
853            IBinder target = filter.receiverList.receiver.asBinder();
854            for (int i = dest.size() - 1; i >= 0; i--) {
855                if (dest.get(i).receiverList.receiver.asBinder() == target) {
856                    return false;
857                }
858            }
859            return true;
860        }
861
862        @Override
863        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
864            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
865                    || userId == filter.owningUserId) {
866                return super.newResult(filter, match, userId);
867            }
868            return null;
869        }
870
871        @Override
872        protected BroadcastFilter[] newArray(int size) {
873            return new BroadcastFilter[size];
874        }
875
876        @Override
877        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
878            return packageName.equals(filter.packageName);
879        }
880    };
881
882    /**
883     * State of all active sticky broadcasts per user.  Keys are the action of the
884     * sticky Intent, values are an ArrayList of all broadcasted intents with
885     * that action (which should usually be one).  The SparseArray is keyed
886     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
887     * for stickies that are sent to all users.
888     */
889    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
890            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
891
892    final ActiveServices mServices;
893
894    final static class Association {
895        final int mSourceUid;
896        final String mSourceProcess;
897        final int mTargetUid;
898        final ComponentName mTargetComponent;
899        final String mTargetProcess;
900
901        int mCount;
902        long mTime;
903
904        int mNesting;
905        long mStartTime;
906
907        // states of the source process when the bind occurred.
908        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
909        long mLastStateUptime;
910        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
911                - ActivityManager.MIN_PROCESS_STATE+1];
912
913        Association(int sourceUid, String sourceProcess, int targetUid,
914                ComponentName targetComponent, String targetProcess) {
915            mSourceUid = sourceUid;
916            mSourceProcess = sourceProcess;
917            mTargetUid = targetUid;
918            mTargetComponent = targetComponent;
919            mTargetProcess = targetProcess;
920        }
921    }
922
923    /**
924     * When service association tracking is enabled, this is all of the associations we
925     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
926     * -> association data.
927     */
928    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
929            mAssociations = new SparseArray<>();
930    boolean mTrackingAssociations;
931
932    /**
933     * Backup/restore process management
934     */
935    String mBackupAppName = null;
936    BackupRecord mBackupTarget = null;
937
938    final ProviderMap mProviderMap;
939
940    /**
941     * List of content providers who have clients waiting for them.  The
942     * application is currently being launched and the provider will be
943     * removed from this list once it is published.
944     */
945    final ArrayList<ContentProviderRecord> mLaunchingProviders
946            = new ArrayList<ContentProviderRecord>();
947
948    /**
949     * File storing persisted {@link #mGrantedUriPermissions}.
950     */
951    private final AtomicFile mGrantFile;
952
953    /** XML constants used in {@link #mGrantFile} */
954    private static final String TAG_URI_GRANTS = "uri-grants";
955    private static final String TAG_URI_GRANT = "uri-grant";
956    private static final String ATTR_USER_HANDLE = "userHandle";
957    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
958    private static final String ATTR_TARGET_USER_ID = "targetUserId";
959    private static final String ATTR_SOURCE_PKG = "sourcePkg";
960    private static final String ATTR_TARGET_PKG = "targetPkg";
961    private static final String ATTR_URI = "uri";
962    private static final String ATTR_MODE_FLAGS = "modeFlags";
963    private static final String ATTR_CREATED_TIME = "createdTime";
964    private static final String ATTR_PREFIX = "prefix";
965
966    /**
967     * Global set of specific {@link Uri} permissions that have been granted.
968     * This optimized lookup structure maps from {@link UriPermission#targetUid}
969     * to {@link UriPermission#uri} to {@link UriPermission}.
970     */
971    @GuardedBy("this")
972    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
973            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
974
975    public static class GrantUri {
976        public final int sourceUserId;
977        public final Uri uri;
978        public boolean prefix;
979
980        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
981            this.sourceUserId = sourceUserId;
982            this.uri = uri;
983            this.prefix = prefix;
984        }
985
986        @Override
987        public int hashCode() {
988            int hashCode = 1;
989            hashCode = 31 * hashCode + sourceUserId;
990            hashCode = 31 * hashCode + uri.hashCode();
991            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
992            return hashCode;
993        }
994
995        @Override
996        public boolean equals(Object o) {
997            if (o instanceof GrantUri) {
998                GrantUri other = (GrantUri) o;
999                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1000                        && prefix == other.prefix;
1001            }
1002            return false;
1003        }
1004
1005        @Override
1006        public String toString() {
1007            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1008            if (prefix) result += " [prefix]";
1009            return result;
1010        }
1011
1012        public String toSafeString() {
1013            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1014            if (prefix) result += " [prefix]";
1015            return result;
1016        }
1017
1018        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1019            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1020                    ContentProvider.getUriWithoutUserId(uri), false);
1021        }
1022    }
1023
1024    CoreSettingsObserver mCoreSettingsObserver;
1025
1026    FontScaleSettingObserver mFontScaleSettingObserver;
1027
1028    private final class FontScaleSettingObserver extends ContentObserver {
1029        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1030
1031        public FontScaleSettingObserver() {
1032            super(mHandler);
1033            ContentResolver resolver = mContext.getContentResolver();
1034            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1035        }
1036
1037        @Override
1038        public void onChange(boolean selfChange, Uri uri) {
1039            if (mFontScaleUri.equals(uri)) {
1040                updateFontScaleIfNeeded();
1041            }
1042        }
1043    }
1044
1045    /**
1046     * Thread-local storage used to carry caller permissions over through
1047     * indirect content-provider access.
1048     */
1049    private class Identity {
1050        public final IBinder token;
1051        public final int pid;
1052        public final int uid;
1053
1054        Identity(IBinder _token, int _pid, int _uid) {
1055            token = _token;
1056            pid = _pid;
1057            uid = _uid;
1058        }
1059    }
1060
1061    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1062
1063    /**
1064     * All information we have collected about the runtime performance of
1065     * any user id that can impact battery performance.
1066     */
1067    final BatteryStatsService mBatteryStatsService;
1068
1069    /**
1070     * Information about component usage
1071     */
1072    UsageStatsManagerInternal mUsageStatsService;
1073
1074    /**
1075     * Access to DeviceIdleController service.
1076     */
1077    DeviceIdleController.LocalService mLocalDeviceIdleController;
1078
1079    /**
1080     * Information about and control over application operations
1081     */
1082    final AppOpsService mAppOpsService;
1083
1084    /**
1085     * Current configuration information.  HistoryRecord objects are given
1086     * a reference to this object to indicate which configuration they are
1087     * currently running in, so this object must be kept immutable.
1088     */
1089    Configuration mConfiguration = new Configuration();
1090
1091    /**
1092     * Current sequencing integer of the configuration, for skipping old
1093     * configurations.
1094     */
1095    int mConfigurationSeq = 0;
1096
1097    boolean mSuppressResizeConfigChanges = false;
1098
1099    /**
1100     * Hardware-reported OpenGLES version.
1101     */
1102    final int GL_ES_VERSION;
1103
1104    /**
1105     * List of initialization arguments to pass to all processes when binding applications to them.
1106     * For example, references to the commonly used services.
1107     */
1108    HashMap<String, IBinder> mAppBindArgs;
1109
1110    /**
1111     * Temporary to avoid allocations.  Protected by main lock.
1112     */
1113    final StringBuilder mStringBuilder = new StringBuilder(256);
1114
1115    /**
1116     * Used to control how we initialize the service.
1117     */
1118    ComponentName mTopComponent;
1119    String mTopAction = Intent.ACTION_MAIN;
1120    String mTopData;
1121
1122    volatile boolean mProcessesReady = false;
1123    volatile boolean mSystemReady = false;
1124    volatile boolean mOnBattery = false;
1125    volatile int mFactoryTest;
1126
1127    @GuardedBy("this") boolean mBooting = false;
1128    @GuardedBy("this") boolean mCallFinishBooting = false;
1129    @GuardedBy("this") boolean mBootAnimationComplete = false;
1130    @GuardedBy("this") boolean mLaunchWarningShown = false;
1131    @GuardedBy("this") boolean mCheckedForSetup = false;
1132
1133    Context mContext;
1134
1135    /**
1136     * The time at which we will allow normal application switches again,
1137     * after a call to {@link #stopAppSwitches()}.
1138     */
1139    long mAppSwitchesAllowedTime;
1140
1141    /**
1142     * This is set to true after the first switch after mAppSwitchesAllowedTime
1143     * is set; any switches after that will clear the time.
1144     */
1145    boolean mDidAppSwitch;
1146
1147    /**
1148     * Last time (in realtime) at which we checked for power usage.
1149     */
1150    long mLastPowerCheckRealtime;
1151
1152    /**
1153     * Last time (in uptime) at which we checked for power usage.
1154     */
1155    long mLastPowerCheckUptime;
1156
1157    /**
1158     * Set while we are wanting to sleep, to prevent any
1159     * activities from being started/resumed.
1160     */
1161    private boolean mSleeping = false;
1162
1163    /**
1164     * The process state used for processes that are running the top activities.
1165     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1166     */
1167    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1168
1169    /**
1170     * Set while we are running a voice interaction.  This overrides
1171     * sleeping while it is active.
1172     */
1173    private IVoiceInteractionSession mRunningVoice;
1174
1175    /**
1176     * For some direct access we need to power manager.
1177     */
1178    PowerManagerInternal mLocalPowerManager;
1179
1180    /**
1181     * We want to hold a wake lock while running a voice interaction session, since
1182     * this may happen with the screen off and we need to keep the CPU running to
1183     * be able to continue to interact with the user.
1184     */
1185    PowerManager.WakeLock mVoiceWakeLock;
1186
1187    /**
1188     * State of external calls telling us if the device is awake or asleep.
1189     */
1190    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1191
1192    /**
1193     * A list of tokens that cause the top activity to be put to sleep.
1194     * They are used by components that may hide and block interaction with underlying
1195     * activities.
1196     */
1197    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1198
1199    static final int LOCK_SCREEN_HIDDEN = 0;
1200    static final int LOCK_SCREEN_LEAVING = 1;
1201    static final int LOCK_SCREEN_SHOWN = 2;
1202    /**
1203     * State of external call telling us if the lock screen is shown.
1204     */
1205    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1206
1207    /**
1208     * Set if we are shutting down the system, similar to sleeping.
1209     */
1210    boolean mShuttingDown = false;
1211
1212    /**
1213     * Current sequence id for oom_adj computation traversal.
1214     */
1215    int mAdjSeq = 0;
1216
1217    /**
1218     * Current sequence id for process LRU updating.
1219     */
1220    int mLruSeq = 0;
1221
1222    /**
1223     * Keep track of the non-cached/empty process we last found, to help
1224     * determine how to distribute cached/empty processes next time.
1225     */
1226    int mNumNonCachedProcs = 0;
1227
1228    /**
1229     * Keep track of the number of cached hidden procs, to balance oom adj
1230     * distribution between those and empty procs.
1231     */
1232    int mNumCachedHiddenProcs = 0;
1233
1234    /**
1235     * Keep track of the number of service processes we last found, to
1236     * determine on the next iteration which should be B services.
1237     */
1238    int mNumServiceProcs = 0;
1239    int mNewNumAServiceProcs = 0;
1240    int mNewNumServiceProcs = 0;
1241
1242    /**
1243     * Allow the current computed overall memory level of the system to go down?
1244     * This is set to false when we are killing processes for reasons other than
1245     * memory management, so that the now smaller process list will not be taken as
1246     * an indication that memory is tighter.
1247     */
1248    boolean mAllowLowerMemLevel = false;
1249
1250    /**
1251     * The last computed memory level, for holding when we are in a state that
1252     * processes are going away for other reasons.
1253     */
1254    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1255
1256    /**
1257     * The last total number of process we have, to determine if changes actually look
1258     * like a shrinking number of process due to lower RAM.
1259     */
1260    int mLastNumProcesses;
1261
1262    /**
1263     * The uptime of the last time we performed idle maintenance.
1264     */
1265    long mLastIdleTime = SystemClock.uptimeMillis();
1266
1267    /**
1268     * Total time spent with RAM that has been added in the past since the last idle time.
1269     */
1270    long mLowRamTimeSinceLastIdle = 0;
1271
1272    /**
1273     * If RAM is currently low, when that horrible situation started.
1274     */
1275    long mLowRamStartTime = 0;
1276
1277    /**
1278     * For reporting to battery stats the current top application.
1279     */
1280    private String mCurResumedPackage = null;
1281    private int mCurResumedUid = -1;
1282
1283    /**
1284     * For reporting to battery stats the apps currently running foreground
1285     * service.  The ProcessMap is package/uid tuples; each of these contain
1286     * an array of the currently foreground processes.
1287     */
1288    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1289            = new ProcessMap<ArrayList<ProcessRecord>>();
1290
1291    /**
1292     * This is set if we had to do a delayed dexopt of an app before launching
1293     * it, to increase the ANR timeouts in that case.
1294     */
1295    boolean mDidDexOpt;
1296
1297    /**
1298     * Set if the systemServer made a call to enterSafeMode.
1299     */
1300    boolean mSafeMode;
1301
1302    /**
1303     * If true, we are running under a test environment so will sample PSS from processes
1304     * much more rapidly to try to collect better data when the tests are rapidly
1305     * running through apps.
1306     */
1307    boolean mTestPssMode = false;
1308
1309    String mDebugApp = null;
1310    boolean mWaitForDebugger = false;
1311    boolean mDebugTransient = false;
1312    String mOrigDebugApp = null;
1313    boolean mOrigWaitForDebugger = false;
1314    boolean mAlwaysFinishActivities = false;
1315    boolean mLenientBackgroundCheck = false;
1316    boolean mForceResizableActivities;
1317    boolean mSupportsMultiWindow;
1318    boolean mSupportsFreeformWindowManagement;
1319    boolean mSupportsPictureInPicture;
1320    Rect mDefaultPinnedStackBounds;
1321    IActivityController mController = null;
1322    boolean mControllerIsAMonkey = false;
1323    String mProfileApp = null;
1324    ProcessRecord mProfileProc = null;
1325    String mProfileFile;
1326    ParcelFileDescriptor mProfileFd;
1327    int mSamplingInterval = 0;
1328    boolean mAutoStopProfiler = false;
1329    int mProfileType = 0;
1330    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1331    String mMemWatchDumpProcName;
1332    String mMemWatchDumpFile;
1333    int mMemWatchDumpPid;
1334    int mMemWatchDumpUid;
1335    String mTrackAllocationApp = null;
1336    String mNativeDebuggingApp = null;
1337
1338    final long[] mTmpLong = new long[2];
1339
1340    static final class ProcessChangeItem {
1341        static final int CHANGE_ACTIVITIES = 1<<0;
1342        static final int CHANGE_PROCESS_STATE = 1<<1;
1343        int changes;
1344        int uid;
1345        int pid;
1346        int processState;
1347        boolean foregroundActivities;
1348    }
1349
1350    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1351    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1352
1353    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1354    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1355
1356    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1357    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1358
1359    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1360    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1361
1362    /**
1363     * Runtime CPU use collection thread.  This object's lock is used to
1364     * perform synchronization with the thread (notifying it to run).
1365     */
1366    final Thread mProcessCpuThread;
1367
1368    /**
1369     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1370     * Must acquire this object's lock when accessing it.
1371     * NOTE: this lock will be held while doing long operations (trawling
1372     * through all processes in /proc), so it should never be acquired by
1373     * any critical paths such as when holding the main activity manager lock.
1374     */
1375    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1376            MONITOR_THREAD_CPU_USAGE);
1377    final AtomicLong mLastCpuTime = new AtomicLong(0);
1378    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1379
1380    long mLastWriteTime = 0;
1381
1382    /**
1383     * Used to retain an update lock when the foreground activity is in
1384     * immersive mode.
1385     */
1386    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1387
1388    /**
1389     * Set to true after the system has finished booting.
1390     */
1391    boolean mBooted = false;
1392
1393    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1394    int mProcessLimitOverride = -1;
1395
1396    WindowManagerService mWindowManager;
1397    final ActivityThread mSystemThread;
1398
1399    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1400        final ProcessRecord mApp;
1401        final int mPid;
1402        final IApplicationThread mAppThread;
1403
1404        AppDeathRecipient(ProcessRecord app, int pid,
1405                IApplicationThread thread) {
1406            if (DEBUG_ALL) Slog.v(
1407                TAG, "New death recipient " + this
1408                + " for thread " + thread.asBinder());
1409            mApp = app;
1410            mPid = pid;
1411            mAppThread = thread;
1412        }
1413
1414        @Override
1415        public void binderDied() {
1416            if (DEBUG_ALL) Slog.v(
1417                TAG, "Death received in " + this
1418                + " for thread " + mAppThread.asBinder());
1419            synchronized(ActivityManagerService.this) {
1420                appDiedLocked(mApp, mPid, mAppThread, true);
1421            }
1422        }
1423    }
1424
1425    static final int SHOW_ERROR_UI_MSG = 1;
1426    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1427    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1428    static final int UPDATE_CONFIGURATION_MSG = 4;
1429    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1430    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1431    static final int SERVICE_TIMEOUT_MSG = 12;
1432    static final int UPDATE_TIME_ZONE = 13;
1433    static final int SHOW_UID_ERROR_UI_MSG = 14;
1434    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1435    static final int PROC_START_TIMEOUT_MSG = 20;
1436    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1437    static final int KILL_APPLICATION_MSG = 22;
1438    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1439    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1440    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1441    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1442    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1443    static final int CLEAR_DNS_CACHE_MSG = 28;
1444    static final int UPDATE_HTTP_PROXY_MSG = 29;
1445    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1446    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1447    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1448    static final int REPORT_MEM_USAGE_MSG = 33;
1449    static final int REPORT_USER_SWITCH_MSG = 34;
1450    static final int CONTINUE_USER_SWITCH_MSG = 35;
1451    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1452    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1453    static final int PERSIST_URI_GRANTS_MSG = 38;
1454    static final int REQUEST_ALL_PSS_MSG = 39;
1455    static final int START_PROFILES_MSG = 40;
1456    static final int UPDATE_TIME = 41;
1457    static final int SYSTEM_USER_START_MSG = 42;
1458    static final int SYSTEM_USER_CURRENT_MSG = 43;
1459    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1460    static final int FINISH_BOOTING_MSG = 45;
1461    static final int START_USER_SWITCH_UI_MSG = 46;
1462    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1463    static final int DISMISS_DIALOG_UI_MSG = 48;
1464    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1465    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1466    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1467    static final int DELETE_DUMPHEAP_MSG = 52;
1468    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1469    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1470    static final int REPORT_TIME_TRACKER_MSG = 55;
1471    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1472    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1473    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1474    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1475    static final int IDLE_UIDS_MSG = 60;
1476    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1477    static final int LOG_STACK_STATE = 62;
1478    static final int VR_MODE_CHANGE_MSG = 63;
1479    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1480    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1481    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1482    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1483    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1484    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1485
1486    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1487    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1488    static final int FIRST_COMPAT_MODE_MSG = 300;
1489    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1490
1491    static ServiceThread sKillThread = null;
1492    static KillHandler sKillHandler = null;
1493
1494    CompatModeDialog mCompatModeDialog;
1495    long mLastMemUsageReportTime = 0;
1496
1497    /**
1498     * Flag whether the current user is a "monkey", i.e. whether
1499     * the UI is driven by a UI automation tool.
1500     */
1501    private boolean mUserIsMonkey;
1502
1503    /** Flag whether the device has a Recents UI */
1504    boolean mHasRecents;
1505
1506    /** The dimensions of the thumbnails in the Recents UI. */
1507    int mThumbnailWidth;
1508    int mThumbnailHeight;
1509    float mFullscreenThumbnailScale;
1510
1511    final ServiceThread mHandlerThread;
1512    final MainHandler mHandler;
1513    final UiHandler mUiHandler;
1514
1515    PackageManagerInternal mPackageManagerInt;
1516
1517    // VoiceInteraction session ID that changes for each new request except when
1518    // being called for multiwindow assist in a single session.
1519    private int mViSessionId = 1000;
1520
1521    final class KillHandler extends Handler {
1522        static final int KILL_PROCESS_GROUP_MSG = 4000;
1523
1524        public KillHandler(Looper looper) {
1525            super(looper, null, true);
1526        }
1527
1528        @Override
1529        public void handleMessage(Message msg) {
1530            switch (msg.what) {
1531                case KILL_PROCESS_GROUP_MSG:
1532                {
1533                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1534                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1535                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1536                }
1537                break;
1538
1539                default:
1540                    super.handleMessage(msg);
1541            }
1542        }
1543    }
1544
1545    final class UiHandler extends Handler {
1546        public UiHandler() {
1547            super(com.android.server.UiThread.get().getLooper(), null, true);
1548        }
1549
1550        @Override
1551        public void handleMessage(Message msg) {
1552            switch (msg.what) {
1553            case SHOW_ERROR_UI_MSG: {
1554                mAppErrors.handleShowAppErrorUi(msg);
1555                ensureBootCompleted();
1556            } break;
1557            case SHOW_NOT_RESPONDING_UI_MSG: {
1558                mAppErrors.handleShowAnrUi(msg);
1559                ensureBootCompleted();
1560            } break;
1561            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1562                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1563                synchronized (ActivityManagerService.this) {
1564                    ProcessRecord proc = (ProcessRecord) data.get("app");
1565                    if (proc == null) {
1566                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1567                        break;
1568                    }
1569                    if (proc.crashDialog != null) {
1570                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1571                        return;
1572                    }
1573                    AppErrorResult res = (AppErrorResult) data.get("result");
1574                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1575                        Dialog d = new StrictModeViolationDialog(mContext,
1576                                ActivityManagerService.this, res, proc);
1577                        d.show();
1578                        proc.crashDialog = d;
1579                    } else {
1580                        // The device is asleep, so just pretend that the user
1581                        // saw a crash dialog and hit "force quit".
1582                        res.set(0);
1583                    }
1584                }
1585                ensureBootCompleted();
1586            } break;
1587            case SHOW_FACTORY_ERROR_UI_MSG: {
1588                Dialog d = new FactoryErrorDialog(
1589                    mContext, msg.getData().getCharSequence("msg"));
1590                d.show();
1591                ensureBootCompleted();
1592            } break;
1593            case WAIT_FOR_DEBUGGER_UI_MSG: {
1594                synchronized (ActivityManagerService.this) {
1595                    ProcessRecord app = (ProcessRecord)msg.obj;
1596                    if (msg.arg1 != 0) {
1597                        if (!app.waitedForDebugger) {
1598                            Dialog d = new AppWaitingForDebuggerDialog(
1599                                    ActivityManagerService.this,
1600                                    mContext, app);
1601                            app.waitDialog = d;
1602                            app.waitedForDebugger = true;
1603                            d.show();
1604                        }
1605                    } else {
1606                        if (app.waitDialog != null) {
1607                            app.waitDialog.dismiss();
1608                            app.waitDialog = null;
1609                        }
1610                    }
1611                }
1612            } break;
1613            case SHOW_UID_ERROR_UI_MSG: {
1614                if (mShowDialogs) {
1615                    AlertDialog d = new BaseErrorDialog(mContext);
1616                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1617                    d.setCancelable(false);
1618                    d.setTitle(mContext.getText(R.string.android_system_label));
1619                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1620                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1621                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1622                    d.show();
1623                }
1624            } break;
1625            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1626                if (mShowDialogs) {
1627                    AlertDialog d = new BaseErrorDialog(mContext);
1628                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1629                    d.setCancelable(false);
1630                    d.setTitle(mContext.getText(R.string.android_system_label));
1631                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1632                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1633                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1634                    d.show();
1635                }
1636            } break;
1637            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1638                synchronized (ActivityManagerService.this) {
1639                    ActivityRecord ar = (ActivityRecord) msg.obj;
1640                    if (mCompatModeDialog != null) {
1641                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1642                                ar.info.applicationInfo.packageName)) {
1643                            return;
1644                        }
1645                        mCompatModeDialog.dismiss();
1646                        mCompatModeDialog = null;
1647                    }
1648                    if (ar != null && false) {
1649                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1650                                ar.packageName)) {
1651                            int mode = mCompatModePackages.computeCompatModeLocked(
1652                                    ar.info.applicationInfo);
1653                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1654                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1655                                mCompatModeDialog = new CompatModeDialog(
1656                                        ActivityManagerService.this, mContext,
1657                                        ar.info.applicationInfo);
1658                                mCompatModeDialog.show();
1659                            }
1660                        }
1661                    }
1662                }
1663                break;
1664            }
1665            case START_USER_SWITCH_UI_MSG: {
1666                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1667                break;
1668            }
1669            case DISMISS_DIALOG_UI_MSG: {
1670                final Dialog d = (Dialog) msg.obj;
1671                d.dismiss();
1672                break;
1673            }
1674            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1675                dispatchProcessesChanged();
1676                break;
1677            }
1678            case DISPATCH_PROCESS_DIED_UI_MSG: {
1679                final int pid = msg.arg1;
1680                final int uid = msg.arg2;
1681                dispatchProcessDied(pid, uid);
1682                break;
1683            }
1684            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1685                dispatchUidsChanged();
1686            } break;
1687            }
1688        }
1689    }
1690
1691    final class MainHandler extends Handler {
1692        public MainHandler(Looper looper) {
1693            super(looper, null, true);
1694        }
1695
1696        @Override
1697        public void handleMessage(Message msg) {
1698            switch (msg.what) {
1699            case UPDATE_CONFIGURATION_MSG: {
1700                final ContentResolver resolver = mContext.getContentResolver();
1701                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1702                        msg.arg1);
1703            } break;
1704            case GC_BACKGROUND_PROCESSES_MSG: {
1705                synchronized (ActivityManagerService.this) {
1706                    performAppGcsIfAppropriateLocked();
1707                }
1708            } break;
1709            case SERVICE_TIMEOUT_MSG: {
1710                if (mDidDexOpt) {
1711                    mDidDexOpt = false;
1712                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1713                    nmsg.obj = msg.obj;
1714                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1715                    return;
1716                }
1717                mServices.serviceTimeout((ProcessRecord)msg.obj);
1718            } break;
1719            case UPDATE_TIME_ZONE: {
1720                synchronized (ActivityManagerService.this) {
1721                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1722                        ProcessRecord r = mLruProcesses.get(i);
1723                        if (r.thread != null) {
1724                            try {
1725                                r.thread.updateTimeZone();
1726                            } catch (RemoteException ex) {
1727                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1728                            }
1729                        }
1730                    }
1731                }
1732            } break;
1733            case CLEAR_DNS_CACHE_MSG: {
1734                synchronized (ActivityManagerService.this) {
1735                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1736                        ProcessRecord r = mLruProcesses.get(i);
1737                        if (r.thread != null) {
1738                            try {
1739                                r.thread.clearDnsCache();
1740                            } catch (RemoteException ex) {
1741                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1742                            }
1743                        }
1744                    }
1745                }
1746            } break;
1747            case UPDATE_HTTP_PROXY_MSG: {
1748                ProxyInfo proxy = (ProxyInfo)msg.obj;
1749                String host = "";
1750                String port = "";
1751                String exclList = "";
1752                Uri pacFileUrl = Uri.EMPTY;
1753                if (proxy != null) {
1754                    host = proxy.getHost();
1755                    port = Integer.toString(proxy.getPort());
1756                    exclList = proxy.getExclusionListAsString();
1757                    pacFileUrl = proxy.getPacFileUrl();
1758                }
1759                synchronized (ActivityManagerService.this) {
1760                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1761                        ProcessRecord r = mLruProcesses.get(i);
1762                        if (r.thread != null) {
1763                            try {
1764                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1765                            } catch (RemoteException ex) {
1766                                Slog.w(TAG, "Failed to update http proxy for: " +
1767                                        r.info.processName);
1768                            }
1769                        }
1770                    }
1771                }
1772            } break;
1773            case PROC_START_TIMEOUT_MSG: {
1774                if (mDidDexOpt) {
1775                    mDidDexOpt = false;
1776                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1777                    nmsg.obj = msg.obj;
1778                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1779                    return;
1780                }
1781                ProcessRecord app = (ProcessRecord)msg.obj;
1782                synchronized (ActivityManagerService.this) {
1783                    processStartTimedOutLocked(app);
1784                }
1785            } break;
1786            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1787                ProcessRecord app = (ProcessRecord)msg.obj;
1788                synchronized (ActivityManagerService.this) {
1789                    processContentProviderPublishTimedOutLocked(app);
1790                }
1791            } break;
1792            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1793                synchronized (ActivityManagerService.this) {
1794                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1795                }
1796            } break;
1797            case KILL_APPLICATION_MSG: {
1798                synchronized (ActivityManagerService.this) {
1799                    int appid = msg.arg1;
1800                    boolean restart = (msg.arg2 == 1);
1801                    Bundle bundle = (Bundle)msg.obj;
1802                    String pkg = bundle.getString("pkg");
1803                    String reason = bundle.getString("reason");
1804                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1805                            false, UserHandle.USER_ALL, reason);
1806                }
1807            } break;
1808            case FINALIZE_PENDING_INTENT_MSG: {
1809                ((PendingIntentRecord)msg.obj).completeFinalize();
1810            } break;
1811            case POST_HEAVY_NOTIFICATION_MSG: {
1812                INotificationManager inm = NotificationManager.getService();
1813                if (inm == null) {
1814                    return;
1815                }
1816
1817                ActivityRecord root = (ActivityRecord)msg.obj;
1818                ProcessRecord process = root.app;
1819                if (process == null) {
1820                    return;
1821                }
1822
1823                try {
1824                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1825                    String text = mContext.getString(R.string.heavy_weight_notification,
1826                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1827                    Notification notification = new Notification.Builder(context)
1828                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1829                            .setWhen(0)
1830                            .setOngoing(true)
1831                            .setTicker(text)
1832                            .setColor(mContext.getColor(
1833                                    com.android.internal.R.color.system_notification_accent_color))
1834                            .setContentTitle(text)
1835                            .setContentText(
1836                                    mContext.getText(R.string.heavy_weight_notification_detail))
1837                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1838                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1839                                    new UserHandle(root.userId)))
1840                            .build();
1841                    try {
1842                        int[] outId = new int[1];
1843                        inm.enqueueNotificationWithTag("android", "android", null,
1844                                R.string.heavy_weight_notification,
1845                                notification, outId, root.userId);
1846                    } catch (RuntimeException e) {
1847                        Slog.w(ActivityManagerService.TAG,
1848                                "Error showing notification for heavy-weight app", e);
1849                    } catch (RemoteException e) {
1850                    }
1851                } catch (NameNotFoundException e) {
1852                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1853                }
1854            } break;
1855            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1856                INotificationManager inm = NotificationManager.getService();
1857                if (inm == null) {
1858                    return;
1859                }
1860                try {
1861                    inm.cancelNotificationWithTag("android", null,
1862                            R.string.heavy_weight_notification,  msg.arg1);
1863                } catch (RuntimeException e) {
1864                    Slog.w(ActivityManagerService.TAG,
1865                            "Error canceling notification for service", e);
1866                } catch (RemoteException e) {
1867                }
1868            } break;
1869            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1870                synchronized (ActivityManagerService.this) {
1871                    checkExcessivePowerUsageLocked(true);
1872                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1873                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1874                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1875                }
1876            } break;
1877            case REPORT_MEM_USAGE_MSG: {
1878                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1879                Thread thread = new Thread() {
1880                    @Override public void run() {
1881                        reportMemUsage(memInfos);
1882                    }
1883                };
1884                thread.start();
1885                break;
1886            }
1887            case REPORT_USER_SWITCH_MSG: {
1888                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1889                break;
1890            }
1891            case CONTINUE_USER_SWITCH_MSG: {
1892                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1893                break;
1894            }
1895            case USER_SWITCH_TIMEOUT_MSG: {
1896                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1897                break;
1898            }
1899            case IMMERSIVE_MODE_LOCK_MSG: {
1900                final boolean nextState = (msg.arg1 != 0);
1901                if (mUpdateLock.isHeld() != nextState) {
1902                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1903                            "Applying new update lock state '" + nextState
1904                            + "' for " + (ActivityRecord)msg.obj);
1905                    if (nextState) {
1906                        mUpdateLock.acquire();
1907                    } else {
1908                        mUpdateLock.release();
1909                    }
1910                }
1911                break;
1912            }
1913            case PERSIST_URI_GRANTS_MSG: {
1914                writeGrantedUriPermissions();
1915                break;
1916            }
1917            case REQUEST_ALL_PSS_MSG: {
1918                synchronized (ActivityManagerService.this) {
1919                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1920                }
1921                break;
1922            }
1923            case START_PROFILES_MSG: {
1924                synchronized (ActivityManagerService.this) {
1925                    mUserController.startProfilesLocked();
1926                }
1927                break;
1928            }
1929            case UPDATE_TIME: {
1930                synchronized (ActivityManagerService.this) {
1931                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1932                        ProcessRecord r = mLruProcesses.get(i);
1933                        if (r.thread != null) {
1934                            try {
1935                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1936                            } catch (RemoteException ex) {
1937                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1938                            }
1939                        }
1940                    }
1941                }
1942                break;
1943            }
1944            case SYSTEM_USER_START_MSG: {
1945                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1946                        Integer.toString(msg.arg1), msg.arg1);
1947                mSystemServiceManager.startUser(msg.arg1);
1948                break;
1949            }
1950            case SYSTEM_USER_UNLOCK_MSG: {
1951                final int userId = msg.arg1;
1952                mSystemServiceManager.unlockUser(userId);
1953                synchronized (ActivityManagerService.this) {
1954                    mRecentTasks.loadUserRecentsLocked(userId);
1955                }
1956                if (userId == UserHandle.USER_SYSTEM) {
1957                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1958                }
1959                installEncryptionUnawareProviders(userId);
1960                mUserController.finishUserUnlocked((UserState) msg.obj);
1961                break;
1962            }
1963            case SYSTEM_USER_CURRENT_MSG: {
1964                mBatteryStatsService.noteEvent(
1965                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1966                        Integer.toString(msg.arg2), msg.arg2);
1967                mBatteryStatsService.noteEvent(
1968                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1969                        Integer.toString(msg.arg1), msg.arg1);
1970                mSystemServiceManager.switchUser(msg.arg1);
1971                break;
1972            }
1973            case ENTER_ANIMATION_COMPLETE_MSG: {
1974                synchronized (ActivityManagerService.this) {
1975                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1976                    if (r != null && r.app != null && r.app.thread != null) {
1977                        try {
1978                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1979                        } catch (RemoteException e) {
1980                        }
1981                    }
1982                }
1983                break;
1984            }
1985            case FINISH_BOOTING_MSG: {
1986                if (msg.arg1 != 0) {
1987                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1988                    finishBooting();
1989                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1990                }
1991                if (msg.arg2 != 0) {
1992                    enableScreenAfterBoot();
1993                }
1994                break;
1995            }
1996            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1997                try {
1998                    Locale l = (Locale) msg.obj;
1999                    IBinder service = ServiceManager.getService("mount");
2000                    IMountService mountService = IMountService.Stub.asInterface(service);
2001                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2002                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2003                } catch (RemoteException e) {
2004                    Log.e(TAG, "Error storing locale for decryption UI", e);
2005                }
2006                break;
2007            }
2008            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2009                synchronized (ActivityManagerService.this) {
2010                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2011                        try {
2012                            // Make a one-way callback to the listener
2013                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2014                        } catch (RemoteException e){
2015                            // Handled by the RemoteCallbackList
2016                        }
2017                    }
2018                    mTaskStackListeners.finishBroadcast();
2019                }
2020                break;
2021            }
2022            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2023                synchronized (ActivityManagerService.this) {
2024                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2025                        try {
2026                            // Make a one-way callback to the listener
2027                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2028                        } catch (RemoteException e){
2029                            // Handled by the RemoteCallbackList
2030                        }
2031                    }
2032                    mTaskStackListeners.finishBroadcast();
2033                }
2034                break;
2035            }
2036            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2037                synchronized (ActivityManagerService.this) {
2038                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2039                        try {
2040                            // Make a one-way callback to the listener
2041                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2042                        } catch (RemoteException e){
2043                            // Handled by the RemoteCallbackList
2044                        }
2045                    }
2046                    mTaskStackListeners.finishBroadcast();
2047                }
2048                break;
2049            }
2050            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2051                synchronized (ActivityManagerService.this) {
2052                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2053                        try {
2054                            // Make a one-way callback to the listener
2055                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2056                        } catch (RemoteException e){
2057                            // Handled by the RemoteCallbackList
2058                        }
2059                    }
2060                    mTaskStackListeners.finishBroadcast();
2061                }
2062                break;
2063            }
2064            case NOTIFY_FORCED_RESIZABLE_MSG: {
2065                synchronized (ActivityManagerService.this) {
2066                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2067                        try {
2068                            // Make a one-way callback to the listener
2069                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2070                                    (String) msg.obj, msg.arg1);
2071                        } catch (RemoteException e){
2072                            // Handled by the RemoteCallbackList
2073                        }
2074                    }
2075                    mTaskStackListeners.finishBroadcast();
2076                }
2077                break;
2078            }
2079                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2080                    synchronized (ActivityManagerService.this) {
2081                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2082                            try {
2083                                // Make a one-way callback to the listener
2084                                mTaskStackListeners.getBroadcastItem(i)
2085                                        .onActivityDismissingDockedStack();
2086                            } catch (RemoteException e){
2087                                // Handled by the RemoteCallbackList
2088                            }
2089                        }
2090                        mTaskStackListeners.finishBroadcast();
2091                    }
2092                    break;
2093                }
2094            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2095                final int uid = msg.arg1;
2096                final byte[] firstPacket = (byte[]) msg.obj;
2097
2098                synchronized (mPidsSelfLocked) {
2099                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2100                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2101                        if (p.uid == uid) {
2102                            try {
2103                                p.thread.notifyCleartextNetwork(firstPacket);
2104                            } catch (RemoteException ignored) {
2105                            }
2106                        }
2107                    }
2108                }
2109                break;
2110            }
2111            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2112                final String procName;
2113                final int uid;
2114                final long memLimit;
2115                final String reportPackage;
2116                synchronized (ActivityManagerService.this) {
2117                    procName = mMemWatchDumpProcName;
2118                    uid = mMemWatchDumpUid;
2119                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2120                    if (val == null) {
2121                        val = mMemWatchProcesses.get(procName, 0);
2122                    }
2123                    if (val != null) {
2124                        memLimit = val.first;
2125                        reportPackage = val.second;
2126                    } else {
2127                        memLimit = 0;
2128                        reportPackage = null;
2129                    }
2130                }
2131                if (procName == null) {
2132                    return;
2133                }
2134
2135                if (DEBUG_PSS) Slog.d(TAG_PSS,
2136                        "Showing dump heap notification from " + procName + "/" + uid);
2137
2138                INotificationManager inm = NotificationManager.getService();
2139                if (inm == null) {
2140                    return;
2141                }
2142
2143                String text = mContext.getString(R.string.dump_heap_notification, procName);
2144
2145
2146                Intent deleteIntent = new Intent();
2147                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2148                Intent intent = new Intent();
2149                intent.setClassName("android", DumpHeapActivity.class.getName());
2150                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2151                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2152                if (reportPackage != null) {
2153                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2154                }
2155                int userId = UserHandle.getUserId(uid);
2156                Notification notification = new Notification.Builder(mContext)
2157                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2158                        .setWhen(0)
2159                        .setOngoing(true)
2160                        .setAutoCancel(true)
2161                        .setTicker(text)
2162                        .setColor(mContext.getColor(
2163                                com.android.internal.R.color.system_notification_accent_color))
2164                        .setContentTitle(text)
2165                        .setContentText(
2166                                mContext.getText(R.string.dump_heap_notification_detail))
2167                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2168                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2169                                new UserHandle(userId)))
2170                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2171                                deleteIntent, 0, UserHandle.SYSTEM))
2172                        .build();
2173
2174                try {
2175                    int[] outId = new int[1];
2176                    inm.enqueueNotificationWithTag("android", "android", null,
2177                            R.string.dump_heap_notification,
2178                            notification, outId, userId);
2179                } catch (RuntimeException e) {
2180                    Slog.w(ActivityManagerService.TAG,
2181                            "Error showing notification for dump heap", e);
2182                } catch (RemoteException e) {
2183                }
2184            } break;
2185            case DELETE_DUMPHEAP_MSG: {
2186                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2187                        DumpHeapActivity.JAVA_URI,
2188                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2189                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2190                        UserHandle.myUserId());
2191                synchronized (ActivityManagerService.this) {
2192                    mMemWatchDumpFile = null;
2193                    mMemWatchDumpProcName = null;
2194                    mMemWatchDumpPid = -1;
2195                    mMemWatchDumpUid = -1;
2196                }
2197            } break;
2198            case FOREGROUND_PROFILE_CHANGED_MSG: {
2199                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2200            } break;
2201            case REPORT_TIME_TRACKER_MSG: {
2202                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2203                tracker.deliverResult(mContext);
2204            } break;
2205            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2206                mUserController.dispatchUserSwitchComplete(msg.arg1);
2207            } break;
2208            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2209                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2210                try {
2211                    connection.shutdown();
2212                } catch (RemoteException e) {
2213                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2214                }
2215                // Only a UiAutomation can set this flag and now that
2216                // it is finished we make sure it is reset to its default.
2217                mUserIsMonkey = false;
2218            } break;
2219            case APP_BOOST_DEACTIVATE_MSG: {
2220                synchronized(ActivityManagerService.this) {
2221                    if (mIsBoosted) {
2222                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2223                            nativeMigrateFromBoost();
2224                            mIsBoosted = false;
2225                            mBoostStartTime = 0;
2226                        } else {
2227                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2228                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2229                        }
2230                    }
2231                }
2232            } break;
2233            case IDLE_UIDS_MSG: {
2234                idleUids();
2235            } break;
2236            case LOG_STACK_STATE: {
2237                synchronized (ActivityManagerService.this) {
2238                    mStackSupervisor.logStackState();
2239                }
2240            } break;
2241            case VR_MODE_CHANGE_MSG: {
2242                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2243                final ActivityRecord r = (ActivityRecord) msg.obj;
2244                boolean vrMode;
2245                ComponentName requestedPackage;
2246                ComponentName callingPackage;
2247                int userId;
2248                synchronized (ActivityManagerService.this) {
2249                    vrMode = r.requestedVrComponent != null;
2250                    requestedPackage = r.requestedVrComponent;
2251                    userId = r.userId;
2252                    callingPackage = r.info.getComponentName();
2253                    if (mInVrMode != vrMode) {
2254                        mInVrMode = vrMode;
2255                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2256                    }
2257                }
2258                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2259            } break;
2260            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2261                final ActivityRecord r = (ActivityRecord) msg.obj;
2262                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2263                if (needsVrMode) {
2264                    VrManagerInternal vrService =
2265                            LocalServices.getService(VrManagerInternal.class);
2266                    boolean enable = msg.arg1 == 1;
2267                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2268                            r.info.getComponentName());
2269                }
2270            } break;
2271            }
2272        }
2273    };
2274
2275    static final int COLLECT_PSS_BG_MSG = 1;
2276
2277    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2278        @Override
2279        public void handleMessage(Message msg) {
2280            switch (msg.what) {
2281            case COLLECT_PSS_BG_MSG: {
2282                long start = SystemClock.uptimeMillis();
2283                MemInfoReader memInfo = null;
2284                synchronized (ActivityManagerService.this) {
2285                    if (mFullPssPending) {
2286                        mFullPssPending = false;
2287                        memInfo = new MemInfoReader();
2288                    }
2289                }
2290                if (memInfo != null) {
2291                    updateCpuStatsNow();
2292                    long nativeTotalPss = 0;
2293                    synchronized (mProcessCpuTracker) {
2294                        final int N = mProcessCpuTracker.countStats();
2295                        for (int j=0; j<N; j++) {
2296                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2297                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2298                                // This is definitely an application process; skip it.
2299                                continue;
2300                            }
2301                            synchronized (mPidsSelfLocked) {
2302                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2303                                    // This is one of our own processes; skip it.
2304                                    continue;
2305                                }
2306                            }
2307                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2308                        }
2309                    }
2310                    memInfo.readMemInfo();
2311                    synchronized (ActivityManagerService.this) {
2312                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2313                                + (SystemClock.uptimeMillis()-start) + "ms");
2314                        final long cachedKb = memInfo.getCachedSizeKb();
2315                        final long freeKb = memInfo.getFreeSizeKb();
2316                        final long zramKb = memInfo.getZramTotalSizeKb();
2317                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2318                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2319                                kernelKb*1024, nativeTotalPss*1024);
2320                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2321                                nativeTotalPss);
2322                    }
2323                }
2324
2325                int num = 0;
2326                long[] tmp = new long[2];
2327                do {
2328                    ProcessRecord proc;
2329                    int procState;
2330                    int pid;
2331                    long lastPssTime;
2332                    synchronized (ActivityManagerService.this) {
2333                        if (mPendingPssProcesses.size() <= 0) {
2334                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2335                                    "Collected PSS of " + num + " processes in "
2336                                    + (SystemClock.uptimeMillis() - start) + "ms");
2337                            mPendingPssProcesses.clear();
2338                            return;
2339                        }
2340                        proc = mPendingPssProcesses.remove(0);
2341                        procState = proc.pssProcState;
2342                        lastPssTime = proc.lastPssTime;
2343                        if (proc.thread != null && procState == proc.setProcState
2344                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2345                                        < SystemClock.uptimeMillis()) {
2346                            pid = proc.pid;
2347                        } else {
2348                            proc = null;
2349                            pid = 0;
2350                        }
2351                    }
2352                    if (proc != null) {
2353                        long pss = Debug.getPss(pid, tmp, null);
2354                        synchronized (ActivityManagerService.this) {
2355                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2356                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2357                                num++;
2358                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2359                                        SystemClock.uptimeMillis());
2360                            }
2361                        }
2362                    }
2363                } while (true);
2364            }
2365            }
2366        }
2367    };
2368
2369    public void setSystemProcess() {
2370        try {
2371            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2372            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2373            ServiceManager.addService("meminfo", new MemBinder(this));
2374            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2375            ServiceManager.addService("dbinfo", new DbBinder(this));
2376            if (MONITOR_CPU_USAGE) {
2377                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2378            }
2379            ServiceManager.addService("permission", new PermissionController(this));
2380            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2381
2382            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2383                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2384            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2385
2386            synchronized (this) {
2387                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2388                app.persistent = true;
2389                app.pid = MY_PID;
2390                app.maxAdj = ProcessList.SYSTEM_ADJ;
2391                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2392                synchronized (mPidsSelfLocked) {
2393                    mPidsSelfLocked.put(app.pid, app);
2394                }
2395                updateLruProcessLocked(app, false, null);
2396                updateOomAdjLocked();
2397            }
2398        } catch (PackageManager.NameNotFoundException e) {
2399            throw new RuntimeException(
2400                    "Unable to find android system package", e);
2401        }
2402    }
2403
2404    public void setWindowManager(WindowManagerService wm) {
2405        mWindowManager = wm;
2406        mStackSupervisor.setWindowManager(wm);
2407        mActivityStarter.setWindowManager(wm);
2408    }
2409
2410    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2411        mUsageStatsService = usageStatsManager;
2412    }
2413
2414    public void startObservingNativeCrashes() {
2415        final NativeCrashListener ncl = new NativeCrashListener(this);
2416        ncl.start();
2417    }
2418
2419    public IAppOpsService getAppOpsService() {
2420        return mAppOpsService;
2421    }
2422
2423    static class MemBinder extends Binder {
2424        ActivityManagerService mActivityManagerService;
2425        MemBinder(ActivityManagerService activityManagerService) {
2426            mActivityManagerService = activityManagerService;
2427        }
2428
2429        @Override
2430        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2431            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2432                    != PackageManager.PERMISSION_GRANTED) {
2433                pw.println("Permission Denial: can't dump meminfo from from pid="
2434                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2435                        + " without permission " + android.Manifest.permission.DUMP);
2436                return;
2437            }
2438
2439            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2440        }
2441    }
2442
2443    static class GraphicsBinder extends Binder {
2444        ActivityManagerService mActivityManagerService;
2445        GraphicsBinder(ActivityManagerService activityManagerService) {
2446            mActivityManagerService = activityManagerService;
2447        }
2448
2449        @Override
2450        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2451            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2452                    != PackageManager.PERMISSION_GRANTED) {
2453                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2454                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2455                        + " without permission " + android.Manifest.permission.DUMP);
2456                return;
2457            }
2458
2459            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2460        }
2461    }
2462
2463    static class DbBinder extends Binder {
2464        ActivityManagerService mActivityManagerService;
2465        DbBinder(ActivityManagerService activityManagerService) {
2466            mActivityManagerService = activityManagerService;
2467        }
2468
2469        @Override
2470        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2471            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2472                    != PackageManager.PERMISSION_GRANTED) {
2473                pw.println("Permission Denial: can't dump dbinfo from from pid="
2474                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2475                        + " without permission " + android.Manifest.permission.DUMP);
2476                return;
2477            }
2478
2479            mActivityManagerService.dumpDbInfo(fd, pw, args);
2480        }
2481    }
2482
2483    static class CpuBinder extends Binder {
2484        ActivityManagerService mActivityManagerService;
2485        CpuBinder(ActivityManagerService activityManagerService) {
2486            mActivityManagerService = activityManagerService;
2487        }
2488
2489        @Override
2490        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2491            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2492                    != PackageManager.PERMISSION_GRANTED) {
2493                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2494                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2495                        + " without permission " + android.Manifest.permission.DUMP);
2496                return;
2497            }
2498
2499            synchronized (mActivityManagerService.mProcessCpuTracker) {
2500                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2501                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2502                        SystemClock.uptimeMillis()));
2503            }
2504        }
2505    }
2506
2507    public static final class Lifecycle extends SystemService {
2508        private final ActivityManagerService mService;
2509
2510        public Lifecycle(Context context) {
2511            super(context);
2512            mService = new ActivityManagerService(context);
2513        }
2514
2515        @Override
2516        public void onStart() {
2517            mService.start();
2518        }
2519
2520        public ActivityManagerService getService() {
2521            return mService;
2522        }
2523    }
2524
2525    // Note: This method is invoked on the main thread but may need to attach various
2526    // handlers to other threads.  So take care to be explicit about the looper.
2527    public ActivityManagerService(Context systemContext) {
2528        mContext = systemContext;
2529        mFactoryTest = FactoryTest.getMode();
2530        mSystemThread = ActivityThread.currentActivityThread();
2531
2532        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2533
2534        mHandlerThread = new ServiceThread(TAG,
2535                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2536        mHandlerThread.start();
2537        mHandler = new MainHandler(mHandlerThread.getLooper());
2538        mUiHandler = new UiHandler();
2539
2540        /* static; one-time init here */
2541        if (sKillHandler == null) {
2542            sKillThread = new ServiceThread(TAG + ":kill",
2543                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2544            sKillThread.start();
2545            sKillHandler = new KillHandler(sKillThread.getLooper());
2546        }
2547
2548        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2549                "foreground", BROADCAST_FG_TIMEOUT, false);
2550        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2551                "background", BROADCAST_BG_TIMEOUT, true);
2552        mBroadcastQueues[0] = mFgBroadcastQueue;
2553        mBroadcastQueues[1] = mBgBroadcastQueue;
2554
2555        mServices = new ActiveServices(this);
2556        mProviderMap = new ProviderMap(this);
2557        mAppErrors = new AppErrors(mContext, this);
2558
2559        // TODO: Move creation of battery stats service outside of activity manager service.
2560        File dataDir = Environment.getDataDirectory();
2561        File systemDir = new File(dataDir, "system");
2562        systemDir.mkdirs();
2563        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2564        mBatteryStatsService.getActiveStatistics().readLocked();
2565        mBatteryStatsService.scheduleWriteToDisk();
2566        mOnBattery = DEBUG_POWER ? true
2567                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2568        mBatteryStatsService.getActiveStatistics().setCallback(this);
2569
2570        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2571
2572        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2573        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2574                new IAppOpsCallback.Stub() {
2575                    @Override public void opChanged(int op, int uid, String packageName) {
2576                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2577                            if (mAppOpsService.checkOperation(op, uid, packageName)
2578                                    != AppOpsManager.MODE_ALLOWED) {
2579                                runInBackgroundDisabled(uid);
2580                            }
2581                        }
2582                    }
2583                });
2584
2585        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2586
2587        mUserController = new UserController(this);
2588
2589        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2590            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2591
2592        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2593
2594        mConfiguration.setToDefaults();
2595        mConfiguration.setLocales(LocaleList.getDefault());
2596
2597        mConfigurationSeq = mConfiguration.seq = 1;
2598        mProcessCpuTracker.init();
2599
2600        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2601        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2602        mStackSupervisor = new ActivityStackSupervisor(this);
2603        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2604        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2605
2606        mProcessCpuThread = new Thread("CpuTracker") {
2607            @Override
2608            public void run() {
2609                while (true) {
2610                    try {
2611                        try {
2612                            synchronized(this) {
2613                                final long now = SystemClock.uptimeMillis();
2614                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2615                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2616                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2617                                //        + ", write delay=" + nextWriteDelay);
2618                                if (nextWriteDelay < nextCpuDelay) {
2619                                    nextCpuDelay = nextWriteDelay;
2620                                }
2621                                if (nextCpuDelay > 0) {
2622                                    mProcessCpuMutexFree.set(true);
2623                                    this.wait(nextCpuDelay);
2624                                }
2625                            }
2626                        } catch (InterruptedException e) {
2627                        }
2628                        updateCpuStatsNow();
2629                    } catch (Exception e) {
2630                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2631                    }
2632                }
2633            }
2634        };
2635
2636        Watchdog.getInstance().addMonitor(this);
2637        Watchdog.getInstance().addThread(mHandler);
2638    }
2639
2640    public void setSystemServiceManager(SystemServiceManager mgr) {
2641        mSystemServiceManager = mgr;
2642    }
2643
2644    public void setInstaller(Installer installer) {
2645        mInstaller = installer;
2646    }
2647
2648    private void start() {
2649        Process.removeAllProcessGroups();
2650        mProcessCpuThread.start();
2651
2652        mBatteryStatsService.publish(mContext);
2653        mAppOpsService.publish(mContext);
2654        Slog.d("AppOps", "AppOpsService published");
2655        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2656    }
2657
2658    void onUserStoppedLocked(int userId) {
2659        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2660    }
2661
2662    public void initPowerManagement() {
2663        mStackSupervisor.initPowerManagement();
2664        mBatteryStatsService.initPowerManagement();
2665        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2666        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2667        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2668        mVoiceWakeLock.setReferenceCounted(false);
2669    }
2670
2671    @Override
2672    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2673            throws RemoteException {
2674        if (code == SYSPROPS_TRANSACTION) {
2675            // We need to tell all apps about the system property change.
2676            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2677            synchronized(this) {
2678                final int NP = mProcessNames.getMap().size();
2679                for (int ip=0; ip<NP; ip++) {
2680                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2681                    final int NA = apps.size();
2682                    for (int ia=0; ia<NA; ia++) {
2683                        ProcessRecord app = apps.valueAt(ia);
2684                        if (app.thread != null) {
2685                            procs.add(app.thread.asBinder());
2686                        }
2687                    }
2688                }
2689            }
2690
2691            int N = procs.size();
2692            for (int i=0; i<N; i++) {
2693                Parcel data2 = Parcel.obtain();
2694                try {
2695                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2696                } catch (RemoteException e) {
2697                }
2698                data2.recycle();
2699            }
2700        }
2701        try {
2702            return super.onTransact(code, data, reply, flags);
2703        } catch (RuntimeException e) {
2704            // The activity manager only throws security exceptions, so let's
2705            // log all others.
2706            if (!(e instanceof SecurityException)) {
2707                Slog.wtf(TAG, "Activity Manager Crash", e);
2708            }
2709            throw e;
2710        }
2711    }
2712
2713    void updateCpuStats() {
2714        final long now = SystemClock.uptimeMillis();
2715        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2716            return;
2717        }
2718        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2719            synchronized (mProcessCpuThread) {
2720                mProcessCpuThread.notify();
2721            }
2722        }
2723    }
2724
2725    void updateCpuStatsNow() {
2726        synchronized (mProcessCpuTracker) {
2727            mProcessCpuMutexFree.set(false);
2728            final long now = SystemClock.uptimeMillis();
2729            boolean haveNewCpuStats = false;
2730
2731            if (MONITOR_CPU_USAGE &&
2732                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2733                mLastCpuTime.set(now);
2734                mProcessCpuTracker.update();
2735                if (mProcessCpuTracker.hasGoodLastStats()) {
2736                    haveNewCpuStats = true;
2737                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2738                    //Slog.i(TAG, "Total CPU usage: "
2739                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2740
2741                    // Slog the cpu usage if the property is set.
2742                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2743                        int user = mProcessCpuTracker.getLastUserTime();
2744                        int system = mProcessCpuTracker.getLastSystemTime();
2745                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2746                        int irq = mProcessCpuTracker.getLastIrqTime();
2747                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2748                        int idle = mProcessCpuTracker.getLastIdleTime();
2749
2750                        int total = user + system + iowait + irq + softIrq + idle;
2751                        if (total == 0) total = 1;
2752
2753                        EventLog.writeEvent(EventLogTags.CPU,
2754                                ((user+system+iowait+irq+softIrq) * 100) / total,
2755                                (user * 100) / total,
2756                                (system * 100) / total,
2757                                (iowait * 100) / total,
2758                                (irq * 100) / total,
2759                                (softIrq * 100) / total);
2760                    }
2761                }
2762            }
2763
2764            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2765            synchronized(bstats) {
2766                synchronized(mPidsSelfLocked) {
2767                    if (haveNewCpuStats) {
2768                        if (bstats.startAddingCpuLocked()) {
2769                            int totalUTime = 0;
2770                            int totalSTime = 0;
2771                            final int N = mProcessCpuTracker.countStats();
2772                            for (int i=0; i<N; i++) {
2773                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2774                                if (!st.working) {
2775                                    continue;
2776                                }
2777                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2778                                totalUTime += st.rel_utime;
2779                                totalSTime += st.rel_stime;
2780                                if (pr != null) {
2781                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2782                                    if (ps == null || !ps.isActive()) {
2783                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2784                                                pr.info.uid, pr.processName);
2785                                    }
2786                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2787                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2788                                } else {
2789                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2790                                    if (ps == null || !ps.isActive()) {
2791                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2792                                                bstats.mapUid(st.uid), st.name);
2793                                    }
2794                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2795                                }
2796                            }
2797                            final int userTime = mProcessCpuTracker.getLastUserTime();
2798                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2799                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2800                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2801                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2802                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2803                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2804                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2805                        }
2806                    }
2807                }
2808
2809                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2810                    mLastWriteTime = now;
2811                    mBatteryStatsService.scheduleWriteToDisk();
2812                }
2813            }
2814        }
2815    }
2816
2817    @Override
2818    public void batteryNeedsCpuUpdate() {
2819        updateCpuStatsNow();
2820    }
2821
2822    @Override
2823    public void batteryPowerChanged(boolean onBattery) {
2824        // When plugging in, update the CPU stats first before changing
2825        // the plug state.
2826        updateCpuStatsNow();
2827        synchronized (this) {
2828            synchronized(mPidsSelfLocked) {
2829                mOnBattery = DEBUG_POWER ? true : onBattery;
2830            }
2831        }
2832    }
2833
2834    @Override
2835    public void batterySendBroadcast(Intent intent) {
2836        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2837                AppOpsManager.OP_NONE, null, false, false,
2838                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2839    }
2840
2841    /**
2842     * Initialize the application bind args. These are passed to each
2843     * process when the bindApplication() IPC is sent to the process. They're
2844     * lazily setup to make sure the services are running when they're asked for.
2845     */
2846    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2847        if (mAppBindArgs == null) {
2848            mAppBindArgs = new HashMap<>();
2849
2850            // Isolated processes won't get this optimization, so that we don't
2851            // violate the rules about which services they have access to.
2852            if (!isolated) {
2853                // Setup the application init args
2854                mAppBindArgs.put("package", ServiceManager.getService("package"));
2855                mAppBindArgs.put("window", ServiceManager.getService("window"));
2856                mAppBindArgs.put(Context.ALARM_SERVICE,
2857                        ServiceManager.getService(Context.ALARM_SERVICE));
2858            }
2859        }
2860        return mAppBindArgs;
2861    }
2862
2863    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2864        if (r == null || mFocusedActivity == r) {
2865            return false;
2866        }
2867
2868        if (!r.isFocusable()) {
2869            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2870            return false;
2871        }
2872
2873        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2874
2875        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2876        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2877                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2878        mDoingSetFocusedActivity = true;
2879
2880        final ActivityRecord last = mFocusedActivity;
2881        mFocusedActivity = r;
2882        if (r.task.isApplicationTask()) {
2883            if (mCurAppTimeTracker != r.appTimeTracker) {
2884                // We are switching app tracking.  Complete the current one.
2885                if (mCurAppTimeTracker != null) {
2886                    mCurAppTimeTracker.stop();
2887                    mHandler.obtainMessage(
2888                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2889                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2890                    mCurAppTimeTracker = null;
2891                }
2892                if (r.appTimeTracker != null) {
2893                    mCurAppTimeTracker = r.appTimeTracker;
2894                    startTimeTrackingFocusedActivityLocked();
2895                }
2896            } else {
2897                startTimeTrackingFocusedActivityLocked();
2898            }
2899        } else {
2900            r.appTimeTracker = null;
2901        }
2902        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2903        // TODO: Probably not, because we don't want to resume voice on switching
2904        // back to this activity
2905        if (r.task.voiceInteractor != null) {
2906            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2907        } else {
2908            finishRunningVoiceLocked();
2909            IVoiceInteractionSession session;
2910            if (last != null && ((session = last.task.voiceSession) != null
2911                    || (session = last.voiceSession) != null)) {
2912                // We had been in a voice interaction session, but now focused has
2913                // move to something different.  Just finish the session, we can't
2914                // return to it and retain the proper state and synchronization with
2915                // the voice interaction service.
2916                finishVoiceTask(session);
2917            }
2918        }
2919        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2920            mWindowManager.setFocusedApp(r.appToken, true);
2921        }
2922        applyUpdateLockStateLocked(r);
2923        applyUpdateVrModeLocked(r);
2924        if (mFocusedActivity.userId != mLastFocusedUserId) {
2925            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2926            mHandler.obtainMessage(
2927                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2928            mLastFocusedUserId = mFocusedActivity.userId;
2929        }
2930
2931        // Log a warning if the focused app is changed during the process. This could
2932        // indicate a problem of the focus setting logic!
2933        if (mFocusedActivity != r) Slog.w(TAG,
2934                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2935        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2936
2937        EventLogTags.writeAmFocusedActivity(
2938                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2939                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2940                reason);
2941        return true;
2942    }
2943
2944    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2945        if (mFocusedActivity != goingAway) {
2946            return;
2947        }
2948
2949        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2950        if (focusedStack != null) {
2951            final ActivityRecord top = focusedStack.topActivity();
2952            if (top != null && top.userId != mLastFocusedUserId) {
2953                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2954                mHandler.sendMessage(
2955                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2956                mLastFocusedUserId = top.userId;
2957            }
2958        }
2959
2960        // Try to move focus to another activity if possible.
2961        if (setFocusedActivityLocked(
2962                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2963            return;
2964        }
2965
2966        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2967                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2968        mFocusedActivity = null;
2969        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2970    }
2971
2972    @Override
2973    public void setFocusedStack(int stackId) {
2974        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2975        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2976        final long callingId = Binder.clearCallingIdentity();
2977        try {
2978            synchronized (this) {
2979                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2980                if (stack == null) {
2981                    return;
2982                }
2983                final ActivityRecord r = stack.topRunningActivityLocked();
2984                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2985                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2986                }
2987            }
2988        } finally {
2989            Binder.restoreCallingIdentity(callingId);
2990        }
2991    }
2992
2993    @Override
2994    public void setFocusedTask(int taskId) {
2995        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2996        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2997        final long callingId = Binder.clearCallingIdentity();
2998        try {
2999            synchronized (this) {
3000                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3001                if (task == null) {
3002                    return;
3003                }
3004                final ActivityRecord r = task.topRunningActivityLocked();
3005                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3006                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3007                }
3008            }
3009        } finally {
3010            Binder.restoreCallingIdentity(callingId);
3011        }
3012    }
3013
3014    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3015    @Override
3016    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3017        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3018        synchronized (this) {
3019            if (listener != null) {
3020                mTaskStackListeners.register(listener);
3021            }
3022        }
3023    }
3024
3025    @Override
3026    public void notifyActivityDrawn(IBinder token) {
3027        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3028        synchronized (this) {
3029            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3030            if (r != null) {
3031                r.task.stack.notifyActivityDrawnLocked(r);
3032            }
3033        }
3034    }
3035
3036    final void applyUpdateLockStateLocked(ActivityRecord r) {
3037        // Modifications to the UpdateLock state are done on our handler, outside
3038        // the activity manager's locks.  The new state is determined based on the
3039        // state *now* of the relevant activity record.  The object is passed to
3040        // the handler solely for logging detail, not to be consulted/modified.
3041        final boolean nextState = r != null && r.immersive;
3042        mHandler.sendMessage(
3043                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3044    }
3045
3046    final void applyUpdateVrModeLocked(ActivityRecord r) {
3047        mHandler.sendMessage(
3048                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3049    }
3050
3051    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3052        mHandler.sendMessage(
3053                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3054    }
3055
3056    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3057        Message msg = Message.obtain();
3058        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3059        msg.obj = r.task.askedCompatMode ? null : r;
3060        mUiHandler.sendMessage(msg);
3061    }
3062
3063    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3064            String what, Object obj, ProcessRecord srcApp) {
3065        app.lastActivityTime = now;
3066
3067        if (app.activities.size() > 0) {
3068            // Don't want to touch dependent processes that are hosting activities.
3069            return index;
3070        }
3071
3072        int lrui = mLruProcesses.lastIndexOf(app);
3073        if (lrui < 0) {
3074            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3075                    + what + " " + obj + " from " + srcApp);
3076            return index;
3077        }
3078
3079        if (lrui >= index) {
3080            // Don't want to cause this to move dependent processes *back* in the
3081            // list as if they were less frequently used.
3082            return index;
3083        }
3084
3085        if (lrui >= mLruProcessActivityStart) {
3086            // Don't want to touch dependent processes that are hosting activities.
3087            return index;
3088        }
3089
3090        mLruProcesses.remove(lrui);
3091        if (index > 0) {
3092            index--;
3093        }
3094        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3095                + " in LRU list: " + app);
3096        mLruProcesses.add(index, app);
3097        return index;
3098    }
3099
3100    static void killProcessGroup(int uid, int pid) {
3101        if (sKillHandler != null) {
3102            sKillHandler.sendMessage(
3103                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3104        } else {
3105            Slog.w(TAG, "Asked to kill process group before system bringup!");
3106            Process.killProcessGroup(uid, pid);
3107        }
3108    }
3109
3110    final void removeLruProcessLocked(ProcessRecord app) {
3111        int lrui = mLruProcesses.lastIndexOf(app);
3112        if (lrui >= 0) {
3113            if (!app.killed) {
3114                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3115                Process.killProcessQuiet(app.pid);
3116                killProcessGroup(app.uid, app.pid);
3117            }
3118            if (lrui <= mLruProcessActivityStart) {
3119                mLruProcessActivityStart--;
3120            }
3121            if (lrui <= mLruProcessServiceStart) {
3122                mLruProcessServiceStart--;
3123            }
3124            mLruProcesses.remove(lrui);
3125        }
3126    }
3127
3128    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3129            ProcessRecord client) {
3130        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3131                || app.treatLikeActivity;
3132        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3133        if (!activityChange && hasActivity) {
3134            // The process has activities, so we are only allowing activity-based adjustments
3135            // to move it.  It should be kept in the front of the list with other
3136            // processes that have activities, and we don't want those to change their
3137            // order except due to activity operations.
3138            return;
3139        }
3140
3141        mLruSeq++;
3142        final long now = SystemClock.uptimeMillis();
3143        app.lastActivityTime = now;
3144
3145        // First a quick reject: if the app is already at the position we will
3146        // put it, then there is nothing to do.
3147        if (hasActivity) {
3148            final int N = mLruProcesses.size();
3149            if (N > 0 && mLruProcesses.get(N-1) == app) {
3150                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3151                return;
3152            }
3153        } else {
3154            if (mLruProcessServiceStart > 0
3155                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3156                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3157                return;
3158            }
3159        }
3160
3161        int lrui = mLruProcesses.lastIndexOf(app);
3162
3163        if (app.persistent && lrui >= 0) {
3164            // We don't care about the position of persistent processes, as long as
3165            // they are in the list.
3166            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3167            return;
3168        }
3169
3170        /* In progress: compute new position first, so we can avoid doing work
3171           if the process is not actually going to move.  Not yet working.
3172        int addIndex;
3173        int nextIndex;
3174        boolean inActivity = false, inService = false;
3175        if (hasActivity) {
3176            // Process has activities, put it at the very tipsy-top.
3177            addIndex = mLruProcesses.size();
3178            nextIndex = mLruProcessServiceStart;
3179            inActivity = true;
3180        } else if (hasService) {
3181            // Process has services, put it at the top of the service list.
3182            addIndex = mLruProcessActivityStart;
3183            nextIndex = mLruProcessServiceStart;
3184            inActivity = true;
3185            inService = true;
3186        } else  {
3187            // Process not otherwise of interest, it goes to the top of the non-service area.
3188            addIndex = mLruProcessServiceStart;
3189            if (client != null) {
3190                int clientIndex = mLruProcesses.lastIndexOf(client);
3191                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3192                        + app);
3193                if (clientIndex >= 0 && addIndex > clientIndex) {
3194                    addIndex = clientIndex;
3195                }
3196            }
3197            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3198        }
3199
3200        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3201                + mLruProcessActivityStart + "): " + app);
3202        */
3203
3204        if (lrui >= 0) {
3205            if (lrui < mLruProcessActivityStart) {
3206                mLruProcessActivityStart--;
3207            }
3208            if (lrui < mLruProcessServiceStart) {
3209                mLruProcessServiceStart--;
3210            }
3211            /*
3212            if (addIndex > lrui) {
3213                addIndex--;
3214            }
3215            if (nextIndex > lrui) {
3216                nextIndex--;
3217            }
3218            */
3219            mLruProcesses.remove(lrui);
3220        }
3221
3222        /*
3223        mLruProcesses.add(addIndex, app);
3224        if (inActivity) {
3225            mLruProcessActivityStart++;
3226        }
3227        if (inService) {
3228            mLruProcessActivityStart++;
3229        }
3230        */
3231
3232        int nextIndex;
3233        if (hasActivity) {
3234            final int N = mLruProcesses.size();
3235            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3236                // Process doesn't have activities, but has clients with
3237                // activities...  move it up, but one below the top (the top
3238                // should always have a real activity).
3239                if (DEBUG_LRU) Slog.d(TAG_LRU,
3240                        "Adding to second-top of LRU activity list: " + app);
3241                mLruProcesses.add(N - 1, app);
3242                // To keep it from spamming the LRU list (by making a bunch of clients),
3243                // we will push down any other entries owned by the app.
3244                final int uid = app.info.uid;
3245                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3246                    ProcessRecord subProc = mLruProcesses.get(i);
3247                    if (subProc.info.uid == uid) {
3248                        // We want to push this one down the list.  If the process after
3249                        // it is for the same uid, however, don't do so, because we don't
3250                        // want them internally to be re-ordered.
3251                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3252                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3253                                    "Pushing uid " + uid + " swapping at " + i + ": "
3254                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3255                            ProcessRecord tmp = mLruProcesses.get(i);
3256                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3257                            mLruProcesses.set(i - 1, tmp);
3258                            i--;
3259                        }
3260                    } else {
3261                        // A gap, we can stop here.
3262                        break;
3263                    }
3264                }
3265            } else {
3266                // Process has activities, put it at the very tipsy-top.
3267                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3268                mLruProcesses.add(app);
3269            }
3270            nextIndex = mLruProcessServiceStart;
3271        } else if (hasService) {
3272            // Process has services, put it at the top of the service list.
3273            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3274            mLruProcesses.add(mLruProcessActivityStart, app);
3275            nextIndex = mLruProcessServiceStart;
3276            mLruProcessActivityStart++;
3277        } else  {
3278            // Process not otherwise of interest, it goes to the top of the non-service area.
3279            int index = mLruProcessServiceStart;
3280            if (client != null) {
3281                // If there is a client, don't allow the process to be moved up higher
3282                // in the list than that client.
3283                int clientIndex = mLruProcesses.lastIndexOf(client);
3284                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3285                        + " when updating " + app);
3286                if (clientIndex <= lrui) {
3287                    // Don't allow the client index restriction to push it down farther in the
3288                    // list than it already is.
3289                    clientIndex = lrui;
3290                }
3291                if (clientIndex >= 0 && index > clientIndex) {
3292                    index = clientIndex;
3293                }
3294            }
3295            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3296            mLruProcesses.add(index, app);
3297            nextIndex = index-1;
3298            mLruProcessActivityStart++;
3299            mLruProcessServiceStart++;
3300        }
3301
3302        // If the app is currently using a content provider or service,
3303        // bump those processes as well.
3304        for (int j=app.connections.size()-1; j>=0; j--) {
3305            ConnectionRecord cr = app.connections.valueAt(j);
3306            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3307                    && cr.binding.service.app != null
3308                    && cr.binding.service.app.lruSeq != mLruSeq
3309                    && !cr.binding.service.app.persistent) {
3310                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3311                        "service connection", cr, app);
3312            }
3313        }
3314        for (int j=app.conProviders.size()-1; j>=0; j--) {
3315            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3316            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3317                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3318                        "provider reference", cpr, app);
3319            }
3320        }
3321    }
3322
3323    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3324        if (uid == Process.SYSTEM_UID) {
3325            // The system gets to run in any process.  If there are multiple
3326            // processes with the same uid, just pick the first (this
3327            // should never happen).
3328            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3329            if (procs == null) return null;
3330            final int procCount = procs.size();
3331            for (int i = 0; i < procCount; i++) {
3332                final int procUid = procs.keyAt(i);
3333                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3334                    // Don't use an app process or different user process for system component.
3335                    continue;
3336                }
3337                return procs.valueAt(i);
3338            }
3339        }
3340        ProcessRecord proc = mProcessNames.get(processName, uid);
3341        if (false && proc != null && !keepIfLarge
3342                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3343                && proc.lastCachedPss >= 4000) {
3344            // Turn this condition on to cause killing to happen regularly, for testing.
3345            if (proc.baseProcessTracker != null) {
3346                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3347            }
3348            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3349        } else if (proc != null && !keepIfLarge
3350                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3351                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3352            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3353            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3354                if (proc.baseProcessTracker != null) {
3355                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3356                }
3357                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3358            }
3359        }
3360        return proc;
3361    }
3362
3363    void notifyPackageUse(String packageName, int reason) {
3364        IPackageManager pm = AppGlobals.getPackageManager();
3365        try {
3366            pm.notifyPackageUse(packageName, reason);
3367        } catch (RemoteException e) {
3368        }
3369    }
3370
3371    boolean isNextTransitionForward() {
3372        int transit = mWindowManager.getPendingAppTransition();
3373        return transit == TRANSIT_ACTIVITY_OPEN
3374                || transit == TRANSIT_TASK_OPEN
3375                || transit == TRANSIT_TASK_TO_FRONT;
3376    }
3377
3378    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3379            String processName, String abiOverride, int uid, Runnable crashHandler) {
3380        synchronized(this) {
3381            ApplicationInfo info = new ApplicationInfo();
3382            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3383            // For isolated processes, the former contains the parent's uid and the latter the
3384            // actual uid of the isolated process.
3385            // In the special case introduced by this method (which is, starting an isolated
3386            // process directly from the SystemServer without an actual parent app process) the
3387            // closest thing to a parent's uid is SYSTEM_UID.
3388            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3389            // the |isolated| logic in the ProcessRecord constructor.
3390            info.uid = Process.SYSTEM_UID;
3391            info.processName = processName;
3392            info.className = entryPoint;
3393            info.packageName = "android";
3394            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3395                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3396                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3397                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3398                    crashHandler);
3399            return proc != null ? proc.pid : 0;
3400        }
3401    }
3402
3403    final ProcessRecord startProcessLocked(String processName,
3404            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3405            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3406            boolean isolated, boolean keepIfLarge) {
3407        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3408                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3409                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3410                null /* crashHandler */);
3411    }
3412
3413    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3414            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3415            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3416            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3417        long startTime = SystemClock.elapsedRealtime();
3418        ProcessRecord app;
3419        if (!isolated) {
3420            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3421            checkTime(startTime, "startProcess: after getProcessRecord");
3422
3423            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3424                // If we are in the background, then check to see if this process
3425                // is bad.  If so, we will just silently fail.
3426                if (mAppErrors.isBadProcessLocked(info)) {
3427                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3428                            + "/" + info.processName);
3429                    return null;
3430                }
3431            } else {
3432                // When the user is explicitly starting a process, then clear its
3433                // crash count so that we won't make it bad until they see at
3434                // least one crash dialog again, and make the process good again
3435                // if it had been bad.
3436                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3437                        + "/" + info.processName);
3438                mAppErrors.resetProcessCrashTimeLocked(info);
3439                if (mAppErrors.isBadProcessLocked(info)) {
3440                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3441                            UserHandle.getUserId(info.uid), info.uid,
3442                            info.processName);
3443                    mAppErrors.clearBadProcessLocked(info);
3444                    if (app != null) {
3445                        app.bad = false;
3446                    }
3447                }
3448            }
3449        } else {
3450            // If this is an isolated process, it can't re-use an existing process.
3451            app = null;
3452        }
3453
3454        // app launch boost for big.little configurations
3455        // use cpusets to migrate freshly launched tasks to big cores
3456        synchronized(ActivityManagerService.this) {
3457            nativeMigrateToBoost();
3458            mIsBoosted = true;
3459            mBoostStartTime = SystemClock.uptimeMillis();
3460            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3461            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3462        }
3463
3464        // We don't have to do anything more if:
3465        // (1) There is an existing application record; and
3466        // (2) The caller doesn't think it is dead, OR there is no thread
3467        //     object attached to it so we know it couldn't have crashed; and
3468        // (3) There is a pid assigned to it, so it is either starting or
3469        //     already running.
3470        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3471                + " app=" + app + " knownToBeDead=" + knownToBeDead
3472                + " thread=" + (app != null ? app.thread : null)
3473                + " pid=" + (app != null ? app.pid : -1));
3474        if (app != null && app.pid > 0) {
3475            if (!knownToBeDead || app.thread == null) {
3476                // We already have the app running, or are waiting for it to
3477                // come up (we have a pid but not yet its thread), so keep it.
3478                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3479                // If this is a new package in the process, add the package to the list
3480                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3481                checkTime(startTime, "startProcess: done, added package to proc");
3482                return app;
3483            }
3484
3485            // An application record is attached to a previous process,
3486            // clean it up now.
3487            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3488            checkTime(startTime, "startProcess: bad proc running, killing");
3489            killProcessGroup(app.uid, app.pid);
3490            handleAppDiedLocked(app, true, true);
3491            checkTime(startTime, "startProcess: done killing old proc");
3492        }
3493
3494        String hostingNameStr = hostingName != null
3495                ? hostingName.flattenToShortString() : null;
3496
3497        if (app == null) {
3498            checkTime(startTime, "startProcess: creating new process record");
3499            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3500            if (app == null) {
3501                Slog.w(TAG, "Failed making new process record for "
3502                        + processName + "/" + info.uid + " isolated=" + isolated);
3503                return null;
3504            }
3505            app.crashHandler = crashHandler;
3506            checkTime(startTime, "startProcess: done creating new process record");
3507        } else {
3508            // If this is a new package in the process, add the package to the list
3509            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3510            checkTime(startTime, "startProcess: added package to existing proc");
3511        }
3512
3513        // If the system is not ready yet, then hold off on starting this
3514        // process until it is.
3515        if (!mProcessesReady
3516                && !isAllowedWhileBooting(info)
3517                && !allowWhileBooting) {
3518            if (!mProcessesOnHold.contains(app)) {
3519                mProcessesOnHold.add(app);
3520            }
3521            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3522                    "System not ready, putting on hold: " + app);
3523            checkTime(startTime, "startProcess: returning with proc on hold");
3524            return app;
3525        }
3526
3527        checkTime(startTime, "startProcess: stepping in to startProcess");
3528        startProcessLocked(
3529                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3530        checkTime(startTime, "startProcess: done starting proc!");
3531        return (app.pid != 0) ? app : null;
3532    }
3533
3534    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3535        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3536    }
3537
3538    private final void startProcessLocked(ProcessRecord app,
3539            String hostingType, String hostingNameStr) {
3540        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3541                null /* entryPoint */, null /* entryPointArgs */);
3542    }
3543
3544    private final void startProcessLocked(ProcessRecord app, String hostingType,
3545            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3546        long startTime = SystemClock.elapsedRealtime();
3547        if (app.pid > 0 && app.pid != MY_PID) {
3548            checkTime(startTime, "startProcess: removing from pids map");
3549            synchronized (mPidsSelfLocked) {
3550                mPidsSelfLocked.remove(app.pid);
3551                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3552            }
3553            checkTime(startTime, "startProcess: done removing from pids map");
3554            app.setPid(0);
3555        }
3556
3557        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3558                "startProcessLocked removing on hold: " + app);
3559        mProcessesOnHold.remove(app);
3560
3561        checkTime(startTime, "startProcess: starting to update cpu stats");
3562        updateCpuStats();
3563        checkTime(startTime, "startProcess: done updating cpu stats");
3564
3565        try {
3566            try {
3567                final int userId = UserHandle.getUserId(app.uid);
3568                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3569            } catch (RemoteException e) {
3570                throw e.rethrowAsRuntimeException();
3571            }
3572
3573            int uid = app.uid;
3574            int[] gids = null;
3575            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3576            if (!app.isolated) {
3577                int[] permGids = null;
3578                try {
3579                    checkTime(startTime, "startProcess: getting gids from package manager");
3580                    final IPackageManager pm = AppGlobals.getPackageManager();
3581                    permGids = pm.getPackageGids(app.info.packageName,
3582                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3583                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3584                            MountServiceInternal.class);
3585                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3586                            app.info.packageName);
3587                } catch (RemoteException e) {
3588                    throw e.rethrowAsRuntimeException();
3589                }
3590
3591                /*
3592                 * Add shared application and profile GIDs so applications can share some
3593                 * resources like shared libraries and access user-wide resources
3594                 */
3595                if (ArrayUtils.isEmpty(permGids)) {
3596                    gids = new int[2];
3597                } else {
3598                    gids = new int[permGids.length + 2];
3599                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3600                }
3601                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3602                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3603            }
3604            checkTime(startTime, "startProcess: building args");
3605            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3606                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3607                        && mTopComponent != null
3608                        && app.processName.equals(mTopComponent.getPackageName())) {
3609                    uid = 0;
3610                }
3611                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3612                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3613                    uid = 0;
3614                }
3615            }
3616            int debugFlags = 0;
3617            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3618                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3619                // Also turn on CheckJNI for debuggable apps. It's quite
3620                // awkward to turn on otherwise.
3621                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3622            }
3623            // Run the app in safe mode if its manifest requests so or the
3624            // system is booted in safe mode.
3625            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3626                mSafeMode == true) {
3627                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3628            }
3629            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3630                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3631            }
3632            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3633            if ("true".equals(genDebugInfoProperty)) {
3634                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3635            }
3636            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3637                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3638            }
3639            if ("1".equals(SystemProperties.get("debug.assert"))) {
3640                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3641            }
3642            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3643                // Enable all debug flags required by the native debugger.
3644                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3645                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3646                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3647                mNativeDebuggingApp = null;
3648            }
3649
3650            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3651            if (requiredAbi == null) {
3652                requiredAbi = Build.SUPPORTED_ABIS[0];
3653            }
3654
3655            String instructionSet = null;
3656            if (app.info.primaryCpuAbi != null) {
3657                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3658            }
3659
3660            app.gids = gids;
3661            app.requiredAbi = requiredAbi;
3662            app.instructionSet = instructionSet;
3663
3664            // Start the process.  It will either succeed and return a result containing
3665            // the PID of the new process, or else throw a RuntimeException.
3666            boolean isActivityProcess = (entryPoint == null);
3667            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3668            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3669                    app.processName);
3670            checkTime(startTime, "startProcess: asking zygote to start proc");
3671            Process.ProcessStartResult startResult = Process.start(entryPoint,
3672                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3673                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3674                    app.info.dataDir, entryPointArgs);
3675            checkTime(startTime, "startProcess: returned from zygote!");
3676            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3677
3678            if (app.isolated) {
3679                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3680            }
3681            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3682            checkTime(startTime, "startProcess: done updating battery stats");
3683
3684            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3685                    UserHandle.getUserId(uid), startResult.pid, uid,
3686                    app.processName, hostingType,
3687                    hostingNameStr != null ? hostingNameStr : "");
3688
3689            try {
3690                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3691                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3692            } catch (RemoteException ex) {
3693                // Ignore
3694            }
3695
3696            if (app.persistent) {
3697                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3698            }
3699
3700            checkTime(startTime, "startProcess: building log message");
3701            StringBuilder buf = mStringBuilder;
3702            buf.setLength(0);
3703            buf.append("Start proc ");
3704            buf.append(startResult.pid);
3705            buf.append(':');
3706            buf.append(app.processName);
3707            buf.append('/');
3708            UserHandle.formatUid(buf, uid);
3709            if (!isActivityProcess) {
3710                buf.append(" [");
3711                buf.append(entryPoint);
3712                buf.append("]");
3713            }
3714            buf.append(" for ");
3715            buf.append(hostingType);
3716            if (hostingNameStr != null) {
3717                buf.append(" ");
3718                buf.append(hostingNameStr);
3719            }
3720            Slog.i(TAG, buf.toString());
3721            app.setPid(startResult.pid);
3722            app.usingWrapper = startResult.usingWrapper;
3723            app.removed = false;
3724            app.killed = false;
3725            app.killedByAm = false;
3726            checkTime(startTime, "startProcess: starting to update pids map");
3727            synchronized (mPidsSelfLocked) {
3728                this.mPidsSelfLocked.put(startResult.pid, app);
3729                if (isActivityProcess) {
3730                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3731                    msg.obj = app;
3732                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3733                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3734                }
3735            }
3736            checkTime(startTime, "startProcess: done updating pids map");
3737        } catch (RuntimeException e) {
3738            Slog.e(TAG, "Failure starting process " + app.processName, e);
3739
3740            // Something went very wrong while trying to start this process; one
3741            // common case is when the package is frozen due to an active
3742            // upgrade. To recover, clean up any active bookkeeping related to
3743            // starting this process. (We already invoked this method once when
3744            // the package was initially frozen through KILL_APPLICATION_MSG, so
3745            // it doesn't hurt to use it again.)
3746            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3747                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3748        }
3749    }
3750
3751    void updateUsageStats(ActivityRecord component, boolean resumed) {
3752        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3753                "updateUsageStats: comp=" + component + "res=" + resumed);
3754        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3755        if (resumed) {
3756            if (mUsageStatsService != null) {
3757                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3758                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3759            }
3760            synchronized (stats) {
3761                stats.noteActivityResumedLocked(component.app.uid);
3762            }
3763        } else {
3764            if (mUsageStatsService != null) {
3765                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3766                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3767            }
3768            synchronized (stats) {
3769                stats.noteActivityPausedLocked(component.app.uid);
3770            }
3771        }
3772    }
3773
3774    Intent getHomeIntent() {
3775        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3776        intent.setComponent(mTopComponent);
3777        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3778        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3779            intent.addCategory(Intent.CATEGORY_HOME);
3780        }
3781        return intent;
3782    }
3783
3784    boolean startHomeActivityLocked(int userId, String reason) {
3785        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3786                && mTopAction == null) {
3787            // We are running in factory test mode, but unable to find
3788            // the factory test app, so just sit around displaying the
3789            // error message and don't try to start anything.
3790            return false;
3791        }
3792        Intent intent = getHomeIntent();
3793        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3794        if (aInfo != null) {
3795            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3796            // Don't do this if the home app is currently being
3797            // instrumented.
3798            aInfo = new ActivityInfo(aInfo);
3799            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3800            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3801                    aInfo.applicationInfo.uid, true);
3802            if (app == null || app.instrumentationClass == null) {
3803                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3804                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3805            }
3806        } else {
3807            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3808        }
3809
3810        return true;
3811    }
3812
3813    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3814        ActivityInfo ai = null;
3815        ComponentName comp = intent.getComponent();
3816        try {
3817            if (comp != null) {
3818                // Factory test.
3819                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3820            } else {
3821                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3822                        intent,
3823                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3824                        flags, userId);
3825
3826                if (info != null) {
3827                    ai = info.activityInfo;
3828                }
3829            }
3830        } catch (RemoteException e) {
3831            // ignore
3832        }
3833
3834        return ai;
3835    }
3836
3837    /**
3838     * Starts the "new version setup screen" if appropriate.
3839     */
3840    void startSetupActivityLocked() {
3841        // Only do this once per boot.
3842        if (mCheckedForSetup) {
3843            return;
3844        }
3845
3846        // We will show this screen if the current one is a different
3847        // version than the last one shown, and we are not running in
3848        // low-level factory test mode.
3849        final ContentResolver resolver = mContext.getContentResolver();
3850        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3851                Settings.Global.getInt(resolver,
3852                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3853            mCheckedForSetup = true;
3854
3855            // See if we should be showing the platform update setup UI.
3856            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3857            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3858                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3859            if (!ris.isEmpty()) {
3860                final ResolveInfo ri = ris.get(0);
3861                String vers = ri.activityInfo.metaData != null
3862                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3863                        : null;
3864                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3865                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3866                            Intent.METADATA_SETUP_VERSION);
3867                }
3868                String lastVers = Settings.Secure.getString(
3869                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3870                if (vers != null && !vers.equals(lastVers)) {
3871                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3872                    intent.setComponent(new ComponentName(
3873                            ri.activityInfo.packageName, ri.activityInfo.name));
3874                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3875                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3876                            null, 0, 0, 0, null, false, false, null, null, null);
3877                }
3878            }
3879        }
3880    }
3881
3882    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3883        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3884    }
3885
3886    void enforceNotIsolatedCaller(String caller) {
3887        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3888            throw new SecurityException("Isolated process not allowed to call " + caller);
3889        }
3890    }
3891
3892    void enforceShellRestriction(String restriction, int userHandle) {
3893        if (Binder.getCallingUid() == Process.SHELL_UID) {
3894            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3895                throw new SecurityException("Shell does not have permission to access user "
3896                        + userHandle);
3897            }
3898        }
3899    }
3900
3901    @Override
3902    public int getFrontActivityScreenCompatMode() {
3903        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3904        synchronized (this) {
3905            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3906        }
3907    }
3908
3909    @Override
3910    public void setFrontActivityScreenCompatMode(int mode) {
3911        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3912                "setFrontActivityScreenCompatMode");
3913        synchronized (this) {
3914            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3915        }
3916    }
3917
3918    @Override
3919    public int getPackageScreenCompatMode(String packageName) {
3920        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3921        synchronized (this) {
3922            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3923        }
3924    }
3925
3926    @Override
3927    public void setPackageScreenCompatMode(String packageName, int mode) {
3928        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3929                "setPackageScreenCompatMode");
3930        synchronized (this) {
3931            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3932        }
3933    }
3934
3935    @Override
3936    public boolean getPackageAskScreenCompat(String packageName) {
3937        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3938        synchronized (this) {
3939            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3940        }
3941    }
3942
3943    @Override
3944    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3945        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3946                "setPackageAskScreenCompat");
3947        synchronized (this) {
3948            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3949        }
3950    }
3951
3952    private boolean hasUsageStatsPermission(String callingPackage) {
3953        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3954                Binder.getCallingUid(), callingPackage);
3955        if (mode == AppOpsManager.MODE_DEFAULT) {
3956            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3957                    == PackageManager.PERMISSION_GRANTED;
3958        }
3959        return mode == AppOpsManager.MODE_ALLOWED;
3960    }
3961
3962    @Override
3963    public int getPackageProcessState(String packageName, String callingPackage) {
3964        if (!hasUsageStatsPermission(callingPackage)) {
3965            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3966                    "getPackageProcessState");
3967        }
3968
3969        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3970        synchronized (this) {
3971            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3972                final ProcessRecord proc = mLruProcesses.get(i);
3973                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3974                        || procState > proc.setProcState) {
3975                    boolean found = false;
3976                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3977                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3978                            procState = proc.setProcState;
3979                            found = true;
3980                        }
3981                    }
3982                    if (proc.pkgDeps != null && !found) {
3983                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3984                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3985                                procState = proc.setProcState;
3986                                break;
3987                            }
3988                        }
3989                    }
3990                }
3991            }
3992        }
3993        return procState;
3994    }
3995
3996    @Override
3997    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3998        synchronized (this) {
3999            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4000            if (app == null) {
4001                return false;
4002            }
4003            if (app.trimMemoryLevel < level && app.thread != null &&
4004                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4005                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4006                try {
4007                    app.thread.scheduleTrimMemory(level);
4008                    app.trimMemoryLevel = level;
4009                    return true;
4010                } catch (RemoteException e) {
4011                    // Fallthrough to failure case.
4012                }
4013            }
4014        }
4015        return false;
4016    }
4017
4018    private void dispatchProcessesChanged() {
4019        int N;
4020        synchronized (this) {
4021            N = mPendingProcessChanges.size();
4022            if (mActiveProcessChanges.length < N) {
4023                mActiveProcessChanges = new ProcessChangeItem[N];
4024            }
4025            mPendingProcessChanges.toArray(mActiveProcessChanges);
4026            mPendingProcessChanges.clear();
4027            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4028                    "*** Delivering " + N + " process changes");
4029        }
4030
4031        int i = mProcessObservers.beginBroadcast();
4032        while (i > 0) {
4033            i--;
4034            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4035            if (observer != null) {
4036                try {
4037                    for (int j=0; j<N; j++) {
4038                        ProcessChangeItem item = mActiveProcessChanges[j];
4039                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4040                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4041                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4042                                    + item.uid + ": " + item.foregroundActivities);
4043                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4044                                    item.foregroundActivities);
4045                        }
4046                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4047                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4048                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4049                                    + ": " + item.processState);
4050                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4051                        }
4052                    }
4053                } catch (RemoteException e) {
4054                }
4055            }
4056        }
4057        mProcessObservers.finishBroadcast();
4058
4059        synchronized (this) {
4060            for (int j=0; j<N; j++) {
4061                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4062            }
4063        }
4064    }
4065
4066    private void dispatchProcessDied(int pid, int uid) {
4067        int i = mProcessObservers.beginBroadcast();
4068        while (i > 0) {
4069            i--;
4070            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4071            if (observer != null) {
4072                try {
4073                    observer.onProcessDied(pid, uid);
4074                } catch (RemoteException e) {
4075                }
4076            }
4077        }
4078        mProcessObservers.finishBroadcast();
4079    }
4080
4081    private void dispatchUidsChanged() {
4082        int N;
4083        synchronized (this) {
4084            N = mPendingUidChanges.size();
4085            if (mActiveUidChanges.length < N) {
4086                mActiveUidChanges = new UidRecord.ChangeItem[N];
4087            }
4088            for (int i=0; i<N; i++) {
4089                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4090                mActiveUidChanges[i] = change;
4091                if (change.uidRecord != null) {
4092                    change.uidRecord.pendingChange = null;
4093                    change.uidRecord = null;
4094                }
4095            }
4096            mPendingUidChanges.clear();
4097            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4098                    "*** Delivering " + N + " uid changes");
4099        }
4100
4101        if (mLocalPowerManager != null) {
4102            for (int j=0; j<N; j++) {
4103                UidRecord.ChangeItem item = mActiveUidChanges[j];
4104                if (item.change == UidRecord.CHANGE_GONE
4105                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4106                    mLocalPowerManager.uidGone(item.uid);
4107                } else {
4108                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4109                }
4110            }
4111        }
4112
4113        int i = mUidObservers.beginBroadcast();
4114        while (i > 0) {
4115            i--;
4116            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4117            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4118            if (observer != null) {
4119                try {
4120                    for (int j=0; j<N; j++) {
4121                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4122                        final int change = item.change;
4123                        UidRecord validateUid = null;
4124                        if (VALIDATE_UID_STATES && i == 0) {
4125                            validateUid = mValidateUids.get(item.uid);
4126                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4127                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4128                                validateUid = new UidRecord(item.uid);
4129                                mValidateUids.put(item.uid, validateUid);
4130                            }
4131                        }
4132                        if (change == UidRecord.CHANGE_IDLE
4133                                || change == UidRecord.CHANGE_GONE_IDLE) {
4134                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4135                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4136                                        "UID idle uid=" + item.uid);
4137                                observer.onUidIdle(item.uid);
4138                            }
4139                            if (VALIDATE_UID_STATES && i == 0) {
4140                                if (validateUid != null) {
4141                                    validateUid.idle = true;
4142                                }
4143                            }
4144                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4145                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4146                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4147                                        "UID active uid=" + item.uid);
4148                                observer.onUidActive(item.uid);
4149                            }
4150                            if (VALIDATE_UID_STATES && i == 0) {
4151                                validateUid.idle = false;
4152                            }
4153                        }
4154                        if (change == UidRecord.CHANGE_GONE
4155                                || change == UidRecord.CHANGE_GONE_IDLE) {
4156                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4157                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4158                                        "UID gone uid=" + item.uid);
4159                                observer.onUidGone(item.uid);
4160                            }
4161                            if (VALIDATE_UID_STATES && i == 0) {
4162                                if (validateUid != null) {
4163                                    mValidateUids.remove(item.uid);
4164                                }
4165                            }
4166                        } else {
4167                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4168                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4169                                        "UID CHANGED uid=" + item.uid
4170                                                + ": " + item.processState);
4171                                observer.onUidStateChanged(item.uid, item.processState);
4172                            }
4173                            if (VALIDATE_UID_STATES && i == 0) {
4174                                validateUid.curProcState = validateUid.setProcState
4175                                        = item.processState;
4176                            }
4177                        }
4178                    }
4179                } catch (RemoteException e) {
4180                }
4181            }
4182        }
4183        mUidObservers.finishBroadcast();
4184
4185        synchronized (this) {
4186            for (int j=0; j<N; j++) {
4187                mAvailUidChanges.add(mActiveUidChanges[j]);
4188            }
4189        }
4190    }
4191
4192    @Override
4193    public final int startActivity(IApplicationThread caller, String callingPackage,
4194            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4195            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4196        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4197                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4198                UserHandle.getCallingUserId());
4199    }
4200
4201    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4202        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4203        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4204                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4205                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4206
4207        // TODO: Switch to user app stacks here.
4208        String mimeType = intent.getType();
4209        final Uri data = intent.getData();
4210        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4211            mimeType = getProviderMimeType(data, userId);
4212        }
4213        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4214
4215        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4216        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4217                null, 0, 0, null, null, null, null, false, userId, container, null);
4218    }
4219
4220    @Override
4221    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4222            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4223            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4224        enforceNotIsolatedCaller("startActivity");
4225        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4226                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4227        // TODO: Switch to user app stacks here.
4228        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4229                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4230                profilerInfo, null, null, bOptions, false, userId, null, null);
4231    }
4232
4233    @Override
4234    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4235            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4236            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4237            int userId) {
4238
4239        // This is very dangerous -- it allows you to perform a start activity (including
4240        // permission grants) as any app that may launch one of your own activities.  So
4241        // we will only allow this to be done from activities that are part of the core framework,
4242        // and then only when they are running as the system.
4243        final ActivityRecord sourceRecord;
4244        final int targetUid;
4245        final String targetPackage;
4246        synchronized (this) {
4247            if (resultTo == null) {
4248                throw new SecurityException("Must be called from an activity");
4249            }
4250            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4251            if (sourceRecord == null) {
4252                throw new SecurityException("Called with bad activity token: " + resultTo);
4253            }
4254            if (!sourceRecord.info.packageName.equals("android")) {
4255                throw new SecurityException(
4256                        "Must be called from an activity that is declared in the android package");
4257            }
4258            if (sourceRecord.app == null) {
4259                throw new SecurityException("Called without a process attached to activity");
4260            }
4261            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4262                // This is still okay, as long as this activity is running under the
4263                // uid of the original calling activity.
4264                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4265                    throw new SecurityException(
4266                            "Calling activity in uid " + sourceRecord.app.uid
4267                                    + " must be system uid or original calling uid "
4268                                    + sourceRecord.launchedFromUid);
4269                }
4270            }
4271            if (ignoreTargetSecurity) {
4272                if (intent.getComponent() == null) {
4273                    throw new SecurityException(
4274                            "Component must be specified with ignoreTargetSecurity");
4275                }
4276                if (intent.getSelector() != null) {
4277                    throw new SecurityException(
4278                            "Selector not allowed with ignoreTargetSecurity");
4279                }
4280            }
4281            targetUid = sourceRecord.launchedFromUid;
4282            targetPackage = sourceRecord.launchedFromPackage;
4283        }
4284
4285        if (userId == UserHandle.USER_NULL) {
4286            userId = UserHandle.getUserId(sourceRecord.app.uid);
4287        }
4288
4289        // TODO: Switch to user app stacks here.
4290        try {
4291            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4292                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4293                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4294            return ret;
4295        } catch (SecurityException e) {
4296            // XXX need to figure out how to propagate to original app.
4297            // A SecurityException here is generally actually a fault of the original
4298            // calling activity (such as a fairly granting permissions), so propagate it
4299            // back to them.
4300            /*
4301            StringBuilder msg = new StringBuilder();
4302            msg.append("While launching");
4303            msg.append(intent.toString());
4304            msg.append(": ");
4305            msg.append(e.getMessage());
4306            */
4307            throw e;
4308        }
4309    }
4310
4311    @Override
4312    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4313            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4314            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4315        enforceNotIsolatedCaller("startActivityAndWait");
4316        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4317                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4318        WaitResult res = new WaitResult();
4319        // TODO: Switch to user app stacks here.
4320        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4321                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4322                bOptions, false, userId, null, null);
4323        return res;
4324    }
4325
4326    @Override
4327    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4328            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4329            int startFlags, Configuration config, Bundle bOptions, int userId) {
4330        enforceNotIsolatedCaller("startActivityWithConfig");
4331        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4332                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4333        // TODO: Switch to user app stacks here.
4334        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4335                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4336                null, null, config, bOptions, false, userId, null, null);
4337        return ret;
4338    }
4339
4340    @Override
4341    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4342            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4343            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4344            throws TransactionTooLargeException {
4345        enforceNotIsolatedCaller("startActivityIntentSender");
4346        // Refuse possible leaked file descriptors
4347        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4348            throw new IllegalArgumentException("File descriptors passed in Intent");
4349        }
4350
4351        IIntentSender sender = intent.getTarget();
4352        if (!(sender instanceof PendingIntentRecord)) {
4353            throw new IllegalArgumentException("Bad PendingIntent object");
4354        }
4355
4356        PendingIntentRecord pir = (PendingIntentRecord)sender;
4357
4358        synchronized (this) {
4359            // If this is coming from the currently resumed activity, it is
4360            // effectively saying that app switches are allowed at this point.
4361            final ActivityStack stack = getFocusedStack();
4362            if (stack.mResumedActivity != null &&
4363                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4364                mAppSwitchesAllowedTime = 0;
4365            }
4366        }
4367        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4368                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4369        return ret;
4370    }
4371
4372    @Override
4373    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4374            Intent intent, String resolvedType, IVoiceInteractionSession session,
4375            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4376            Bundle bOptions, int userId) {
4377        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4378                != PackageManager.PERMISSION_GRANTED) {
4379            String msg = "Permission Denial: startVoiceActivity() from pid="
4380                    + Binder.getCallingPid()
4381                    + ", uid=" + Binder.getCallingUid()
4382                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4383            Slog.w(TAG, msg);
4384            throw new SecurityException(msg);
4385        }
4386        if (session == null || interactor == null) {
4387            throw new NullPointerException("null session or interactor");
4388        }
4389        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4390                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4391        // TODO: Switch to user app stacks here.
4392        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4393                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4394                null, bOptions, false, userId, null, null);
4395    }
4396
4397    @Override
4398    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4399            throws RemoteException {
4400        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4401        synchronized (this) {
4402            ActivityRecord activity = getFocusedStack().topActivity();
4403            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4404                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4405            }
4406            if (mRunningVoice != null || activity.task.voiceSession != null
4407                    || activity.voiceSession != null) {
4408                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4409                return;
4410            }
4411            if (activity.pendingVoiceInteractionStart) {
4412                Slog.w(TAG, "Pending start of voice interaction already.");
4413                return;
4414            }
4415            activity.pendingVoiceInteractionStart = true;
4416        }
4417        LocalServices.getService(VoiceInteractionManagerInternal.class)
4418                .startLocalVoiceInteraction(callingActivity, options);
4419    }
4420
4421    @Override
4422    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4423        LocalServices.getService(VoiceInteractionManagerInternal.class)
4424                .stopLocalVoiceInteraction(callingActivity);
4425    }
4426
4427    @Override
4428    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4429        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4430                .supportsLocalVoiceInteraction();
4431    }
4432
4433    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4434            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4435        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4436        if (activityToCallback == null) return;
4437        activityToCallback.setVoiceSessionLocked(voiceSession);
4438
4439        // Inform the activity
4440        try {
4441            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4442                    voiceInteractor);
4443            long token = Binder.clearCallingIdentity();
4444            try {
4445                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4446            } finally {
4447                Binder.restoreCallingIdentity(token);
4448            }
4449            // TODO: VI Should we cache the activity so that it's easier to find later
4450            // rather than scan through all the stacks and activities?
4451        } catch (RemoteException re) {
4452            activityToCallback.clearVoiceSessionLocked();
4453            // TODO: VI Should this terminate the voice session?
4454        }
4455    }
4456
4457    @Override
4458    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4459        synchronized (this) {
4460            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4461                if (keepAwake) {
4462                    mVoiceWakeLock.acquire();
4463                } else {
4464                    mVoiceWakeLock.release();
4465                }
4466            }
4467        }
4468    }
4469
4470    @Override
4471    public boolean startNextMatchingActivity(IBinder callingActivity,
4472            Intent intent, Bundle bOptions) {
4473        // Refuse possible leaked file descriptors
4474        if (intent != null && intent.hasFileDescriptors() == true) {
4475            throw new IllegalArgumentException("File descriptors passed in Intent");
4476        }
4477        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4478
4479        synchronized (this) {
4480            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4481            if (r == null) {
4482                ActivityOptions.abort(options);
4483                return false;
4484            }
4485            if (r.app == null || r.app.thread == null) {
4486                // The caller is not running...  d'oh!
4487                ActivityOptions.abort(options);
4488                return false;
4489            }
4490            intent = new Intent(intent);
4491            // The caller is not allowed to change the data.
4492            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4493            // And we are resetting to find the next component...
4494            intent.setComponent(null);
4495
4496            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4497
4498            ActivityInfo aInfo = null;
4499            try {
4500                List<ResolveInfo> resolves =
4501                    AppGlobals.getPackageManager().queryIntentActivities(
4502                            intent, r.resolvedType,
4503                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4504                            UserHandle.getCallingUserId()).getList();
4505
4506                // Look for the original activity in the list...
4507                final int N = resolves != null ? resolves.size() : 0;
4508                for (int i=0; i<N; i++) {
4509                    ResolveInfo rInfo = resolves.get(i);
4510                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4511                            && rInfo.activityInfo.name.equals(r.info.name)) {
4512                        // We found the current one...  the next matching is
4513                        // after it.
4514                        i++;
4515                        if (i<N) {
4516                            aInfo = resolves.get(i).activityInfo;
4517                        }
4518                        if (debug) {
4519                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4520                                    + "/" + r.info.name);
4521                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4522                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4523                        }
4524                        break;
4525                    }
4526                }
4527            } catch (RemoteException e) {
4528            }
4529
4530            if (aInfo == null) {
4531                // Nobody who is next!
4532                ActivityOptions.abort(options);
4533                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4534                return false;
4535            }
4536
4537            intent.setComponent(new ComponentName(
4538                    aInfo.applicationInfo.packageName, aInfo.name));
4539            intent.setFlags(intent.getFlags()&~(
4540                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4541                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4542                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4543                    Intent.FLAG_ACTIVITY_NEW_TASK));
4544
4545            // Okay now we need to start the new activity, replacing the
4546            // currently running activity.  This is a little tricky because
4547            // we want to start the new one as if the current one is finished,
4548            // but not finish the current one first so that there is no flicker.
4549            // And thus...
4550            final boolean wasFinishing = r.finishing;
4551            r.finishing = true;
4552
4553            // Propagate reply information over to the new activity.
4554            final ActivityRecord resultTo = r.resultTo;
4555            final String resultWho = r.resultWho;
4556            final int requestCode = r.requestCode;
4557            r.resultTo = null;
4558            if (resultTo != null) {
4559                resultTo.removeResultsLocked(r, resultWho, requestCode);
4560            }
4561
4562            final long origId = Binder.clearCallingIdentity();
4563            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4564                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4565                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4566                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4567                    false, false, null, null, null);
4568            Binder.restoreCallingIdentity(origId);
4569
4570            r.finishing = wasFinishing;
4571            if (res != ActivityManager.START_SUCCESS) {
4572                return false;
4573            }
4574            return true;
4575        }
4576    }
4577
4578    @Override
4579    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4580        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4581            String msg = "Permission Denial: startActivityFromRecents called without " +
4582                    START_TASKS_FROM_RECENTS;
4583            Slog.w(TAG, msg);
4584            throw new SecurityException(msg);
4585        }
4586        final long origId = Binder.clearCallingIdentity();
4587        try {
4588            synchronized (this) {
4589                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4590            }
4591        } finally {
4592            Binder.restoreCallingIdentity(origId);
4593        }
4594    }
4595
4596    final int startActivityInPackage(int uid, String callingPackage,
4597            Intent intent, String resolvedType, IBinder resultTo,
4598            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4599            IActivityContainer container, TaskRecord inTask) {
4600
4601        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4602                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4603
4604        // TODO: Switch to user app stacks here.
4605        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4606                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4607                null, null, null, bOptions, false, userId, container, inTask);
4608        return ret;
4609    }
4610
4611    @Override
4612    public final int startActivities(IApplicationThread caller, String callingPackage,
4613            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4614            int userId) {
4615        enforceNotIsolatedCaller("startActivities");
4616        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4617                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4618        // TODO: Switch to user app stacks here.
4619        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4620                resolvedTypes, resultTo, bOptions, userId);
4621        return ret;
4622    }
4623
4624    final int startActivitiesInPackage(int uid, String callingPackage,
4625            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4626            Bundle bOptions, int userId) {
4627
4628        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4629                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4630        // TODO: Switch to user app stacks here.
4631        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4632                resultTo, bOptions, userId);
4633        return ret;
4634    }
4635
4636    @Override
4637    public void reportActivityFullyDrawn(IBinder token) {
4638        synchronized (this) {
4639            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4640            if (r == null) {
4641                return;
4642            }
4643            r.reportFullyDrawnLocked();
4644        }
4645    }
4646
4647    @Override
4648    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4649        synchronized (this) {
4650            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4651            if (r == null) {
4652                return;
4653            }
4654            TaskRecord task = r.task;
4655            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4656                // Fixed screen orientation isn't supported when activities aren't in full screen
4657                // mode.
4658                return;
4659            }
4660            final long origId = Binder.clearCallingIdentity();
4661            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4662            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4663                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4664            if (config != null) {
4665                r.frozenBeforeDestroy = true;
4666                if (!updateConfigurationLocked(config, r, false)) {
4667                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4668                }
4669            }
4670            Binder.restoreCallingIdentity(origId);
4671        }
4672    }
4673
4674    @Override
4675    public int getRequestedOrientation(IBinder token) {
4676        synchronized (this) {
4677            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4678            if (r == null) {
4679                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4680            }
4681            return mWindowManager.getAppOrientation(r.appToken);
4682        }
4683    }
4684
4685    /**
4686     * This is the internal entry point for handling Activity.finish().
4687     *
4688     * @param token The Binder token referencing the Activity we want to finish.
4689     * @param resultCode Result code, if any, from this Activity.
4690     * @param resultData Result data (Intent), if any, from this Activity.
4691     * @param finishTask Whether to finish the task associated with this Activity.
4692     *
4693     * @return Returns true if the activity successfully finished, or false if it is still running.
4694     */
4695    @Override
4696    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4697            int finishTask) {
4698        // Refuse possible leaked file descriptors
4699        if (resultData != null && resultData.hasFileDescriptors() == true) {
4700            throw new IllegalArgumentException("File descriptors passed in Intent");
4701        }
4702
4703        synchronized(this) {
4704            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4705            if (r == null) {
4706                return true;
4707            }
4708            // Keep track of the root activity of the task before we finish it
4709            TaskRecord tr = r.task;
4710            ActivityRecord rootR = tr.getRootActivity();
4711            if (rootR == null) {
4712                Slog.w(TAG, "Finishing task with all activities already finished");
4713            }
4714            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4715            // finish.
4716            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4717                    mStackSupervisor.isLastLockedTask(tr)) {
4718                Slog.i(TAG, "Not finishing task in lock task mode");
4719                mStackSupervisor.showLockTaskToast();
4720                return false;
4721            }
4722            if (mController != null) {
4723                // Find the first activity that is not finishing.
4724                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4725                if (next != null) {
4726                    // ask watcher if this is allowed
4727                    boolean resumeOK = true;
4728                    try {
4729                        resumeOK = mController.activityResuming(next.packageName);
4730                    } catch (RemoteException e) {
4731                        mController = null;
4732                        Watchdog.getInstance().setActivityController(null);
4733                    }
4734
4735                    if (!resumeOK) {
4736                        Slog.i(TAG, "Not finishing activity because controller resumed");
4737                        return false;
4738                    }
4739                }
4740            }
4741            final long origId = Binder.clearCallingIdentity();
4742            try {
4743                boolean res;
4744                final boolean finishWithRootActivity =
4745                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4746                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4747                        || (finishWithRootActivity && r == rootR)) {
4748                    // If requested, remove the task that is associated to this activity only if it
4749                    // was the root activity in the task. The result code and data is ignored
4750                    // because we don't support returning them across task boundaries. Also, to
4751                    // keep backwards compatibility we remove the task from recents when finishing
4752                    // task with root activity.
4753                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4754                    if (!res) {
4755                        Slog.i(TAG, "Removing task failed to finish activity");
4756                    }
4757                } else {
4758                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4759                            resultData, "app-request", true);
4760                    if (!res) {
4761                        Slog.i(TAG, "Failed to finish by app-request");
4762                    }
4763                }
4764                return res;
4765            } finally {
4766                Binder.restoreCallingIdentity(origId);
4767            }
4768        }
4769    }
4770
4771    @Override
4772    public final void finishHeavyWeightApp() {
4773        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4774                != PackageManager.PERMISSION_GRANTED) {
4775            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4776                    + Binder.getCallingPid()
4777                    + ", uid=" + Binder.getCallingUid()
4778                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4779            Slog.w(TAG, msg);
4780            throw new SecurityException(msg);
4781        }
4782
4783        synchronized(this) {
4784            if (mHeavyWeightProcess == null) {
4785                return;
4786            }
4787
4788            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4789            for (int i = 0; i < activities.size(); i++) {
4790                ActivityRecord r = activities.get(i);
4791                if (!r.finishing && r.isInStackLocked()) {
4792                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4793                            null, "finish-heavy", true);
4794                }
4795            }
4796
4797            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4798                    mHeavyWeightProcess.userId, 0));
4799            mHeavyWeightProcess = null;
4800        }
4801    }
4802
4803    @Override
4804    public void crashApplication(int uid, int initialPid, String packageName,
4805            String message) {
4806        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4807                != PackageManager.PERMISSION_GRANTED) {
4808            String msg = "Permission Denial: crashApplication() from pid="
4809                    + Binder.getCallingPid()
4810                    + ", uid=" + Binder.getCallingUid()
4811                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4812            Slog.w(TAG, msg);
4813            throw new SecurityException(msg);
4814        }
4815
4816        synchronized(this) {
4817            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4818        }
4819    }
4820
4821    @Override
4822    public final void finishSubActivity(IBinder token, String resultWho,
4823            int requestCode) {
4824        synchronized(this) {
4825            final long origId = Binder.clearCallingIdentity();
4826            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4827            if (r != null) {
4828                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4829            }
4830            Binder.restoreCallingIdentity(origId);
4831        }
4832    }
4833
4834    @Override
4835    public boolean finishActivityAffinity(IBinder token) {
4836        synchronized(this) {
4837            final long origId = Binder.clearCallingIdentity();
4838            try {
4839                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4840                if (r == null) {
4841                    return false;
4842                }
4843
4844                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4845                // can finish.
4846                final TaskRecord task = r.task;
4847                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4848                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4849                    mStackSupervisor.showLockTaskToast();
4850                    return false;
4851                }
4852                return task.stack.finishActivityAffinityLocked(r);
4853            } finally {
4854                Binder.restoreCallingIdentity(origId);
4855            }
4856        }
4857    }
4858
4859    @Override
4860    public void finishVoiceTask(IVoiceInteractionSession session) {
4861        synchronized (this) {
4862            final long origId = Binder.clearCallingIdentity();
4863            try {
4864                // TODO: VI Consider treating local voice interactions and voice tasks
4865                // differently here
4866                mStackSupervisor.finishVoiceTask(session);
4867            } finally {
4868                Binder.restoreCallingIdentity(origId);
4869            }
4870        }
4871
4872    }
4873
4874    @Override
4875    public boolean releaseActivityInstance(IBinder token) {
4876        synchronized(this) {
4877            final long origId = Binder.clearCallingIdentity();
4878            try {
4879                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4880                if (r == null) {
4881                    return false;
4882                }
4883                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4884            } finally {
4885                Binder.restoreCallingIdentity(origId);
4886            }
4887        }
4888    }
4889
4890    @Override
4891    public void releaseSomeActivities(IApplicationThread appInt) {
4892        synchronized(this) {
4893            final long origId = Binder.clearCallingIdentity();
4894            try {
4895                ProcessRecord app = getRecordForAppLocked(appInt);
4896                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4897            } finally {
4898                Binder.restoreCallingIdentity(origId);
4899            }
4900        }
4901    }
4902
4903    @Override
4904    public boolean willActivityBeVisible(IBinder token) {
4905        synchronized(this) {
4906            ActivityStack stack = ActivityRecord.getStackLocked(token);
4907            if (stack != null) {
4908                return stack.willActivityBeVisibleLocked(token);
4909            }
4910            return false;
4911        }
4912    }
4913
4914    @Override
4915    public void overridePendingTransition(IBinder token, String packageName,
4916            int enterAnim, int exitAnim) {
4917        synchronized(this) {
4918            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4919            if (self == null) {
4920                return;
4921            }
4922
4923            final long origId = Binder.clearCallingIdentity();
4924
4925            if (self.state == ActivityState.RESUMED
4926                    || self.state == ActivityState.PAUSING) {
4927                mWindowManager.overridePendingAppTransition(packageName,
4928                        enterAnim, exitAnim, null);
4929            }
4930
4931            Binder.restoreCallingIdentity(origId);
4932        }
4933    }
4934
4935    /**
4936     * Main function for removing an existing process from the activity manager
4937     * as a result of that process going away.  Clears out all connections
4938     * to the process.
4939     */
4940    private final void handleAppDiedLocked(ProcessRecord app,
4941            boolean restarting, boolean allowRestart) {
4942        int pid = app.pid;
4943        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4944        if (!kept && !restarting) {
4945            removeLruProcessLocked(app);
4946            if (pid > 0) {
4947                ProcessList.remove(pid);
4948            }
4949        }
4950
4951        if (mProfileProc == app) {
4952            clearProfilerLocked();
4953        }
4954
4955        // Remove this application's activities from active lists.
4956        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4957
4958        app.activities.clear();
4959
4960        if (app.instrumentationClass != null) {
4961            Slog.w(TAG, "Crash of app " + app.processName
4962                  + " running instrumentation " + app.instrumentationClass);
4963            Bundle info = new Bundle();
4964            info.putString("shortMsg", "Process crashed.");
4965            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4966        }
4967
4968        if (!restarting && hasVisibleActivities
4969                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4970            // If there was nothing to resume, and we are not already restarting this process, but
4971            // there is a visible activity that is hosted by the process...  then make sure all
4972            // visible activities are running, taking care of restarting this process.
4973            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4974        }
4975    }
4976
4977    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4978        IBinder threadBinder = thread.asBinder();
4979        // Find the application record.
4980        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4981            ProcessRecord rec = mLruProcesses.get(i);
4982            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4983                return i;
4984            }
4985        }
4986        return -1;
4987    }
4988
4989    final ProcessRecord getRecordForAppLocked(
4990            IApplicationThread thread) {
4991        if (thread == null) {
4992            return null;
4993        }
4994
4995        int appIndex = getLRURecordIndexForAppLocked(thread);
4996        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4997    }
4998
4999    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5000        // If there are no longer any background processes running,
5001        // and the app that died was not running instrumentation,
5002        // then tell everyone we are now low on memory.
5003        boolean haveBg = false;
5004        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5005            ProcessRecord rec = mLruProcesses.get(i);
5006            if (rec.thread != null
5007                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5008                haveBg = true;
5009                break;
5010            }
5011        }
5012
5013        if (!haveBg) {
5014            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5015            if (doReport) {
5016                long now = SystemClock.uptimeMillis();
5017                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5018                    doReport = false;
5019                } else {
5020                    mLastMemUsageReportTime = now;
5021                }
5022            }
5023            final ArrayList<ProcessMemInfo> memInfos
5024                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5025            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5026            long now = SystemClock.uptimeMillis();
5027            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5028                ProcessRecord rec = mLruProcesses.get(i);
5029                if (rec == dyingProc || rec.thread == null) {
5030                    continue;
5031                }
5032                if (doReport) {
5033                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5034                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5035                }
5036                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5037                    // The low memory report is overriding any current
5038                    // state for a GC request.  Make sure to do
5039                    // heavy/important/visible/foreground processes first.
5040                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5041                        rec.lastRequestedGc = 0;
5042                    } else {
5043                        rec.lastRequestedGc = rec.lastLowMemory;
5044                    }
5045                    rec.reportLowMemory = true;
5046                    rec.lastLowMemory = now;
5047                    mProcessesToGc.remove(rec);
5048                    addProcessToGcListLocked(rec);
5049                }
5050            }
5051            if (doReport) {
5052                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5053                mHandler.sendMessage(msg);
5054            }
5055            scheduleAppGcsLocked();
5056        }
5057    }
5058
5059    final void appDiedLocked(ProcessRecord app) {
5060       appDiedLocked(app, app.pid, app.thread, false);
5061    }
5062
5063    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5064            boolean fromBinderDied) {
5065        // First check if this ProcessRecord is actually active for the pid.
5066        synchronized (mPidsSelfLocked) {
5067            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5068            if (curProc != app) {
5069                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5070                return;
5071            }
5072        }
5073
5074        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5075        synchronized (stats) {
5076            stats.noteProcessDiedLocked(app.info.uid, pid);
5077        }
5078
5079        if (!app.killed) {
5080            if (!fromBinderDied) {
5081                Process.killProcessQuiet(pid);
5082            }
5083            killProcessGroup(app.uid, pid);
5084            app.killed = true;
5085        }
5086
5087        // Clean up already done if the process has been re-started.
5088        if (app.pid == pid && app.thread != null &&
5089                app.thread.asBinder() == thread.asBinder()) {
5090            boolean doLowMem = app.instrumentationClass == null;
5091            boolean doOomAdj = doLowMem;
5092            if (!app.killedByAm) {
5093                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5094                        + ") has died");
5095                mAllowLowerMemLevel = true;
5096            } else {
5097                // Note that we always want to do oom adj to update our state with the
5098                // new number of procs.
5099                mAllowLowerMemLevel = false;
5100                doLowMem = false;
5101            }
5102            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5103            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5104                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5105            handleAppDiedLocked(app, false, true);
5106
5107            if (doOomAdj) {
5108                updateOomAdjLocked();
5109            }
5110            if (doLowMem) {
5111                doLowMemReportIfNeededLocked(app);
5112            }
5113        } else if (app.pid != pid) {
5114            // A new process has already been started.
5115            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5116                    + ") has died and restarted (pid " + app.pid + ").");
5117            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5118        } else if (DEBUG_PROCESSES) {
5119            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5120                    + thread.asBinder());
5121        }
5122    }
5123
5124    /**
5125     * If a stack trace dump file is configured, dump process stack traces.
5126     * @param clearTraces causes the dump file to be erased prior to the new
5127     *    traces being written, if true; when false, the new traces will be
5128     *    appended to any existing file content.
5129     * @param firstPids of dalvik VM processes to dump stack traces for first
5130     * @param lastPids of dalvik VM processes to dump stack traces for last
5131     * @param nativeProcs optional list of native process names to dump stack crawls
5132     * @return file containing stack traces, or null if no dump file is configured
5133     */
5134    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5135            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5136        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5137        if (tracesPath == null || tracesPath.length() == 0) {
5138            return null;
5139        }
5140
5141        File tracesFile = new File(tracesPath);
5142        try {
5143            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5144            tracesFile.createNewFile();
5145            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5146        } catch (IOException e) {
5147            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5148            return null;
5149        }
5150
5151        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5152        return tracesFile;
5153    }
5154
5155    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5156            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5157        // Use a FileObserver to detect when traces finish writing.
5158        // The order of traces is considered important to maintain for legibility.
5159        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5160            @Override
5161            public synchronized void onEvent(int event, String path) { notify(); }
5162        };
5163
5164        try {
5165            observer.startWatching();
5166
5167            // First collect all of the stacks of the most important pids.
5168            if (firstPids != null) {
5169                try {
5170                    int num = firstPids.size();
5171                    for (int i = 0; i < num; i++) {
5172                        synchronized (observer) {
5173                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5174                                    + firstPids.get(i));
5175                            final long sime = SystemClock.elapsedRealtime();
5176                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5177                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5178                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5179                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5180                        }
5181                    }
5182                } catch (InterruptedException e) {
5183                    Slog.wtf(TAG, e);
5184                }
5185            }
5186
5187            // Next collect the stacks of the native pids
5188            if (nativeProcs != null) {
5189                int[] pids = Process.getPidsForCommands(nativeProcs);
5190                if (pids != null) {
5191                    for (int pid : pids) {
5192                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5193                        final long sime = SystemClock.elapsedRealtime();
5194                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5195                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5196                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5197                    }
5198                }
5199            }
5200
5201            // Lastly, measure CPU usage.
5202            if (processCpuTracker != null) {
5203                processCpuTracker.init();
5204                System.gc();
5205                processCpuTracker.update();
5206                try {
5207                    synchronized (processCpuTracker) {
5208                        processCpuTracker.wait(500); // measure over 1/2 second.
5209                    }
5210                } catch (InterruptedException e) {
5211                }
5212                processCpuTracker.update();
5213
5214                // We'll take the stack crawls of just the top apps using CPU.
5215                final int N = processCpuTracker.countWorkingStats();
5216                int numProcs = 0;
5217                for (int i=0; i<N && numProcs<5; i++) {
5218                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5219                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5220                        numProcs++;
5221                        try {
5222                            synchronized (observer) {
5223                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5224                                        + stats.pid);
5225                                final long stime = SystemClock.elapsedRealtime();
5226                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5227                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5228                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5229                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5230                            }
5231                        } catch (InterruptedException e) {
5232                            Slog.wtf(TAG, e);
5233                        }
5234                    } else if (DEBUG_ANR) {
5235                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5236                                + stats.pid);
5237                    }
5238                }
5239            }
5240        } finally {
5241            observer.stopWatching();
5242        }
5243    }
5244
5245    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5246        if (true || IS_USER_BUILD) {
5247            return;
5248        }
5249        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5250        if (tracesPath == null || tracesPath.length() == 0) {
5251            return;
5252        }
5253
5254        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5255        StrictMode.allowThreadDiskWrites();
5256        try {
5257            final File tracesFile = new File(tracesPath);
5258            final File tracesDir = tracesFile.getParentFile();
5259            final File tracesTmp = new File(tracesDir, "__tmp__");
5260            try {
5261                if (tracesFile.exists()) {
5262                    tracesTmp.delete();
5263                    tracesFile.renameTo(tracesTmp);
5264                }
5265                StringBuilder sb = new StringBuilder();
5266                Time tobj = new Time();
5267                tobj.set(System.currentTimeMillis());
5268                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5269                sb.append(": ");
5270                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5271                sb.append(" since ");
5272                sb.append(msg);
5273                FileOutputStream fos = new FileOutputStream(tracesFile);
5274                fos.write(sb.toString().getBytes());
5275                if (app == null) {
5276                    fos.write("\n*** No application process!".getBytes());
5277                }
5278                fos.close();
5279                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5280            } catch (IOException e) {
5281                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5282                return;
5283            }
5284
5285            if (app != null) {
5286                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5287                firstPids.add(app.pid);
5288                dumpStackTraces(tracesPath, firstPids, null, null, null);
5289            }
5290
5291            File lastTracesFile = null;
5292            File curTracesFile = null;
5293            for (int i=9; i>=0; i--) {
5294                String name = String.format(Locale.US, "slow%02d.txt", i);
5295                curTracesFile = new File(tracesDir, name);
5296                if (curTracesFile.exists()) {
5297                    if (lastTracesFile != null) {
5298                        curTracesFile.renameTo(lastTracesFile);
5299                    } else {
5300                        curTracesFile.delete();
5301                    }
5302                }
5303                lastTracesFile = curTracesFile;
5304            }
5305            tracesFile.renameTo(curTracesFile);
5306            if (tracesTmp.exists()) {
5307                tracesTmp.renameTo(tracesFile);
5308            }
5309        } finally {
5310            StrictMode.setThreadPolicy(oldPolicy);
5311        }
5312    }
5313
5314    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5315        if (!mLaunchWarningShown) {
5316            mLaunchWarningShown = true;
5317            mUiHandler.post(new Runnable() {
5318                @Override
5319                public void run() {
5320                    synchronized (ActivityManagerService.this) {
5321                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5322                        d.show();
5323                        mUiHandler.postDelayed(new Runnable() {
5324                            @Override
5325                            public void run() {
5326                                synchronized (ActivityManagerService.this) {
5327                                    d.dismiss();
5328                                    mLaunchWarningShown = false;
5329                                }
5330                            }
5331                        }, 4000);
5332                    }
5333                }
5334            });
5335        }
5336    }
5337
5338    @Override
5339    public boolean clearApplicationUserData(final String packageName,
5340            final IPackageDataObserver observer, int userId) {
5341        enforceNotIsolatedCaller("clearApplicationUserData");
5342        int uid = Binder.getCallingUid();
5343        int pid = Binder.getCallingPid();
5344        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5345                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5346
5347        final DevicePolicyManagerInternal dpmi = LocalServices
5348                .getService(DevicePolicyManagerInternal.class);
5349        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5350            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5351        }
5352
5353        long callingId = Binder.clearCallingIdentity();
5354        try {
5355            IPackageManager pm = AppGlobals.getPackageManager();
5356            int pkgUid = -1;
5357            synchronized(this) {
5358                try {
5359                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5360                } catch (RemoteException e) {
5361                }
5362                if (pkgUid == -1) {
5363                    Slog.w(TAG, "Invalid packageName: " + packageName);
5364                    if (observer != null) {
5365                        try {
5366                            observer.onRemoveCompleted(packageName, false);
5367                        } catch (RemoteException e) {
5368                            Slog.i(TAG, "Observer no longer exists.");
5369                        }
5370                    }
5371                    return false;
5372                }
5373                if (uid == pkgUid || checkComponentPermission(
5374                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5375                        pid, uid, -1, true)
5376                        == PackageManager.PERMISSION_GRANTED) {
5377                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5378                } else {
5379                    throw new SecurityException("PID " + pid + " does not have permission "
5380                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5381                                    + " of package " + packageName);
5382                }
5383
5384                // Remove all tasks match the cleared application package and user
5385                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5386                    final TaskRecord tr = mRecentTasks.get(i);
5387                    final String taskPackageName =
5388                            tr.getBaseIntent().getComponent().getPackageName();
5389                    if (tr.userId != userId) continue;
5390                    if (!taskPackageName.equals(packageName)) continue;
5391                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5392                }
5393            }
5394
5395            try {
5396                // Clear application user data
5397                pm.clearApplicationUserData(packageName, observer, userId);
5398
5399                synchronized(this) {
5400                    // Remove all permissions granted from/to this package
5401                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5402                }
5403
5404                // Remove all zen rules created by this package; revoke it's zen access.
5405                INotificationManager inm = NotificationManager.getService();
5406                inm.removeAutomaticZenRules(packageName);
5407                inm.setNotificationPolicyAccessGranted(packageName, false);
5408
5409                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5410                        Uri.fromParts("package", packageName, null));
5411                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5412                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5413                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5414                        null, null, 0, null, null, null, null, false, false, userId);
5415            } catch (RemoteException e) {
5416            }
5417        } finally {
5418            Binder.restoreCallingIdentity(callingId);
5419        }
5420        return true;
5421    }
5422
5423    @Override
5424    public void killBackgroundProcesses(final String packageName, int userId) {
5425        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5426                != PackageManager.PERMISSION_GRANTED &&
5427                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5428                        != PackageManager.PERMISSION_GRANTED) {
5429            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5430                    + Binder.getCallingPid()
5431                    + ", uid=" + Binder.getCallingUid()
5432                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5433            Slog.w(TAG, msg);
5434            throw new SecurityException(msg);
5435        }
5436
5437        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5438                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5439        long callingId = Binder.clearCallingIdentity();
5440        try {
5441            IPackageManager pm = AppGlobals.getPackageManager();
5442            synchronized(this) {
5443                int appId = -1;
5444                try {
5445                    appId = UserHandle.getAppId(
5446                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5447                } catch (RemoteException e) {
5448                }
5449                if (appId == -1) {
5450                    Slog.w(TAG, "Invalid packageName: " + packageName);
5451                    return;
5452                }
5453                killPackageProcessesLocked(packageName, appId, userId,
5454                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5455            }
5456        } finally {
5457            Binder.restoreCallingIdentity(callingId);
5458        }
5459    }
5460
5461    @Override
5462    public void killAllBackgroundProcesses() {
5463        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5464                != PackageManager.PERMISSION_GRANTED) {
5465            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5466                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5467                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5468            Slog.w(TAG, msg);
5469            throw new SecurityException(msg);
5470        }
5471
5472        final long callingId = Binder.clearCallingIdentity();
5473        try {
5474            synchronized (this) {
5475                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5476                final int NP = mProcessNames.getMap().size();
5477                for (int ip = 0; ip < NP; ip++) {
5478                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5479                    final int NA = apps.size();
5480                    for (int ia = 0; ia < NA; ia++) {
5481                        final ProcessRecord app = apps.valueAt(ia);
5482                        if (app.persistent) {
5483                            // We don't kill persistent processes.
5484                            continue;
5485                        }
5486                        if (app.removed) {
5487                            procs.add(app);
5488                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5489                            app.removed = true;
5490                            procs.add(app);
5491                        }
5492                    }
5493                }
5494
5495                final int N = procs.size();
5496                for (int i = 0; i < N; i++) {
5497                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5498                }
5499
5500                mAllowLowerMemLevel = true;
5501
5502                updateOomAdjLocked();
5503                doLowMemReportIfNeededLocked(null);
5504            }
5505        } finally {
5506            Binder.restoreCallingIdentity(callingId);
5507        }
5508    }
5509
5510    /**
5511     * Kills all background processes, except those matching any of the
5512     * specified properties.
5513     *
5514     * @param minTargetSdk the target SDK version at or above which to preserve
5515     *                     processes, or {@code -1} to ignore the target SDK
5516     * @param maxProcState the process state at or below which to preserve
5517     *                     processes, or {@code -1} to ignore the process state
5518     */
5519    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5520        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5521                != PackageManager.PERMISSION_GRANTED) {
5522            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5523                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5524                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5525            Slog.w(TAG, msg);
5526            throw new SecurityException(msg);
5527        }
5528
5529        final long callingId = Binder.clearCallingIdentity();
5530        try {
5531            synchronized (this) {
5532                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5533                final int NP = mProcessNames.getMap().size();
5534                for (int ip = 0; ip < NP; ip++) {
5535                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5536                    final int NA = apps.size();
5537                    for (int ia = 0; ia < NA; ia++) {
5538                        final ProcessRecord app = apps.valueAt(ia);
5539                        if (app.removed) {
5540                            procs.add(app);
5541                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5542                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5543                            app.removed = true;
5544                            procs.add(app);
5545                        }
5546                    }
5547                }
5548
5549                final int N = procs.size();
5550                for (int i = 0; i < N; i++) {
5551                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5552                }
5553            }
5554        } finally {
5555            Binder.restoreCallingIdentity(callingId);
5556        }
5557    }
5558
5559    @Override
5560    public void forceStopPackage(final String packageName, int userId) {
5561        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5562                != PackageManager.PERMISSION_GRANTED) {
5563            String msg = "Permission Denial: forceStopPackage() from pid="
5564                    + Binder.getCallingPid()
5565                    + ", uid=" + Binder.getCallingUid()
5566                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5567            Slog.w(TAG, msg);
5568            throw new SecurityException(msg);
5569        }
5570        final int callingPid = Binder.getCallingPid();
5571        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5572                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5573        long callingId = Binder.clearCallingIdentity();
5574        try {
5575            IPackageManager pm = AppGlobals.getPackageManager();
5576            synchronized(this) {
5577                int[] users = userId == UserHandle.USER_ALL
5578                        ? mUserController.getUsers() : new int[] { userId };
5579                for (int user : users) {
5580                    int pkgUid = -1;
5581                    try {
5582                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5583                                user);
5584                    } catch (RemoteException e) {
5585                    }
5586                    if (pkgUid == -1) {
5587                        Slog.w(TAG, "Invalid packageName: " + packageName);
5588                        continue;
5589                    }
5590                    try {
5591                        pm.setPackageStoppedState(packageName, true, user);
5592                    } catch (RemoteException e) {
5593                    } catch (IllegalArgumentException e) {
5594                        Slog.w(TAG, "Failed trying to unstop package "
5595                                + packageName + ": " + e);
5596                    }
5597                    if (mUserController.isUserRunningLocked(user, 0)) {
5598                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5599                    }
5600                }
5601            }
5602        } finally {
5603            Binder.restoreCallingIdentity(callingId);
5604        }
5605    }
5606
5607    @Override
5608    public void addPackageDependency(String packageName) {
5609        synchronized (this) {
5610            int callingPid = Binder.getCallingPid();
5611            if (callingPid == Process.myPid()) {
5612                //  Yeah, um, no.
5613                return;
5614            }
5615            ProcessRecord proc;
5616            synchronized (mPidsSelfLocked) {
5617                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5618            }
5619            if (proc != null) {
5620                if (proc.pkgDeps == null) {
5621                    proc.pkgDeps = new ArraySet<String>(1);
5622                }
5623                proc.pkgDeps.add(packageName);
5624            }
5625        }
5626    }
5627
5628    /*
5629     * The pkg name and app id have to be specified.
5630     */
5631    @Override
5632    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5633        if (pkg == null) {
5634            return;
5635        }
5636        // Make sure the uid is valid.
5637        if (appid < 0) {
5638            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5639            return;
5640        }
5641        int callerUid = Binder.getCallingUid();
5642        // Only the system server can kill an application
5643        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5644            // Post an aysnc message to kill the application
5645            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5646            msg.arg1 = appid;
5647            msg.arg2 = 0;
5648            Bundle bundle = new Bundle();
5649            bundle.putString("pkg", pkg);
5650            bundle.putString("reason", reason);
5651            msg.obj = bundle;
5652            mHandler.sendMessage(msg);
5653        } else {
5654            throw new SecurityException(callerUid + " cannot kill pkg: " +
5655                    pkg);
5656        }
5657    }
5658
5659    @Override
5660    public void closeSystemDialogs(String reason) {
5661        enforceNotIsolatedCaller("closeSystemDialogs");
5662
5663        final int pid = Binder.getCallingPid();
5664        final int uid = Binder.getCallingUid();
5665        final long origId = Binder.clearCallingIdentity();
5666        try {
5667            synchronized (this) {
5668                // Only allow this from foreground processes, so that background
5669                // applications can't abuse it to prevent system UI from being shown.
5670                if (uid >= Process.FIRST_APPLICATION_UID) {
5671                    ProcessRecord proc;
5672                    synchronized (mPidsSelfLocked) {
5673                        proc = mPidsSelfLocked.get(pid);
5674                    }
5675                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5676                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5677                                + " from background process " + proc);
5678                        return;
5679                    }
5680                }
5681                closeSystemDialogsLocked(reason);
5682            }
5683        } finally {
5684            Binder.restoreCallingIdentity(origId);
5685        }
5686    }
5687
5688    void closeSystemDialogsLocked(String reason) {
5689        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5690        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5691                | Intent.FLAG_RECEIVER_FOREGROUND);
5692        if (reason != null) {
5693            intent.putExtra("reason", reason);
5694        }
5695        mWindowManager.closeSystemDialogs(reason);
5696
5697        mStackSupervisor.closeSystemDialogsLocked();
5698
5699        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5700                AppOpsManager.OP_NONE, null, false, false,
5701                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5702    }
5703
5704    @Override
5705    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5706        enforceNotIsolatedCaller("getProcessMemoryInfo");
5707        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5708        for (int i=pids.length-1; i>=0; i--) {
5709            ProcessRecord proc;
5710            int oomAdj;
5711            synchronized (this) {
5712                synchronized (mPidsSelfLocked) {
5713                    proc = mPidsSelfLocked.get(pids[i]);
5714                    oomAdj = proc != null ? proc.setAdj : 0;
5715                }
5716            }
5717            infos[i] = new Debug.MemoryInfo();
5718            Debug.getMemoryInfo(pids[i], infos[i]);
5719            if (proc != null) {
5720                synchronized (this) {
5721                    if (proc.thread != null && proc.setAdj == oomAdj) {
5722                        // Record this for posterity if the process has been stable.
5723                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5724                                infos[i].getTotalUss(), false, proc.pkgList);
5725                    }
5726                }
5727            }
5728        }
5729        return infos;
5730    }
5731
5732    @Override
5733    public long[] getProcessPss(int[] pids) {
5734        enforceNotIsolatedCaller("getProcessPss");
5735        long[] pss = new long[pids.length];
5736        for (int i=pids.length-1; i>=0; i--) {
5737            ProcessRecord proc;
5738            int oomAdj;
5739            synchronized (this) {
5740                synchronized (mPidsSelfLocked) {
5741                    proc = mPidsSelfLocked.get(pids[i]);
5742                    oomAdj = proc != null ? proc.setAdj : 0;
5743                }
5744            }
5745            long[] tmpUss = new long[1];
5746            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5747            if (proc != null) {
5748                synchronized (this) {
5749                    if (proc.thread != null && proc.setAdj == oomAdj) {
5750                        // Record this for posterity if the process has been stable.
5751                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5752                    }
5753                }
5754            }
5755        }
5756        return pss;
5757    }
5758
5759    @Override
5760    public void killApplicationProcess(String processName, int uid) {
5761        if (processName == null) {
5762            return;
5763        }
5764
5765        int callerUid = Binder.getCallingUid();
5766        // Only the system server can kill an application
5767        if (callerUid == Process.SYSTEM_UID) {
5768            synchronized (this) {
5769                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5770                if (app != null && app.thread != null) {
5771                    try {
5772                        app.thread.scheduleSuicide();
5773                    } catch (RemoteException e) {
5774                        // If the other end already died, then our work here is done.
5775                    }
5776                } else {
5777                    Slog.w(TAG, "Process/uid not found attempting kill of "
5778                            + processName + " / " + uid);
5779                }
5780            }
5781        } else {
5782            throw new SecurityException(callerUid + " cannot kill app process: " +
5783                    processName);
5784        }
5785    }
5786
5787    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5788        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5789                false, true, false, false, UserHandle.getUserId(uid), reason);
5790        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5791                Uri.fromParts("package", packageName, null));
5792        if (!mProcessesReady) {
5793            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5794                    | Intent.FLAG_RECEIVER_FOREGROUND);
5795        }
5796        intent.putExtra(Intent.EXTRA_UID, uid);
5797        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5798        broadcastIntentLocked(null, null, intent,
5799                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5800                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5801    }
5802
5803
5804    private final boolean killPackageProcessesLocked(String packageName, int appId,
5805            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5806            boolean doit, boolean evenPersistent, String reason) {
5807        ArrayList<ProcessRecord> procs = new ArrayList<>();
5808
5809        // Remove all processes this package may have touched: all with the
5810        // same UID (except for the system or root user), and all whose name
5811        // matches the package name.
5812        final int NP = mProcessNames.getMap().size();
5813        for (int ip=0; ip<NP; ip++) {
5814            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5815            final int NA = apps.size();
5816            for (int ia=0; ia<NA; ia++) {
5817                ProcessRecord app = apps.valueAt(ia);
5818                if (app.persistent && !evenPersistent) {
5819                    // we don't kill persistent processes
5820                    continue;
5821                }
5822                if (app.removed) {
5823                    if (doit) {
5824                        procs.add(app);
5825                    }
5826                    continue;
5827                }
5828
5829                // Skip process if it doesn't meet our oom adj requirement.
5830                if (app.setAdj < minOomAdj) {
5831                    continue;
5832                }
5833
5834                // If no package is specified, we call all processes under the
5835                // give user id.
5836                if (packageName == null) {
5837                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5838                        continue;
5839                    }
5840                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5841                        continue;
5842                    }
5843                // Package has been specified, we want to hit all processes
5844                // that match it.  We need to qualify this by the processes
5845                // that are running under the specified app and user ID.
5846                } else {
5847                    final boolean isDep = app.pkgDeps != null
5848                            && app.pkgDeps.contains(packageName);
5849                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5850                        continue;
5851                    }
5852                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5853                        continue;
5854                    }
5855                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5856                        continue;
5857                    }
5858                }
5859
5860                // Process has passed all conditions, kill it!
5861                if (!doit) {
5862                    return true;
5863                }
5864                app.removed = true;
5865                procs.add(app);
5866            }
5867        }
5868
5869        int N = procs.size();
5870        for (int i=0; i<N; i++) {
5871            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5872        }
5873        updateOomAdjLocked();
5874        return N > 0;
5875    }
5876
5877    private void cleanupDisabledPackageComponentsLocked(
5878            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5879
5880        Set<String> disabledClasses = null;
5881        boolean packageDisabled = false;
5882        IPackageManager pm = AppGlobals.getPackageManager();
5883
5884        if (changedClasses == null) {
5885            // Nothing changed...
5886            return;
5887        }
5888
5889        // Determine enable/disable state of the package and its components.
5890        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5891        for (int i = changedClasses.length - 1; i >= 0; i--) {
5892            final String changedClass = changedClasses[i];
5893
5894            if (changedClass.equals(packageName)) {
5895                try {
5896                    // Entire package setting changed
5897                    enabled = pm.getApplicationEnabledSetting(packageName,
5898                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5899                } catch (Exception e) {
5900                    // No such package/component; probably racing with uninstall.  In any
5901                    // event it means we have nothing further to do here.
5902                    return;
5903                }
5904                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5905                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5906                if (packageDisabled) {
5907                    // Entire package is disabled.
5908                    // No need to continue to check component states.
5909                    disabledClasses = null;
5910                    break;
5911                }
5912            } else {
5913                try {
5914                    enabled = pm.getComponentEnabledSetting(
5915                            new ComponentName(packageName, changedClass),
5916                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5917                } catch (Exception e) {
5918                    // As above, probably racing with uninstall.
5919                    return;
5920                }
5921                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5922                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5923                    if (disabledClasses == null) {
5924                        disabledClasses = new ArraySet<>(changedClasses.length);
5925                    }
5926                    disabledClasses.add(changedClass);
5927                }
5928            }
5929        }
5930
5931        if (!packageDisabled && disabledClasses == null) {
5932            // Nothing to do here...
5933            return;
5934        }
5935
5936        // Clean-up disabled activities.
5937        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5938                packageName, disabledClasses, true, false, userId) && mBooted) {
5939            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5940            mStackSupervisor.scheduleIdleLocked();
5941        }
5942
5943        // Clean-up disabled tasks
5944        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5945
5946        // Clean-up disabled services.
5947        mServices.bringDownDisabledPackageServicesLocked(
5948                packageName, disabledClasses, userId, false, killProcess, true);
5949
5950        // Clean-up disabled providers.
5951        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5952        mProviderMap.collectPackageProvidersLocked(
5953                packageName, disabledClasses, true, false, userId, providers);
5954        for (int i = providers.size() - 1; i >= 0; i--) {
5955            removeDyingProviderLocked(null, providers.get(i), true);
5956        }
5957
5958        // Clean-up disabled broadcast receivers.
5959        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5960            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5961                    packageName, disabledClasses, userId, true);
5962        }
5963
5964    }
5965
5966    final boolean clearBroadcastQueueForUserLocked(int userId) {
5967        boolean didSomething = false;
5968        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5969            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5970                    null, null, userId, true);
5971        }
5972        return didSomething;
5973    }
5974
5975    final boolean forceStopPackageLocked(String packageName, int appId,
5976            boolean callerWillRestart, boolean purgeCache, boolean doit,
5977            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5978        int i;
5979
5980        if (userId == UserHandle.USER_ALL && packageName == null) {
5981            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5982        }
5983
5984        if (appId < 0 && packageName != null) {
5985            try {
5986                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5987                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5988            } catch (RemoteException e) {
5989            }
5990        }
5991
5992        if (doit) {
5993            if (packageName != null) {
5994                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5995                        + " user=" + userId + ": " + reason);
5996            } else {
5997                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5998            }
5999
6000            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6001        }
6002
6003        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6004                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6005                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6006
6007        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6008                packageName, null, doit, evenPersistent, userId)) {
6009            if (!doit) {
6010                return true;
6011            }
6012            didSomething = true;
6013        }
6014
6015        if (mServices.bringDownDisabledPackageServicesLocked(
6016                packageName, null, userId, evenPersistent, true, doit)) {
6017            if (!doit) {
6018                return true;
6019            }
6020            didSomething = true;
6021        }
6022
6023        if (packageName == null) {
6024            // Remove all sticky broadcasts from this user.
6025            mStickyBroadcasts.remove(userId);
6026        }
6027
6028        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6029        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6030                userId, providers)) {
6031            if (!doit) {
6032                return true;
6033            }
6034            didSomething = true;
6035        }
6036        for (i = providers.size() - 1; i >= 0; i--) {
6037            removeDyingProviderLocked(null, providers.get(i), true);
6038        }
6039
6040        // Remove transient permissions granted from/to this package/user
6041        removeUriPermissionsForPackageLocked(packageName, userId, false);
6042
6043        if (doit) {
6044            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6045                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6046                        packageName, null, userId, doit);
6047            }
6048        }
6049
6050        if (packageName == null || uninstalling) {
6051            // Remove pending intents.  For now we only do this when force
6052            // stopping users, because we have some problems when doing this
6053            // for packages -- app widgets are not currently cleaned up for
6054            // such packages, so they can be left with bad pending intents.
6055            if (mIntentSenderRecords.size() > 0) {
6056                Iterator<WeakReference<PendingIntentRecord>> it
6057                        = mIntentSenderRecords.values().iterator();
6058                while (it.hasNext()) {
6059                    WeakReference<PendingIntentRecord> wpir = it.next();
6060                    if (wpir == null) {
6061                        it.remove();
6062                        continue;
6063                    }
6064                    PendingIntentRecord pir = wpir.get();
6065                    if (pir == null) {
6066                        it.remove();
6067                        continue;
6068                    }
6069                    if (packageName == null) {
6070                        // Stopping user, remove all objects for the user.
6071                        if (pir.key.userId != userId) {
6072                            // Not the same user, skip it.
6073                            continue;
6074                        }
6075                    } else {
6076                        if (UserHandle.getAppId(pir.uid) != appId) {
6077                            // Different app id, skip it.
6078                            continue;
6079                        }
6080                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6081                            // Different user, skip it.
6082                            continue;
6083                        }
6084                        if (!pir.key.packageName.equals(packageName)) {
6085                            // Different package, skip it.
6086                            continue;
6087                        }
6088                    }
6089                    if (!doit) {
6090                        return true;
6091                    }
6092                    didSomething = true;
6093                    it.remove();
6094                    pir.canceled = true;
6095                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6096                        pir.key.activity.pendingResults.remove(pir.ref);
6097                    }
6098                }
6099            }
6100        }
6101
6102        if (doit) {
6103            if (purgeCache && packageName != null) {
6104                AttributeCache ac = AttributeCache.instance();
6105                if (ac != null) {
6106                    ac.removePackage(packageName);
6107                }
6108            }
6109            if (mBooted) {
6110                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6111                mStackSupervisor.scheduleIdleLocked();
6112            }
6113        }
6114
6115        return didSomething;
6116    }
6117
6118    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6119        ProcessRecord old = mProcessNames.remove(name, uid);
6120        if (old != null) {
6121            old.uidRecord.numProcs--;
6122            if (old.uidRecord.numProcs == 0) {
6123                // No more processes using this uid, tell clients it is gone.
6124                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6125                        "No more processes in " + old.uidRecord);
6126                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6127                mActiveUids.remove(uid);
6128                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6129            }
6130            old.uidRecord = null;
6131        }
6132        mIsolatedProcesses.remove(uid);
6133        return old;
6134    }
6135
6136    private final void addProcessNameLocked(ProcessRecord proc) {
6137        // We shouldn't already have a process under this name, but just in case we
6138        // need to clean up whatever may be there now.
6139        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6140        if (old == proc && proc.persistent) {
6141            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6142            Slog.w(TAG, "Re-adding persistent process " + proc);
6143        } else if (old != null) {
6144            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6145        }
6146        UidRecord uidRec = mActiveUids.get(proc.uid);
6147        if (uidRec == null) {
6148            uidRec = new UidRecord(proc.uid);
6149            // This is the first appearance of the uid, report it now!
6150            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6151                    "Creating new process uid: " + uidRec);
6152            mActiveUids.put(proc.uid, uidRec);
6153            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6154            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6155        }
6156        proc.uidRecord = uidRec;
6157        uidRec.numProcs++;
6158        mProcessNames.put(proc.processName, proc.uid, proc);
6159        if (proc.isolated) {
6160            mIsolatedProcesses.put(proc.uid, proc);
6161        }
6162    }
6163
6164    boolean removeProcessLocked(ProcessRecord app,
6165            boolean callerWillRestart, boolean allowRestart, String reason) {
6166        final String name = app.processName;
6167        final int uid = app.uid;
6168        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6169            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6170
6171        ProcessRecord old = mProcessNames.get(name, uid);
6172        if (old != app) {
6173            // This process is no longer active, so nothing to do.
6174            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6175            return false;
6176        }
6177        removeProcessNameLocked(name, uid);
6178        if (mHeavyWeightProcess == app) {
6179            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6180                    mHeavyWeightProcess.userId, 0));
6181            mHeavyWeightProcess = null;
6182        }
6183        boolean needRestart = false;
6184        if (app.pid > 0 && app.pid != MY_PID) {
6185            int pid = app.pid;
6186            synchronized (mPidsSelfLocked) {
6187                mPidsSelfLocked.remove(pid);
6188                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6189            }
6190            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6191            if (app.isolated) {
6192                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6193            }
6194            boolean willRestart = false;
6195            if (app.persistent && !app.isolated) {
6196                if (!callerWillRestart) {
6197                    willRestart = true;
6198                } else {
6199                    needRestart = true;
6200                }
6201            }
6202            app.kill(reason, true);
6203            handleAppDiedLocked(app, willRestart, allowRestart);
6204            if (willRestart) {
6205                removeLruProcessLocked(app);
6206                addAppLocked(app.info, false, null /* ABI override */);
6207            }
6208        } else {
6209            mRemovedProcesses.add(app);
6210        }
6211
6212        return needRestart;
6213    }
6214
6215    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6216        cleanupAppInLaunchingProvidersLocked(app, true);
6217        removeProcessLocked(app, false, true, "timeout publishing content providers");
6218    }
6219
6220    private final void processStartTimedOutLocked(ProcessRecord app) {
6221        final int pid = app.pid;
6222        boolean gone = false;
6223        synchronized (mPidsSelfLocked) {
6224            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6225            if (knownApp != null && knownApp.thread == null) {
6226                mPidsSelfLocked.remove(pid);
6227                gone = true;
6228            }
6229        }
6230
6231        if (gone) {
6232            Slog.w(TAG, "Process " + app + " failed to attach");
6233            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6234                    pid, app.uid, app.processName);
6235            removeProcessNameLocked(app.processName, app.uid);
6236            if (mHeavyWeightProcess == app) {
6237                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6238                        mHeavyWeightProcess.userId, 0));
6239                mHeavyWeightProcess = null;
6240            }
6241            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6242            if (app.isolated) {
6243                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6244            }
6245            // Take care of any launching providers waiting for this process.
6246            cleanupAppInLaunchingProvidersLocked(app, true);
6247            // Take care of any services that are waiting for the process.
6248            mServices.processStartTimedOutLocked(app);
6249            app.kill("start timeout", true);
6250            removeLruProcessLocked(app);
6251            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6252                Slog.w(TAG, "Unattached app died before backup, skipping");
6253                try {
6254                    IBackupManager bm = IBackupManager.Stub.asInterface(
6255                            ServiceManager.getService(Context.BACKUP_SERVICE));
6256                    bm.agentDisconnected(app.info.packageName);
6257                } catch (RemoteException e) {
6258                    // Can't happen; the backup manager is local
6259                }
6260            }
6261            if (isPendingBroadcastProcessLocked(pid)) {
6262                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6263                skipPendingBroadcastLocked(pid);
6264            }
6265        } else {
6266            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6267        }
6268    }
6269
6270    private final boolean attachApplicationLocked(IApplicationThread thread,
6271            int pid) {
6272
6273        // Find the application record that is being attached...  either via
6274        // the pid if we are running in multiple processes, or just pull the
6275        // next app record if we are emulating process with anonymous threads.
6276        ProcessRecord app;
6277        if (pid != MY_PID && pid >= 0) {
6278            synchronized (mPidsSelfLocked) {
6279                app = mPidsSelfLocked.get(pid);
6280            }
6281        } else {
6282            app = null;
6283        }
6284
6285        if (app == null) {
6286            Slog.w(TAG, "No pending application record for pid " + pid
6287                    + " (IApplicationThread " + thread + "); dropping process");
6288            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6289            if (pid > 0 && pid != MY_PID) {
6290                Process.killProcessQuiet(pid);
6291                //TODO: killProcessGroup(app.info.uid, pid);
6292            } else {
6293                try {
6294                    thread.scheduleExit();
6295                } catch (Exception e) {
6296                    // Ignore exceptions.
6297                }
6298            }
6299            return false;
6300        }
6301
6302        // If this application record is still attached to a previous
6303        // process, clean it up now.
6304        if (app.thread != null) {
6305            handleAppDiedLocked(app, true, true);
6306        }
6307
6308        // Tell the process all about itself.
6309
6310        if (DEBUG_ALL) Slog.v(
6311                TAG, "Binding process pid " + pid + " to record " + app);
6312
6313        final String processName = app.processName;
6314        try {
6315            AppDeathRecipient adr = new AppDeathRecipient(
6316                    app, pid, thread);
6317            thread.asBinder().linkToDeath(adr, 0);
6318            app.deathRecipient = adr;
6319        } catch (RemoteException e) {
6320            app.resetPackageList(mProcessStats);
6321            startProcessLocked(app, "link fail", processName);
6322            return false;
6323        }
6324
6325        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6326
6327        app.makeActive(thread, mProcessStats);
6328        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6329        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6330        app.forcingToForeground = null;
6331        updateProcessForegroundLocked(app, false, false);
6332        app.hasShownUi = false;
6333        app.debugging = false;
6334        app.cached = false;
6335        app.killedByAm = false;
6336
6337        // We carefully use the same state that PackageManager uses for
6338        // filtering, since we use this flag to decide if we need to install
6339        // providers when user is unlocked later
6340        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6341
6342        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6343
6344        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6345        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6346
6347        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6348            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6349            msg.obj = app;
6350            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6351        }
6352
6353        if (!normalMode) {
6354            Slog.i(TAG, "Launching preboot mode app: " + app);
6355        }
6356
6357        if (DEBUG_ALL) Slog.v(
6358            TAG, "New app record " + app
6359            + " thread=" + thread.asBinder() + " pid=" + pid);
6360        try {
6361            int testMode = IApplicationThread.DEBUG_OFF;
6362            if (mDebugApp != null && mDebugApp.equals(processName)) {
6363                testMode = mWaitForDebugger
6364                    ? IApplicationThread.DEBUG_WAIT
6365                    : IApplicationThread.DEBUG_ON;
6366                app.debugging = true;
6367                if (mDebugTransient) {
6368                    mDebugApp = mOrigDebugApp;
6369                    mWaitForDebugger = mOrigWaitForDebugger;
6370                }
6371            }
6372            String profileFile = app.instrumentationProfileFile;
6373            ParcelFileDescriptor profileFd = null;
6374            int samplingInterval = 0;
6375            boolean profileAutoStop = false;
6376            if (mProfileApp != null && mProfileApp.equals(processName)) {
6377                mProfileProc = app;
6378                profileFile = mProfileFile;
6379                profileFd = mProfileFd;
6380                samplingInterval = mSamplingInterval;
6381                profileAutoStop = mAutoStopProfiler;
6382            }
6383            boolean enableTrackAllocation = false;
6384            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6385                enableTrackAllocation = true;
6386                mTrackAllocationApp = null;
6387            }
6388
6389            // If the app is being launched for restore or full backup, set it up specially
6390            boolean isRestrictedBackupMode = false;
6391            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6392                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6393                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6394                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6395                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6396            }
6397
6398            if (app.instrumentationClass != null) {
6399                notifyPackageUse(app.instrumentationClass.getPackageName(),
6400                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6401            }
6402            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6403                    + processName + " with config " + mConfiguration);
6404            ApplicationInfo appInfo = app.instrumentationInfo != null
6405                    ? app.instrumentationInfo : app.info;
6406            app.compat = compatibilityInfoForPackageLocked(appInfo);
6407            if (profileFd != null) {
6408                profileFd = profileFd.dup();
6409            }
6410            ProfilerInfo profilerInfo = profileFile == null ? null
6411                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6412            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6413                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6414                    app.instrumentationUiAutomationConnection, testMode,
6415                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6416                    isRestrictedBackupMode || !normalMode, app.persistent,
6417                    new Configuration(mConfiguration), app.compat,
6418                    getCommonServicesLocked(app.isolated),
6419                    mCoreSettingsObserver.getCoreSettingsLocked());
6420            updateLruProcessLocked(app, false, null);
6421            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6422        } catch (Exception e) {
6423            // todo: Yikes!  What should we do?  For now we will try to
6424            // start another process, but that could easily get us in
6425            // an infinite loop of restarting processes...
6426            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6427
6428            app.resetPackageList(mProcessStats);
6429            app.unlinkDeathRecipient();
6430            startProcessLocked(app, "bind fail", processName);
6431            return false;
6432        }
6433
6434        // Remove this record from the list of starting applications.
6435        mPersistentStartingProcesses.remove(app);
6436        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6437                "Attach application locked removing on hold: " + app);
6438        mProcessesOnHold.remove(app);
6439
6440        boolean badApp = false;
6441        boolean didSomething = false;
6442
6443        // See if the top visible activity is waiting to run in this process...
6444        if (normalMode) {
6445            try {
6446                if (mStackSupervisor.attachApplicationLocked(app)) {
6447                    didSomething = true;
6448                }
6449            } catch (Exception e) {
6450                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6451                badApp = true;
6452            }
6453        }
6454
6455        // Find any services that should be running in this process...
6456        if (!badApp) {
6457            try {
6458                didSomething |= mServices.attachApplicationLocked(app, processName);
6459            } catch (Exception e) {
6460                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6461                badApp = true;
6462            }
6463        }
6464
6465        // Check if a next-broadcast receiver is in this process...
6466        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6467            try {
6468                didSomething |= sendPendingBroadcastsLocked(app);
6469            } catch (Exception e) {
6470                // If the app died trying to launch the receiver we declare it 'bad'
6471                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6472                badApp = true;
6473            }
6474        }
6475
6476        // Check whether the next backup agent is in this process...
6477        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6478            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6479                    "New app is backup target, launching agent for " + app);
6480            notifyPackageUse(mBackupTarget.appInfo.packageName,
6481                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6482            try {
6483                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6484                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6485                        mBackupTarget.backupMode);
6486            } catch (Exception e) {
6487                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6488                badApp = true;
6489            }
6490        }
6491
6492        if (badApp) {
6493            app.kill("error during init", true);
6494            handleAppDiedLocked(app, false, true);
6495            return false;
6496        }
6497
6498        if (!didSomething) {
6499            updateOomAdjLocked();
6500        }
6501
6502        return true;
6503    }
6504
6505    @Override
6506    public final void attachApplication(IApplicationThread thread) {
6507        synchronized (this) {
6508            int callingPid = Binder.getCallingPid();
6509            final long origId = Binder.clearCallingIdentity();
6510            attachApplicationLocked(thread, callingPid);
6511            Binder.restoreCallingIdentity(origId);
6512        }
6513    }
6514
6515    @Override
6516    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6517        final long origId = Binder.clearCallingIdentity();
6518        synchronized (this) {
6519            ActivityStack stack = ActivityRecord.getStackLocked(token);
6520            if (stack != null) {
6521                ActivityRecord r =
6522                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6523                if (stopProfiling) {
6524                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6525                        try {
6526                            mProfileFd.close();
6527                        } catch (IOException e) {
6528                        }
6529                        clearProfilerLocked();
6530                    }
6531                }
6532            }
6533        }
6534        Binder.restoreCallingIdentity(origId);
6535    }
6536
6537    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6538        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6539                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6540    }
6541
6542    void enableScreenAfterBoot() {
6543        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6544                SystemClock.uptimeMillis());
6545        mWindowManager.enableScreenAfterBoot();
6546
6547        synchronized (this) {
6548            updateEventDispatchingLocked();
6549        }
6550    }
6551
6552    @Override
6553    public void showBootMessage(final CharSequence msg, final boolean always) {
6554        if (Binder.getCallingUid() != Process.myUid()) {
6555            // These days only the core system can call this, so apps can't get in
6556            // the way of what we show about running them.
6557        }
6558        mWindowManager.showBootMessage(msg, always);
6559    }
6560
6561    @Override
6562    public void keyguardWaitingForActivityDrawn() {
6563        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6564        final long token = Binder.clearCallingIdentity();
6565        try {
6566            synchronized (this) {
6567                if (DEBUG_LOCKSCREEN) logLockScreen("");
6568                mWindowManager.keyguardWaitingForActivityDrawn();
6569                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6570                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6571                    updateSleepIfNeededLocked();
6572                }
6573            }
6574        } finally {
6575            Binder.restoreCallingIdentity(token);
6576        }
6577    }
6578
6579    @Override
6580    public void keyguardGoingAway(int flags) {
6581        enforceNotIsolatedCaller("keyguardGoingAway");
6582        final long token = Binder.clearCallingIdentity();
6583        try {
6584            synchronized (this) {
6585                if (DEBUG_LOCKSCREEN) logLockScreen("");
6586                mWindowManager.keyguardGoingAway(flags);
6587                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6588                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6589                    updateSleepIfNeededLocked();
6590
6591                    // Some stack visibility might change (e.g. docked stack)
6592                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6593                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6594                }
6595            }
6596        } finally {
6597            Binder.restoreCallingIdentity(token);
6598        }
6599    }
6600
6601    final void finishBooting() {
6602        synchronized (this) {
6603            if (!mBootAnimationComplete) {
6604                mCallFinishBooting = true;
6605                return;
6606            }
6607            mCallFinishBooting = false;
6608        }
6609
6610        ArraySet<String> completedIsas = new ArraySet<String>();
6611        for (String abi : Build.SUPPORTED_ABIS) {
6612            Process.establishZygoteConnectionForAbi(abi);
6613            final String instructionSet = VMRuntime.getInstructionSet(abi);
6614            if (!completedIsas.contains(instructionSet)) {
6615                try {
6616                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6617                } catch (InstallerException e) {
6618                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6619                            e.getMessage() +")");
6620                }
6621                completedIsas.add(instructionSet);
6622            }
6623        }
6624
6625        IntentFilter pkgFilter = new IntentFilter();
6626        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6627        pkgFilter.addDataScheme("package");
6628        mContext.registerReceiver(new BroadcastReceiver() {
6629            @Override
6630            public void onReceive(Context context, Intent intent) {
6631                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6632                if (pkgs != null) {
6633                    for (String pkg : pkgs) {
6634                        synchronized (ActivityManagerService.this) {
6635                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6636                                    0, "query restart")) {
6637                                setResultCode(Activity.RESULT_OK);
6638                                return;
6639                            }
6640                        }
6641                    }
6642                }
6643            }
6644        }, pkgFilter);
6645
6646        IntentFilter dumpheapFilter = new IntentFilter();
6647        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6648        mContext.registerReceiver(new BroadcastReceiver() {
6649            @Override
6650            public void onReceive(Context context, Intent intent) {
6651                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6652                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6653                } else {
6654                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6655                }
6656            }
6657        }, dumpheapFilter);
6658
6659        // Let system services know.
6660        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6661
6662        synchronized (this) {
6663            // Ensure that any processes we had put on hold are now started
6664            // up.
6665            final int NP = mProcessesOnHold.size();
6666            if (NP > 0) {
6667                ArrayList<ProcessRecord> procs =
6668                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6669                for (int ip=0; ip<NP; ip++) {
6670                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6671                            + procs.get(ip));
6672                    startProcessLocked(procs.get(ip), "on-hold", null);
6673                }
6674            }
6675
6676            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6677                // Start looking for apps that are abusing wake locks.
6678                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6679                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6680                // Tell anyone interested that we are done booting!
6681                SystemProperties.set("sys.boot_completed", "1");
6682
6683                // And trigger dev.bootcomplete if we are not showing encryption progress
6684                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6685                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6686                    SystemProperties.set("dev.bootcomplete", "1");
6687                }
6688                mUserController.sendBootCompletedLocked(
6689                        new IIntentReceiver.Stub() {
6690                            @Override
6691                            public void performReceive(Intent intent, int resultCode,
6692                                    String data, Bundle extras, boolean ordered,
6693                                    boolean sticky, int sendingUser) {
6694                                synchronized (ActivityManagerService.this) {
6695                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6696                                            true, false);
6697                                }
6698                            }
6699                        });
6700                scheduleStartProfilesLocked();
6701            }
6702        }
6703    }
6704
6705    @Override
6706    public void bootAnimationComplete() {
6707        final boolean callFinishBooting;
6708        synchronized (this) {
6709            callFinishBooting = mCallFinishBooting;
6710            mBootAnimationComplete = true;
6711        }
6712        if (callFinishBooting) {
6713            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6714            finishBooting();
6715            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6716        }
6717    }
6718
6719    final void ensureBootCompleted() {
6720        boolean booting;
6721        boolean enableScreen;
6722        synchronized (this) {
6723            booting = mBooting;
6724            mBooting = false;
6725            enableScreen = !mBooted;
6726            mBooted = true;
6727        }
6728
6729        if (booting) {
6730            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6731            finishBooting();
6732            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6733        }
6734
6735        if (enableScreen) {
6736            enableScreenAfterBoot();
6737        }
6738    }
6739
6740    @Override
6741    public final void activityResumed(IBinder token) {
6742        final long origId = Binder.clearCallingIdentity();
6743        synchronized(this) {
6744            ActivityStack stack = ActivityRecord.getStackLocked(token);
6745            if (stack != null) {
6746                stack.activityResumedLocked(token);
6747            }
6748        }
6749        Binder.restoreCallingIdentity(origId);
6750    }
6751
6752    @Override
6753    public final void activityPaused(IBinder token) {
6754        final long origId = Binder.clearCallingIdentity();
6755        synchronized(this) {
6756            ActivityStack stack = ActivityRecord.getStackLocked(token);
6757            if (stack != null) {
6758                stack.activityPausedLocked(token, false);
6759            }
6760        }
6761        Binder.restoreCallingIdentity(origId);
6762    }
6763
6764    @Override
6765    public final void activityStopped(IBinder token, Bundle icicle,
6766            PersistableBundle persistentState, CharSequence description) {
6767        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6768
6769        // Refuse possible leaked file descriptors
6770        if (icicle != null && icicle.hasFileDescriptors()) {
6771            throw new IllegalArgumentException("File descriptors passed in Bundle");
6772        }
6773
6774        final long origId = Binder.clearCallingIdentity();
6775
6776        synchronized (this) {
6777            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6778            if (r != null) {
6779                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6780            }
6781        }
6782
6783        trimApplications();
6784
6785        Binder.restoreCallingIdentity(origId);
6786    }
6787
6788    @Override
6789    public final void activityDestroyed(IBinder token) {
6790        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6791        synchronized (this) {
6792            ActivityStack stack = ActivityRecord.getStackLocked(token);
6793            if (stack != null) {
6794                stack.activityDestroyedLocked(token, "activityDestroyed");
6795            }
6796        }
6797    }
6798
6799    @Override
6800    public final void activityRelaunched(IBinder token) {
6801        final long origId = Binder.clearCallingIdentity();
6802        synchronized (this) {
6803            mStackSupervisor.activityRelaunchedLocked(token);
6804        }
6805        Binder.restoreCallingIdentity(origId);
6806    }
6807
6808    @Override
6809    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6810            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6811        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6812                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6813        synchronized (this) {
6814            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6815            if (record == null) {
6816                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6817                        + "found for: " + token);
6818            }
6819            record.setSizeConfigurations(horizontalSizeConfiguration,
6820                    verticalSizeConfigurations, smallestSizeConfigurations);
6821        }
6822    }
6823
6824    @Override
6825    public final void backgroundResourcesReleased(IBinder token) {
6826        final long origId = Binder.clearCallingIdentity();
6827        try {
6828            synchronized (this) {
6829                ActivityStack stack = ActivityRecord.getStackLocked(token);
6830                if (stack != null) {
6831                    stack.backgroundResourcesReleased();
6832                }
6833            }
6834        } finally {
6835            Binder.restoreCallingIdentity(origId);
6836        }
6837    }
6838
6839    @Override
6840    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6841        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6842    }
6843
6844    @Override
6845    public final void notifyEnterAnimationComplete(IBinder token) {
6846        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6847    }
6848
6849    @Override
6850    public String getCallingPackage(IBinder token) {
6851        synchronized (this) {
6852            ActivityRecord r = getCallingRecordLocked(token);
6853            return r != null ? r.info.packageName : null;
6854        }
6855    }
6856
6857    @Override
6858    public ComponentName getCallingActivity(IBinder token) {
6859        synchronized (this) {
6860            ActivityRecord r = getCallingRecordLocked(token);
6861            return r != null ? r.intent.getComponent() : null;
6862        }
6863    }
6864
6865    private ActivityRecord getCallingRecordLocked(IBinder token) {
6866        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6867        if (r == null) {
6868            return null;
6869        }
6870        return r.resultTo;
6871    }
6872
6873    @Override
6874    public ComponentName getActivityClassForToken(IBinder token) {
6875        synchronized(this) {
6876            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6877            if (r == null) {
6878                return null;
6879            }
6880            return r.intent.getComponent();
6881        }
6882    }
6883
6884    @Override
6885    public String getPackageForToken(IBinder token) {
6886        synchronized(this) {
6887            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6888            if (r == null) {
6889                return null;
6890            }
6891            return r.packageName;
6892        }
6893    }
6894
6895    @Override
6896    public boolean isRootVoiceInteraction(IBinder token) {
6897        synchronized(this) {
6898            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6899            if (r == null) {
6900                return false;
6901            }
6902            return r.rootVoiceInteraction;
6903        }
6904    }
6905
6906    @Override
6907    public IIntentSender getIntentSender(int type,
6908            String packageName, IBinder token, String resultWho,
6909            int requestCode, Intent[] intents, String[] resolvedTypes,
6910            int flags, Bundle bOptions, int userId) {
6911        enforceNotIsolatedCaller("getIntentSender");
6912        // Refuse possible leaked file descriptors
6913        if (intents != null) {
6914            if (intents.length < 1) {
6915                throw new IllegalArgumentException("Intents array length must be >= 1");
6916            }
6917            for (int i=0; i<intents.length; i++) {
6918                Intent intent = intents[i];
6919                if (intent != null) {
6920                    if (intent.hasFileDescriptors()) {
6921                        throw new IllegalArgumentException("File descriptors passed in Intent");
6922                    }
6923                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6924                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6925                        throw new IllegalArgumentException(
6926                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6927                    }
6928                    intents[i] = new Intent(intent);
6929                }
6930            }
6931            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6932                throw new IllegalArgumentException(
6933                        "Intent array length does not match resolvedTypes length");
6934            }
6935        }
6936        if (bOptions != null) {
6937            if (bOptions.hasFileDescriptors()) {
6938                throw new IllegalArgumentException("File descriptors passed in options");
6939            }
6940        }
6941
6942        synchronized(this) {
6943            int callingUid = Binder.getCallingUid();
6944            int origUserId = userId;
6945            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6946                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6947                    ALLOW_NON_FULL, "getIntentSender", null);
6948            if (origUserId == UserHandle.USER_CURRENT) {
6949                // We don't want to evaluate this until the pending intent is
6950                // actually executed.  However, we do want to always do the
6951                // security checking for it above.
6952                userId = UserHandle.USER_CURRENT;
6953            }
6954            try {
6955                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6956                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6957                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6958                    if (!UserHandle.isSameApp(callingUid, uid)) {
6959                        String msg = "Permission Denial: getIntentSender() from pid="
6960                            + Binder.getCallingPid()
6961                            + ", uid=" + Binder.getCallingUid()
6962                            + ", (need uid=" + uid + ")"
6963                            + " is not allowed to send as package " + packageName;
6964                        Slog.w(TAG, msg);
6965                        throw new SecurityException(msg);
6966                    }
6967                }
6968
6969                return getIntentSenderLocked(type, packageName, callingUid, userId,
6970                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6971
6972            } catch (RemoteException e) {
6973                throw new SecurityException(e);
6974            }
6975        }
6976    }
6977
6978    IIntentSender getIntentSenderLocked(int type, String packageName,
6979            int callingUid, int userId, IBinder token, String resultWho,
6980            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6981            Bundle bOptions) {
6982        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6983        ActivityRecord activity = null;
6984        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6985            activity = ActivityRecord.isInStackLocked(token);
6986            if (activity == null) {
6987                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6988                return null;
6989            }
6990            if (activity.finishing) {
6991                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6992                return null;
6993            }
6994        }
6995
6996        // We're going to be splicing together extras before sending, so we're
6997        // okay poking into any contained extras.
6998        if (intents != null) {
6999            for (int i = 0; i < intents.length; i++) {
7000                intents[i].setDefusable(true);
7001            }
7002        }
7003        Bundle.setDefusable(bOptions, true);
7004
7005        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7006        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7007        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7008        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7009                |PendingIntent.FLAG_UPDATE_CURRENT);
7010
7011        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7012                type, packageName, activity, resultWho,
7013                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7014        WeakReference<PendingIntentRecord> ref;
7015        ref = mIntentSenderRecords.get(key);
7016        PendingIntentRecord rec = ref != null ? ref.get() : null;
7017        if (rec != null) {
7018            if (!cancelCurrent) {
7019                if (updateCurrent) {
7020                    if (rec.key.requestIntent != null) {
7021                        rec.key.requestIntent.replaceExtras(intents != null ?
7022                                intents[intents.length - 1] : null);
7023                    }
7024                    if (intents != null) {
7025                        intents[intents.length-1] = rec.key.requestIntent;
7026                        rec.key.allIntents = intents;
7027                        rec.key.allResolvedTypes = resolvedTypes;
7028                    } else {
7029                        rec.key.allIntents = null;
7030                        rec.key.allResolvedTypes = null;
7031                    }
7032                }
7033                return rec;
7034            }
7035            rec.canceled = true;
7036            mIntentSenderRecords.remove(key);
7037        }
7038        if (noCreate) {
7039            return rec;
7040        }
7041        rec = new PendingIntentRecord(this, key, callingUid);
7042        mIntentSenderRecords.put(key, rec.ref);
7043        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7044            if (activity.pendingResults == null) {
7045                activity.pendingResults
7046                        = new HashSet<WeakReference<PendingIntentRecord>>();
7047            }
7048            activity.pendingResults.add(rec.ref);
7049        }
7050        return rec;
7051    }
7052
7053    @Override
7054    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7055            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7056        if (target instanceof PendingIntentRecord) {
7057            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7058                    finishedReceiver, requiredPermission, options);
7059        } else {
7060            try {
7061                target.send(code, intent, resolvedType, null, requiredPermission, options);
7062            } catch (RemoteException e) {
7063            }
7064            // Platform code can rely on getting a result back when the send is done, but if
7065            // this intent sender is from outside of the system we can't rely on it doing that.
7066            // So instead we don't give it the result receiver, and instead just directly
7067            // report the finish immediately.
7068            if (finishedReceiver != null) {
7069                try {
7070                    finishedReceiver.performReceive(intent, 0,
7071                            null, null, false, false, UserHandle.getCallingUserId());
7072                } catch (RemoteException e) {
7073                }
7074            }
7075            return 0;
7076        }
7077    }
7078
7079    @Override
7080    public void cancelIntentSender(IIntentSender sender) {
7081        if (!(sender instanceof PendingIntentRecord)) {
7082            return;
7083        }
7084        synchronized(this) {
7085            PendingIntentRecord rec = (PendingIntentRecord)sender;
7086            try {
7087                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7088                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7089                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7090                    String msg = "Permission Denial: cancelIntentSender() from pid="
7091                        + Binder.getCallingPid()
7092                        + ", uid=" + Binder.getCallingUid()
7093                        + " is not allowed to cancel packges "
7094                        + rec.key.packageName;
7095                    Slog.w(TAG, msg);
7096                    throw new SecurityException(msg);
7097                }
7098            } catch (RemoteException e) {
7099                throw new SecurityException(e);
7100            }
7101            cancelIntentSenderLocked(rec, true);
7102        }
7103    }
7104
7105    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7106        rec.canceled = true;
7107        mIntentSenderRecords.remove(rec.key);
7108        if (cleanActivity && rec.key.activity != null) {
7109            rec.key.activity.pendingResults.remove(rec.ref);
7110        }
7111    }
7112
7113    @Override
7114    public String getPackageForIntentSender(IIntentSender pendingResult) {
7115        if (!(pendingResult instanceof PendingIntentRecord)) {
7116            return null;
7117        }
7118        try {
7119            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7120            return res.key.packageName;
7121        } catch (ClassCastException e) {
7122        }
7123        return null;
7124    }
7125
7126    @Override
7127    public int getUidForIntentSender(IIntentSender sender) {
7128        if (sender instanceof PendingIntentRecord) {
7129            try {
7130                PendingIntentRecord res = (PendingIntentRecord)sender;
7131                return res.uid;
7132            } catch (ClassCastException e) {
7133            }
7134        }
7135        return -1;
7136    }
7137
7138    @Override
7139    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7140        if (!(pendingResult instanceof PendingIntentRecord)) {
7141            return false;
7142        }
7143        try {
7144            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7145            if (res.key.allIntents == null) {
7146                return false;
7147            }
7148            for (int i=0; i<res.key.allIntents.length; i++) {
7149                Intent intent = res.key.allIntents[i];
7150                if (intent.getPackage() != null && intent.getComponent() != null) {
7151                    return false;
7152                }
7153            }
7154            return true;
7155        } catch (ClassCastException e) {
7156        }
7157        return false;
7158    }
7159
7160    @Override
7161    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7162        if (!(pendingResult instanceof PendingIntentRecord)) {
7163            return false;
7164        }
7165        try {
7166            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7167            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7168                return true;
7169            }
7170            return false;
7171        } catch (ClassCastException e) {
7172        }
7173        return false;
7174    }
7175
7176    @Override
7177    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7178        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7179                "getIntentForIntentSender()");
7180        if (!(pendingResult instanceof PendingIntentRecord)) {
7181            return null;
7182        }
7183        try {
7184            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7185            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7186        } catch (ClassCastException e) {
7187        }
7188        return null;
7189    }
7190
7191    @Override
7192    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7193        if (!(pendingResult instanceof PendingIntentRecord)) {
7194            return null;
7195        }
7196        try {
7197            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7198            synchronized (this) {
7199                return getTagForIntentSenderLocked(res, prefix);
7200            }
7201        } catch (ClassCastException e) {
7202        }
7203        return null;
7204    }
7205
7206    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7207        final Intent intent = res.key.requestIntent;
7208        if (intent != null) {
7209            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7210                    || res.lastTagPrefix.equals(prefix))) {
7211                return res.lastTag;
7212            }
7213            res.lastTagPrefix = prefix;
7214            final StringBuilder sb = new StringBuilder(128);
7215            if (prefix != null) {
7216                sb.append(prefix);
7217            }
7218            if (intent.getAction() != null) {
7219                sb.append(intent.getAction());
7220            } else if (intent.getComponent() != null) {
7221                intent.getComponent().appendShortString(sb);
7222            } else {
7223                sb.append("?");
7224            }
7225            return res.lastTag = sb.toString();
7226        }
7227        return null;
7228    }
7229
7230    @Override
7231    public void setProcessLimit(int max) {
7232        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7233                "setProcessLimit()");
7234        synchronized (this) {
7235            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7236            mProcessLimitOverride = max;
7237        }
7238        trimApplications();
7239    }
7240
7241    @Override
7242    public int getProcessLimit() {
7243        synchronized (this) {
7244            return mProcessLimitOverride;
7245        }
7246    }
7247
7248    void foregroundTokenDied(ForegroundToken token) {
7249        synchronized (ActivityManagerService.this) {
7250            synchronized (mPidsSelfLocked) {
7251                ForegroundToken cur
7252                    = mForegroundProcesses.get(token.pid);
7253                if (cur != token) {
7254                    return;
7255                }
7256                mForegroundProcesses.remove(token.pid);
7257                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7258                if (pr == null) {
7259                    return;
7260                }
7261                pr.forcingToForeground = null;
7262                updateProcessForegroundLocked(pr, false, false);
7263            }
7264            updateOomAdjLocked();
7265        }
7266    }
7267
7268    @Override
7269    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7270        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7271                "setProcessForeground()");
7272        synchronized(this) {
7273            boolean changed = false;
7274
7275            synchronized (mPidsSelfLocked) {
7276                ProcessRecord pr = mPidsSelfLocked.get(pid);
7277                if (pr == null && isForeground) {
7278                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7279                    return;
7280                }
7281                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7282                if (oldToken != null) {
7283                    oldToken.token.unlinkToDeath(oldToken, 0);
7284                    mForegroundProcesses.remove(pid);
7285                    if (pr != null) {
7286                        pr.forcingToForeground = null;
7287                    }
7288                    changed = true;
7289                }
7290                if (isForeground && token != null) {
7291                    ForegroundToken newToken = new ForegroundToken() {
7292                        @Override
7293                        public void binderDied() {
7294                            foregroundTokenDied(this);
7295                        }
7296                    };
7297                    newToken.pid = pid;
7298                    newToken.token = token;
7299                    try {
7300                        token.linkToDeath(newToken, 0);
7301                        mForegroundProcesses.put(pid, newToken);
7302                        pr.forcingToForeground = token;
7303                        changed = true;
7304                    } catch (RemoteException e) {
7305                        // If the process died while doing this, we will later
7306                        // do the cleanup with the process death link.
7307                    }
7308                }
7309            }
7310
7311            if (changed) {
7312                updateOomAdjLocked();
7313            }
7314        }
7315    }
7316
7317    @Override
7318    public boolean isAppForeground(int uid) throws RemoteException {
7319        synchronized (this) {
7320            UidRecord uidRec = mActiveUids.get(uid);
7321            if (uidRec == null || uidRec.idle) {
7322                return false;
7323            }
7324            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7325        }
7326    }
7327
7328    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7329    // be guarded by permission checking.
7330    int getUidState(int uid) {
7331        synchronized (this) {
7332            UidRecord uidRec = mActiveUids.get(uid);
7333            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7334        }
7335    }
7336
7337    @Override
7338    public boolean isInMultiWindowMode(IBinder token) {
7339        final long origId = Binder.clearCallingIdentity();
7340        try {
7341            synchronized(this) {
7342                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7343                if (r == null) {
7344                    return false;
7345                }
7346                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7347                return !r.task.mFullscreen;
7348            }
7349        } finally {
7350            Binder.restoreCallingIdentity(origId);
7351        }
7352    }
7353
7354    @Override
7355    public boolean isInPictureInPictureMode(IBinder token) {
7356        final long origId = Binder.clearCallingIdentity();
7357        try {
7358            synchronized(this) {
7359                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7360                if (stack == null) {
7361                    return false;
7362                }
7363                return stack.mStackId == PINNED_STACK_ID;
7364            }
7365        } finally {
7366            Binder.restoreCallingIdentity(origId);
7367        }
7368    }
7369
7370    @Override
7371    public void enterPictureInPictureMode(IBinder token) {
7372        final long origId = Binder.clearCallingIdentity();
7373        try {
7374            synchronized(this) {
7375                if (!mSupportsPictureInPicture) {
7376                    throw new IllegalStateException("enterPictureInPictureMode: "
7377                            + "Device doesn't support picture-in-picture mode.");
7378                }
7379
7380                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7381
7382                if (r == null) {
7383                    throw new IllegalStateException("enterPictureInPictureMode: "
7384                            + "Can't find activity for token=" + token);
7385                }
7386
7387                if (!r.supportsPictureInPicture()) {
7388                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7389                            + "Picture-In-Picture not supported for r=" + r);
7390                }
7391
7392                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7393                // current bounds.
7394                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7395                final Rect bounds = (pinnedStack != null)
7396                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7397
7398                mStackSupervisor.moveActivityToPinnedStackLocked(
7399                        r, "enterPictureInPictureMode", bounds);
7400            }
7401        } finally {
7402            Binder.restoreCallingIdentity(origId);
7403        }
7404    }
7405
7406    // =========================================================
7407    // PROCESS INFO
7408    // =========================================================
7409
7410    static class ProcessInfoService extends IProcessInfoService.Stub {
7411        final ActivityManagerService mActivityManagerService;
7412        ProcessInfoService(ActivityManagerService activityManagerService) {
7413            mActivityManagerService = activityManagerService;
7414        }
7415
7416        @Override
7417        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7418            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7419                    /*in*/ pids, /*out*/ states, null);
7420        }
7421
7422        @Override
7423        public void getProcessStatesAndOomScoresFromPids(
7424                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7425            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7426                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7427        }
7428    }
7429
7430    /**
7431     * For each PID in the given input array, write the current process state
7432     * for that process into the states array, or -1 to indicate that no
7433     * process with the given PID exists. If scores array is provided, write
7434     * the oom score for the process into the scores array, with INVALID_ADJ
7435     * indicating the PID doesn't exist.
7436     */
7437    public void getProcessStatesAndOomScoresForPIDs(
7438            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7439        if (scores != null) {
7440            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7441                    "getProcessStatesAndOomScoresForPIDs()");
7442        }
7443
7444        if (pids == null) {
7445            throw new NullPointerException("pids");
7446        } else if (states == null) {
7447            throw new NullPointerException("states");
7448        } else if (pids.length != states.length) {
7449            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7450        } else if (scores != null && pids.length != scores.length) {
7451            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7452        }
7453
7454        synchronized (mPidsSelfLocked) {
7455            for (int i = 0; i < pids.length; i++) {
7456                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7457                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7458                        pr.curProcState;
7459                if (scores != null) {
7460                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7461                }
7462            }
7463        }
7464    }
7465
7466    // =========================================================
7467    // PERMISSIONS
7468    // =========================================================
7469
7470    static class PermissionController extends IPermissionController.Stub {
7471        ActivityManagerService mActivityManagerService;
7472        PermissionController(ActivityManagerService activityManagerService) {
7473            mActivityManagerService = activityManagerService;
7474        }
7475
7476        @Override
7477        public boolean checkPermission(String permission, int pid, int uid) {
7478            return mActivityManagerService.checkPermission(permission, pid,
7479                    uid) == PackageManager.PERMISSION_GRANTED;
7480        }
7481
7482        @Override
7483        public String[] getPackagesForUid(int uid) {
7484            return mActivityManagerService.mContext.getPackageManager()
7485                    .getPackagesForUid(uid);
7486        }
7487
7488        @Override
7489        public boolean isRuntimePermission(String permission) {
7490            try {
7491                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7492                        .getPermissionInfo(permission, 0);
7493                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7494            } catch (NameNotFoundException nnfe) {
7495                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7496            }
7497            return false;
7498        }
7499    }
7500
7501    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7502        @Override
7503        public int checkComponentPermission(String permission, int pid, int uid,
7504                int owningUid, boolean exported) {
7505            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7506                    owningUid, exported);
7507        }
7508
7509        @Override
7510        public Object getAMSLock() {
7511            return ActivityManagerService.this;
7512        }
7513    }
7514
7515    /**
7516     * This can be called with or without the global lock held.
7517     */
7518    int checkComponentPermission(String permission, int pid, int uid,
7519            int owningUid, boolean exported) {
7520        if (pid == MY_PID) {
7521            return PackageManager.PERMISSION_GRANTED;
7522        }
7523        return ActivityManager.checkComponentPermission(permission, uid,
7524                owningUid, exported);
7525    }
7526
7527    /**
7528     * As the only public entry point for permissions checking, this method
7529     * can enforce the semantic that requesting a check on a null global
7530     * permission is automatically denied.  (Internally a null permission
7531     * string is used when calling {@link #checkComponentPermission} in cases
7532     * when only uid-based security is needed.)
7533     *
7534     * This can be called with or without the global lock held.
7535     */
7536    @Override
7537    public int checkPermission(String permission, int pid, int uid) {
7538        if (permission == null) {
7539            return PackageManager.PERMISSION_DENIED;
7540        }
7541        return checkComponentPermission(permission, pid, uid, -1, true);
7542    }
7543
7544    @Override
7545    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7546        if (permission == null) {
7547            return PackageManager.PERMISSION_DENIED;
7548        }
7549
7550        // We might be performing an operation on behalf of an indirect binder
7551        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7552        // client identity accordingly before proceeding.
7553        Identity tlsIdentity = sCallerIdentity.get();
7554        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7555            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7556                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7557            uid = tlsIdentity.uid;
7558            pid = tlsIdentity.pid;
7559        }
7560
7561        return checkComponentPermission(permission, pid, uid, -1, true);
7562    }
7563
7564    /**
7565     * Binder IPC calls go through the public entry point.
7566     * This can be called with or without the global lock held.
7567     */
7568    int checkCallingPermission(String permission) {
7569        return checkPermission(permission,
7570                Binder.getCallingPid(),
7571                UserHandle.getAppId(Binder.getCallingUid()));
7572    }
7573
7574    /**
7575     * This can be called with or without the global lock held.
7576     */
7577    void enforceCallingPermission(String permission, String func) {
7578        if (checkCallingPermission(permission)
7579                == PackageManager.PERMISSION_GRANTED) {
7580            return;
7581        }
7582
7583        String msg = "Permission Denial: " + func + " from pid="
7584                + Binder.getCallingPid()
7585                + ", uid=" + Binder.getCallingUid()
7586                + " requires " + permission;
7587        Slog.w(TAG, msg);
7588        throw new SecurityException(msg);
7589    }
7590
7591    /**
7592     * Determine if UID is holding permissions required to access {@link Uri} in
7593     * the given {@link ProviderInfo}. Final permission checking is always done
7594     * in {@link ContentProvider}.
7595     */
7596    private final boolean checkHoldingPermissionsLocked(
7597            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7598        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7599                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7600        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7601            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7602                    != PERMISSION_GRANTED) {
7603                return false;
7604            }
7605        }
7606        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7607    }
7608
7609    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7610            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7611        if (pi.applicationInfo.uid == uid) {
7612            return true;
7613        } else if (!pi.exported) {
7614            return false;
7615        }
7616
7617        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7618        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7619        try {
7620            // check if target holds top-level <provider> permissions
7621            if (!readMet && pi.readPermission != null && considerUidPermissions
7622                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7623                readMet = true;
7624            }
7625            if (!writeMet && pi.writePermission != null && considerUidPermissions
7626                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7627                writeMet = true;
7628            }
7629
7630            // track if unprotected read/write is allowed; any denied
7631            // <path-permission> below removes this ability
7632            boolean allowDefaultRead = pi.readPermission == null;
7633            boolean allowDefaultWrite = pi.writePermission == null;
7634
7635            // check if target holds any <path-permission> that match uri
7636            final PathPermission[] pps = pi.pathPermissions;
7637            if (pps != null) {
7638                final String path = grantUri.uri.getPath();
7639                int i = pps.length;
7640                while (i > 0 && (!readMet || !writeMet)) {
7641                    i--;
7642                    PathPermission pp = pps[i];
7643                    if (pp.match(path)) {
7644                        if (!readMet) {
7645                            final String pprperm = pp.getReadPermission();
7646                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7647                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7648                                    + ": match=" + pp.match(path)
7649                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7650                            if (pprperm != null) {
7651                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7652                                        == PERMISSION_GRANTED) {
7653                                    readMet = true;
7654                                } else {
7655                                    allowDefaultRead = false;
7656                                }
7657                            }
7658                        }
7659                        if (!writeMet) {
7660                            final String ppwperm = pp.getWritePermission();
7661                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7662                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7663                                    + ": match=" + pp.match(path)
7664                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7665                            if (ppwperm != null) {
7666                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7667                                        == PERMISSION_GRANTED) {
7668                                    writeMet = true;
7669                                } else {
7670                                    allowDefaultWrite = false;
7671                                }
7672                            }
7673                        }
7674                    }
7675                }
7676            }
7677
7678            // grant unprotected <provider> read/write, if not blocked by
7679            // <path-permission> above
7680            if (allowDefaultRead) readMet = true;
7681            if (allowDefaultWrite) writeMet = true;
7682
7683        } catch (RemoteException e) {
7684            return false;
7685        }
7686
7687        return readMet && writeMet;
7688    }
7689
7690    public int getAppStartMode(int uid, String packageName) {
7691        synchronized (this) {
7692            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7693        }
7694    }
7695
7696    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7697            boolean allowWhenForeground) {
7698        UidRecord uidRec = mActiveUids.get(uid);
7699        if (!mLenientBackgroundCheck) {
7700            if (!allowWhenForeground || uidRec == null
7701                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7702                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7703                        packageName) != AppOpsManager.MODE_ALLOWED) {
7704                    return ActivityManager.APP_START_MODE_DELAYED;
7705                }
7706            }
7707
7708        } else if (uidRec == null || uidRec.idle) {
7709            if (callingPid >= 0) {
7710                ProcessRecord proc;
7711                synchronized (mPidsSelfLocked) {
7712                    proc = mPidsSelfLocked.get(callingPid);
7713                }
7714                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7715                    // Whoever is instigating this is in the foreground, so we will allow it
7716                    // to go through.
7717                    return ActivityManager.APP_START_MODE_NORMAL;
7718                }
7719            }
7720            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7721                    != AppOpsManager.MODE_ALLOWED) {
7722                return ActivityManager.APP_START_MODE_DELAYED;
7723            }
7724        }
7725        return ActivityManager.APP_START_MODE_NORMAL;
7726    }
7727
7728    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7729        ProviderInfo pi = null;
7730        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7731        if (cpr != null) {
7732            pi = cpr.info;
7733        } else {
7734            try {
7735                pi = AppGlobals.getPackageManager().resolveContentProvider(
7736                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7737            } catch (RemoteException ex) {
7738            }
7739        }
7740        return pi;
7741    }
7742
7743    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7744        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7745        if (targetUris != null) {
7746            return targetUris.get(grantUri);
7747        }
7748        return null;
7749    }
7750
7751    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7752            String targetPkg, int targetUid, GrantUri grantUri) {
7753        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7754        if (targetUris == null) {
7755            targetUris = Maps.newArrayMap();
7756            mGrantedUriPermissions.put(targetUid, targetUris);
7757        }
7758
7759        UriPermission perm = targetUris.get(grantUri);
7760        if (perm == null) {
7761            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7762            targetUris.put(grantUri, perm);
7763        }
7764
7765        return perm;
7766    }
7767
7768    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7769            final int modeFlags) {
7770        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7771        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7772                : UriPermission.STRENGTH_OWNED;
7773
7774        // Root gets to do everything.
7775        if (uid == 0) {
7776            return true;
7777        }
7778
7779        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7780        if (perms == null) return false;
7781
7782        // First look for exact match
7783        final UriPermission exactPerm = perms.get(grantUri);
7784        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7785            return true;
7786        }
7787
7788        // No exact match, look for prefixes
7789        final int N = perms.size();
7790        for (int i = 0; i < N; i++) {
7791            final UriPermission perm = perms.valueAt(i);
7792            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7793                    && perm.getStrength(modeFlags) >= minStrength) {
7794                return true;
7795            }
7796        }
7797
7798        return false;
7799    }
7800
7801    /**
7802     * @param uri This uri must NOT contain an embedded userId.
7803     * @param userId The userId in which the uri is to be resolved.
7804     */
7805    @Override
7806    public int checkUriPermission(Uri uri, int pid, int uid,
7807            final int modeFlags, int userId, IBinder callerToken) {
7808        enforceNotIsolatedCaller("checkUriPermission");
7809
7810        // Another redirected-binder-call permissions check as in
7811        // {@link checkPermissionWithToken}.
7812        Identity tlsIdentity = sCallerIdentity.get();
7813        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7814            uid = tlsIdentity.uid;
7815            pid = tlsIdentity.pid;
7816        }
7817
7818        // Our own process gets to do everything.
7819        if (pid == MY_PID) {
7820            return PackageManager.PERMISSION_GRANTED;
7821        }
7822        synchronized (this) {
7823            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7824                    ? PackageManager.PERMISSION_GRANTED
7825                    : PackageManager.PERMISSION_DENIED;
7826        }
7827    }
7828
7829    /**
7830     * Check if the targetPkg can be granted permission to access uri by
7831     * the callingUid using the given modeFlags.  Throws a security exception
7832     * if callingUid is not allowed to do this.  Returns the uid of the target
7833     * if the URI permission grant should be performed; returns -1 if it is not
7834     * needed (for example targetPkg already has permission to access the URI).
7835     * If you already know the uid of the target, you can supply it in
7836     * lastTargetUid else set that to -1.
7837     */
7838    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7839            final int modeFlags, int lastTargetUid) {
7840        if (!Intent.isAccessUriMode(modeFlags)) {
7841            return -1;
7842        }
7843
7844        if (targetPkg != null) {
7845            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7846                    "Checking grant " + targetPkg + " permission to " + grantUri);
7847        }
7848
7849        final IPackageManager pm = AppGlobals.getPackageManager();
7850
7851        // If this is not a content: uri, we can't do anything with it.
7852        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7853            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7854                    "Can't grant URI permission for non-content URI: " + grantUri);
7855            return -1;
7856        }
7857
7858        final String authority = grantUri.uri.getAuthority();
7859        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7860        if (pi == null) {
7861            Slog.w(TAG, "No content provider found for permission check: " +
7862                    grantUri.uri.toSafeString());
7863            return -1;
7864        }
7865
7866        int targetUid = lastTargetUid;
7867        if (targetUid < 0 && targetPkg != null) {
7868            try {
7869                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7870                        UserHandle.getUserId(callingUid));
7871                if (targetUid < 0) {
7872                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7873                            "Can't grant URI permission no uid for: " + targetPkg);
7874                    return -1;
7875                }
7876            } catch (RemoteException ex) {
7877                return -1;
7878            }
7879        }
7880
7881        if (targetUid >= 0) {
7882            // First...  does the target actually need this permission?
7883            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7884                // No need to grant the target this permission.
7885                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7886                        "Target " + targetPkg + " already has full permission to " + grantUri);
7887                return -1;
7888            }
7889        } else {
7890            // First...  there is no target package, so can anyone access it?
7891            boolean allowed = pi.exported;
7892            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7893                if (pi.readPermission != null) {
7894                    allowed = false;
7895                }
7896            }
7897            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7898                if (pi.writePermission != null) {
7899                    allowed = false;
7900                }
7901            }
7902            if (allowed) {
7903                return -1;
7904            }
7905        }
7906
7907        /* There is a special cross user grant if:
7908         * - The target is on another user.
7909         * - Apps on the current user can access the uri without any uid permissions.
7910         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7911         * grant uri permissions.
7912         */
7913        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7914                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7915                modeFlags, false /*without considering the uid permissions*/);
7916
7917        // Second...  is the provider allowing granting of URI permissions?
7918        if (!specialCrossUserGrant) {
7919            if (!pi.grantUriPermissions) {
7920                throw new SecurityException("Provider " + pi.packageName
7921                        + "/" + pi.name
7922                        + " does not allow granting of Uri permissions (uri "
7923                        + grantUri + ")");
7924            }
7925            if (pi.uriPermissionPatterns != null) {
7926                final int N = pi.uriPermissionPatterns.length;
7927                boolean allowed = false;
7928                for (int i=0; i<N; i++) {
7929                    if (pi.uriPermissionPatterns[i] != null
7930                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7931                        allowed = true;
7932                        break;
7933                    }
7934                }
7935                if (!allowed) {
7936                    throw new SecurityException("Provider " + pi.packageName
7937                            + "/" + pi.name
7938                            + " does not allow granting of permission to path of Uri "
7939                            + grantUri);
7940                }
7941            }
7942        }
7943
7944        // Third...  does the caller itself have permission to access
7945        // this uri?
7946        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7947            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7948                // Require they hold a strong enough Uri permission
7949                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7950                    throw new SecurityException("Uid " + callingUid
7951                            + " does not have permission to uri " + grantUri);
7952                }
7953            }
7954        }
7955        return targetUid;
7956    }
7957
7958    /**
7959     * @param uri This uri must NOT contain an embedded userId.
7960     * @param userId The userId in which the uri is to be resolved.
7961     */
7962    @Override
7963    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7964            final int modeFlags, int userId) {
7965        enforceNotIsolatedCaller("checkGrantUriPermission");
7966        synchronized(this) {
7967            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7968                    new GrantUri(userId, uri, false), modeFlags, -1);
7969        }
7970    }
7971
7972    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7973            final int modeFlags, UriPermissionOwner owner) {
7974        if (!Intent.isAccessUriMode(modeFlags)) {
7975            return;
7976        }
7977
7978        // So here we are: the caller has the assumed permission
7979        // to the uri, and the target doesn't.  Let's now give this to
7980        // the target.
7981
7982        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7983                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7984
7985        final String authority = grantUri.uri.getAuthority();
7986        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7987        if (pi == null) {
7988            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7989            return;
7990        }
7991
7992        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7993            grantUri.prefix = true;
7994        }
7995        final UriPermission perm = findOrCreateUriPermissionLocked(
7996                pi.packageName, targetPkg, targetUid, grantUri);
7997        perm.grantModes(modeFlags, owner);
7998    }
7999
8000    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8001            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8002        if (targetPkg == null) {
8003            throw new NullPointerException("targetPkg");
8004        }
8005        int targetUid;
8006        final IPackageManager pm = AppGlobals.getPackageManager();
8007        try {
8008            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8009        } catch (RemoteException ex) {
8010            return;
8011        }
8012
8013        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8014                targetUid);
8015        if (targetUid < 0) {
8016            return;
8017        }
8018
8019        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8020                owner);
8021    }
8022
8023    static class NeededUriGrants extends ArrayList<GrantUri> {
8024        final String targetPkg;
8025        final int targetUid;
8026        final int flags;
8027
8028        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8029            this.targetPkg = targetPkg;
8030            this.targetUid = targetUid;
8031            this.flags = flags;
8032        }
8033    }
8034
8035    /**
8036     * Like checkGrantUriPermissionLocked, but takes an Intent.
8037     */
8038    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8039            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8040        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8041                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8042                + " clip=" + (intent != null ? intent.getClipData() : null)
8043                + " from " + intent + "; flags=0x"
8044                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8045
8046        if (targetPkg == null) {
8047            throw new NullPointerException("targetPkg");
8048        }
8049
8050        if (intent == null) {
8051            return null;
8052        }
8053        Uri data = intent.getData();
8054        ClipData clip = intent.getClipData();
8055        if (data == null && clip == null) {
8056            return null;
8057        }
8058        // Default userId for uris in the intent (if they don't specify it themselves)
8059        int contentUserHint = intent.getContentUserHint();
8060        if (contentUserHint == UserHandle.USER_CURRENT) {
8061            contentUserHint = UserHandle.getUserId(callingUid);
8062        }
8063        final IPackageManager pm = AppGlobals.getPackageManager();
8064        int targetUid;
8065        if (needed != null) {
8066            targetUid = needed.targetUid;
8067        } else {
8068            try {
8069                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8070                        targetUserId);
8071            } catch (RemoteException ex) {
8072                return null;
8073            }
8074            if (targetUid < 0) {
8075                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8076                        "Can't grant URI permission no uid for: " + targetPkg
8077                        + " on user " + targetUserId);
8078                return null;
8079            }
8080        }
8081        if (data != null) {
8082            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8083            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8084                    targetUid);
8085            if (targetUid > 0) {
8086                if (needed == null) {
8087                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8088                }
8089                needed.add(grantUri);
8090            }
8091        }
8092        if (clip != null) {
8093            for (int i=0; i<clip.getItemCount(); i++) {
8094                Uri uri = clip.getItemAt(i).getUri();
8095                if (uri != null) {
8096                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8097                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8098                            targetUid);
8099                    if (targetUid > 0) {
8100                        if (needed == null) {
8101                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8102                        }
8103                        needed.add(grantUri);
8104                    }
8105                } else {
8106                    Intent clipIntent = clip.getItemAt(i).getIntent();
8107                    if (clipIntent != null) {
8108                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8109                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8110                        if (newNeeded != null) {
8111                            needed = newNeeded;
8112                        }
8113                    }
8114                }
8115            }
8116        }
8117
8118        return needed;
8119    }
8120
8121    /**
8122     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8123     */
8124    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8125            UriPermissionOwner owner) {
8126        if (needed != null) {
8127            for (int i=0; i<needed.size(); i++) {
8128                GrantUri grantUri = needed.get(i);
8129                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8130                        grantUri, needed.flags, owner);
8131            }
8132        }
8133    }
8134
8135    void grantUriPermissionFromIntentLocked(int callingUid,
8136            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8137        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8138                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8139        if (needed == null) {
8140            return;
8141        }
8142
8143        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8144    }
8145
8146    /**
8147     * @param uri This uri must NOT contain an embedded userId.
8148     * @param userId The userId in which the uri is to be resolved.
8149     */
8150    @Override
8151    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8152            final int modeFlags, int userId) {
8153        enforceNotIsolatedCaller("grantUriPermission");
8154        GrantUri grantUri = new GrantUri(userId, uri, false);
8155        synchronized(this) {
8156            final ProcessRecord r = getRecordForAppLocked(caller);
8157            if (r == null) {
8158                throw new SecurityException("Unable to find app for caller "
8159                        + caller
8160                        + " when granting permission to uri " + grantUri);
8161            }
8162            if (targetPkg == null) {
8163                throw new IllegalArgumentException("null target");
8164            }
8165            if (grantUri == null) {
8166                throw new IllegalArgumentException("null uri");
8167            }
8168
8169            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8170                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8171                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8172                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8173
8174            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8175                    UserHandle.getUserId(r.uid));
8176        }
8177    }
8178
8179    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8180        if (perm.modeFlags == 0) {
8181            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8182                    perm.targetUid);
8183            if (perms != null) {
8184                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8185                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8186
8187                perms.remove(perm.uri);
8188                if (perms.isEmpty()) {
8189                    mGrantedUriPermissions.remove(perm.targetUid);
8190                }
8191            }
8192        }
8193    }
8194
8195    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8196        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8197                "Revoking all granted permissions to " + grantUri);
8198
8199        final IPackageManager pm = AppGlobals.getPackageManager();
8200        final String authority = grantUri.uri.getAuthority();
8201        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8202        if (pi == null) {
8203            Slog.w(TAG, "No content provider found for permission revoke: "
8204                    + grantUri.toSafeString());
8205            return;
8206        }
8207
8208        // Does the caller have this permission on the URI?
8209        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8210            // If they don't have direct access to the URI, then revoke any
8211            // ownerless URI permissions that have been granted to them.
8212            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8213            if (perms != null) {
8214                boolean persistChanged = false;
8215                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8216                    final UriPermission perm = it.next();
8217                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8218                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8219                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8220                                "Revoking non-owned " + perm.targetUid
8221                                + " permission to " + perm.uri);
8222                        persistChanged |= perm.revokeModes(
8223                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8224                        if (perm.modeFlags == 0) {
8225                            it.remove();
8226                        }
8227                    }
8228                }
8229                if (perms.isEmpty()) {
8230                    mGrantedUriPermissions.remove(callingUid);
8231                }
8232                if (persistChanged) {
8233                    schedulePersistUriGrants();
8234                }
8235            }
8236            return;
8237        }
8238
8239        boolean persistChanged = false;
8240
8241        // Go through all of the permissions and remove any that match.
8242        int N = mGrantedUriPermissions.size();
8243        for (int i = 0; i < N; i++) {
8244            final int targetUid = mGrantedUriPermissions.keyAt(i);
8245            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8246
8247            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8248                final UriPermission perm = it.next();
8249                if (perm.uri.sourceUserId == grantUri.sourceUserId
8250                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8251                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8252                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8253                    persistChanged |= perm.revokeModes(
8254                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8255                    if (perm.modeFlags == 0) {
8256                        it.remove();
8257                    }
8258                }
8259            }
8260
8261            if (perms.isEmpty()) {
8262                mGrantedUriPermissions.remove(targetUid);
8263                N--;
8264                i--;
8265            }
8266        }
8267
8268        if (persistChanged) {
8269            schedulePersistUriGrants();
8270        }
8271    }
8272
8273    /**
8274     * @param uri This uri must NOT contain an embedded userId.
8275     * @param userId The userId in which the uri is to be resolved.
8276     */
8277    @Override
8278    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8279            int userId) {
8280        enforceNotIsolatedCaller("revokeUriPermission");
8281        synchronized(this) {
8282            final ProcessRecord r = getRecordForAppLocked(caller);
8283            if (r == null) {
8284                throw new SecurityException("Unable to find app for caller "
8285                        + caller
8286                        + " when revoking permission to uri " + uri);
8287            }
8288            if (uri == null) {
8289                Slog.w(TAG, "revokeUriPermission: null uri");
8290                return;
8291            }
8292
8293            if (!Intent.isAccessUriMode(modeFlags)) {
8294                return;
8295            }
8296
8297            final String authority = uri.getAuthority();
8298            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8299            if (pi == null) {
8300                Slog.w(TAG, "No content provider found for permission revoke: "
8301                        + uri.toSafeString());
8302                return;
8303            }
8304
8305            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8306        }
8307    }
8308
8309    /**
8310     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8311     * given package.
8312     *
8313     * @param packageName Package name to match, or {@code null} to apply to all
8314     *            packages.
8315     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8316     *            to all users.
8317     * @param persistable If persistable grants should be removed.
8318     */
8319    private void removeUriPermissionsForPackageLocked(
8320            String packageName, int userHandle, boolean persistable) {
8321        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8322            throw new IllegalArgumentException("Must narrow by either package or user");
8323        }
8324
8325        boolean persistChanged = false;
8326
8327        int N = mGrantedUriPermissions.size();
8328        for (int i = 0; i < N; i++) {
8329            final int targetUid = mGrantedUriPermissions.keyAt(i);
8330            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8331
8332            // Only inspect grants matching user
8333            if (userHandle == UserHandle.USER_ALL
8334                    || userHandle == UserHandle.getUserId(targetUid)) {
8335                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8336                    final UriPermission perm = it.next();
8337
8338                    // Only inspect grants matching package
8339                    if (packageName == null || perm.sourcePkg.equals(packageName)
8340                            || perm.targetPkg.equals(packageName)) {
8341                        persistChanged |= perm.revokeModes(persistable
8342                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8343
8344                        // Only remove when no modes remain; any persisted grants
8345                        // will keep this alive.
8346                        if (perm.modeFlags == 0) {
8347                            it.remove();
8348                        }
8349                    }
8350                }
8351
8352                if (perms.isEmpty()) {
8353                    mGrantedUriPermissions.remove(targetUid);
8354                    N--;
8355                    i--;
8356                }
8357            }
8358        }
8359
8360        if (persistChanged) {
8361            schedulePersistUriGrants();
8362        }
8363    }
8364
8365    @Override
8366    public IBinder newUriPermissionOwner(String name) {
8367        enforceNotIsolatedCaller("newUriPermissionOwner");
8368        synchronized(this) {
8369            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8370            return owner.getExternalTokenLocked();
8371        }
8372    }
8373
8374    @Override
8375    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8376        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8377        synchronized(this) {
8378            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8379            if (r == null) {
8380                throw new IllegalArgumentException("Activity does not exist; token="
8381                        + activityToken);
8382            }
8383            return r.getUriPermissionsLocked().getExternalTokenLocked();
8384        }
8385    }
8386    /**
8387     * @param uri This uri must NOT contain an embedded userId.
8388     * @param sourceUserId The userId in which the uri is to be resolved.
8389     * @param targetUserId The userId of the app that receives the grant.
8390     */
8391    @Override
8392    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8393            final int modeFlags, int sourceUserId, int targetUserId) {
8394        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8395                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8396                "grantUriPermissionFromOwner", null);
8397        synchronized(this) {
8398            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8399            if (owner == null) {
8400                throw new IllegalArgumentException("Unknown owner: " + token);
8401            }
8402            if (fromUid != Binder.getCallingUid()) {
8403                if (Binder.getCallingUid() != Process.myUid()) {
8404                    // Only system code can grant URI permissions on behalf
8405                    // of other users.
8406                    throw new SecurityException("nice try");
8407                }
8408            }
8409            if (targetPkg == null) {
8410                throw new IllegalArgumentException("null target");
8411            }
8412            if (uri == null) {
8413                throw new IllegalArgumentException("null uri");
8414            }
8415
8416            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8417                    modeFlags, owner, targetUserId);
8418        }
8419    }
8420
8421    /**
8422     * @param uri This uri must NOT contain an embedded userId.
8423     * @param userId The userId in which the uri is to be resolved.
8424     */
8425    @Override
8426    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8427        synchronized(this) {
8428            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8429            if (owner == null) {
8430                throw new IllegalArgumentException("Unknown owner: " + token);
8431            }
8432
8433            if (uri == null) {
8434                owner.removeUriPermissionsLocked(mode);
8435            } else {
8436                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8437            }
8438        }
8439    }
8440
8441    private void schedulePersistUriGrants() {
8442        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8443            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8444                    10 * DateUtils.SECOND_IN_MILLIS);
8445        }
8446    }
8447
8448    private void writeGrantedUriPermissions() {
8449        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8450
8451        // Snapshot permissions so we can persist without lock
8452        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8453        synchronized (this) {
8454            final int size = mGrantedUriPermissions.size();
8455            for (int i = 0; i < size; i++) {
8456                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8457                for (UriPermission perm : perms.values()) {
8458                    if (perm.persistedModeFlags != 0) {
8459                        persist.add(perm.snapshot());
8460                    }
8461                }
8462            }
8463        }
8464
8465        FileOutputStream fos = null;
8466        try {
8467            fos = mGrantFile.startWrite();
8468
8469            XmlSerializer out = new FastXmlSerializer();
8470            out.setOutput(fos, StandardCharsets.UTF_8.name());
8471            out.startDocument(null, true);
8472            out.startTag(null, TAG_URI_GRANTS);
8473            for (UriPermission.Snapshot perm : persist) {
8474                out.startTag(null, TAG_URI_GRANT);
8475                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8476                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8477                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8478                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8479                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8480                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8481                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8482                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8483                out.endTag(null, TAG_URI_GRANT);
8484            }
8485            out.endTag(null, TAG_URI_GRANTS);
8486            out.endDocument();
8487
8488            mGrantFile.finishWrite(fos);
8489        } catch (IOException e) {
8490            if (fos != null) {
8491                mGrantFile.failWrite(fos);
8492            }
8493        }
8494    }
8495
8496    private void readGrantedUriPermissionsLocked() {
8497        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8498
8499        final long now = System.currentTimeMillis();
8500
8501        FileInputStream fis = null;
8502        try {
8503            fis = mGrantFile.openRead();
8504            final XmlPullParser in = Xml.newPullParser();
8505            in.setInput(fis, StandardCharsets.UTF_8.name());
8506
8507            int type;
8508            while ((type = in.next()) != END_DOCUMENT) {
8509                final String tag = in.getName();
8510                if (type == START_TAG) {
8511                    if (TAG_URI_GRANT.equals(tag)) {
8512                        final int sourceUserId;
8513                        final int targetUserId;
8514                        final int userHandle = readIntAttribute(in,
8515                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8516                        if (userHandle != UserHandle.USER_NULL) {
8517                            // For backwards compatibility.
8518                            sourceUserId = userHandle;
8519                            targetUserId = userHandle;
8520                        } else {
8521                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8522                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8523                        }
8524                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8525                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8526                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8527                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8528                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8529                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8530
8531                        // Sanity check that provider still belongs to source package
8532                        final ProviderInfo pi = getProviderInfoLocked(
8533                                uri.getAuthority(), sourceUserId);
8534                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8535                            int targetUid = -1;
8536                            try {
8537                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8538                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8539                            } catch (RemoteException e) {
8540                            }
8541                            if (targetUid != -1) {
8542                                final UriPermission perm = findOrCreateUriPermissionLocked(
8543                                        sourcePkg, targetPkg, targetUid,
8544                                        new GrantUri(sourceUserId, uri, prefix));
8545                                perm.initPersistedModes(modeFlags, createdTime);
8546                            }
8547                        } else {
8548                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8549                                    + " but instead found " + pi);
8550                        }
8551                    }
8552                }
8553            }
8554        } catch (FileNotFoundException e) {
8555            // Missing grants is okay
8556        } catch (IOException e) {
8557            Slog.wtf(TAG, "Failed reading Uri grants", e);
8558        } catch (XmlPullParserException e) {
8559            Slog.wtf(TAG, "Failed reading Uri grants", e);
8560        } finally {
8561            IoUtils.closeQuietly(fis);
8562        }
8563    }
8564
8565    /**
8566     * @param uri This uri must NOT contain an embedded userId.
8567     * @param userId The userId in which the uri is to be resolved.
8568     */
8569    @Override
8570    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8571        enforceNotIsolatedCaller("takePersistableUriPermission");
8572
8573        Preconditions.checkFlagsArgument(modeFlags,
8574                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8575
8576        synchronized (this) {
8577            final int callingUid = Binder.getCallingUid();
8578            boolean persistChanged = false;
8579            GrantUri grantUri = new GrantUri(userId, uri, false);
8580
8581            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8582                    new GrantUri(userId, uri, false));
8583            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8584                    new GrantUri(userId, uri, true));
8585
8586            final boolean exactValid = (exactPerm != null)
8587                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8588            final boolean prefixValid = (prefixPerm != null)
8589                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8590
8591            if (!(exactValid || prefixValid)) {
8592                throw new SecurityException("No persistable permission grants found for UID "
8593                        + callingUid + " and Uri " + grantUri.toSafeString());
8594            }
8595
8596            if (exactValid) {
8597                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8598            }
8599            if (prefixValid) {
8600                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8601            }
8602
8603            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8604
8605            if (persistChanged) {
8606                schedulePersistUriGrants();
8607            }
8608        }
8609    }
8610
8611    /**
8612     * @param uri This uri must NOT contain an embedded userId.
8613     * @param userId The userId in which the uri is to be resolved.
8614     */
8615    @Override
8616    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8617        enforceNotIsolatedCaller("releasePersistableUriPermission");
8618
8619        Preconditions.checkFlagsArgument(modeFlags,
8620                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8621
8622        synchronized (this) {
8623            final int callingUid = Binder.getCallingUid();
8624            boolean persistChanged = false;
8625
8626            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8627                    new GrantUri(userId, uri, false));
8628            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8629                    new GrantUri(userId, uri, true));
8630            if (exactPerm == null && prefixPerm == null) {
8631                throw new SecurityException("No permission grants found for UID " + callingUid
8632                        + " and Uri " + uri.toSafeString());
8633            }
8634
8635            if (exactPerm != null) {
8636                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8637                removeUriPermissionIfNeededLocked(exactPerm);
8638            }
8639            if (prefixPerm != null) {
8640                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8641                removeUriPermissionIfNeededLocked(prefixPerm);
8642            }
8643
8644            if (persistChanged) {
8645                schedulePersistUriGrants();
8646            }
8647        }
8648    }
8649
8650    /**
8651     * Prune any older {@link UriPermission} for the given UID until outstanding
8652     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8653     *
8654     * @return if any mutations occured that require persisting.
8655     */
8656    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8657        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8658        if (perms == null) return false;
8659        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8660
8661        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8662        for (UriPermission perm : perms.values()) {
8663            if (perm.persistedModeFlags != 0) {
8664                persisted.add(perm);
8665            }
8666        }
8667
8668        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8669        if (trimCount <= 0) return false;
8670
8671        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8672        for (int i = 0; i < trimCount; i++) {
8673            final UriPermission perm = persisted.get(i);
8674
8675            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8676                    "Trimming grant created at " + perm.persistedCreateTime);
8677
8678            perm.releasePersistableModes(~0);
8679            removeUriPermissionIfNeededLocked(perm);
8680        }
8681
8682        return true;
8683    }
8684
8685    @Override
8686    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8687            String packageName, boolean incoming) {
8688        enforceNotIsolatedCaller("getPersistedUriPermissions");
8689        Preconditions.checkNotNull(packageName, "packageName");
8690
8691        final int callingUid = Binder.getCallingUid();
8692        final IPackageManager pm = AppGlobals.getPackageManager();
8693        try {
8694            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8695                    UserHandle.getUserId(callingUid));
8696            if (packageUid != callingUid) {
8697                throw new SecurityException(
8698                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8699            }
8700        } catch (RemoteException e) {
8701            throw new SecurityException("Failed to verify package name ownership");
8702        }
8703
8704        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8705        synchronized (this) {
8706            if (incoming) {
8707                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8708                        callingUid);
8709                if (perms == null) {
8710                    Slog.w(TAG, "No permission grants found for " + packageName);
8711                } else {
8712                    for (UriPermission perm : perms.values()) {
8713                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8714                            result.add(perm.buildPersistedPublicApiObject());
8715                        }
8716                    }
8717                }
8718            } else {
8719                final int size = mGrantedUriPermissions.size();
8720                for (int i = 0; i < size; i++) {
8721                    final ArrayMap<GrantUri, UriPermission> perms =
8722                            mGrantedUriPermissions.valueAt(i);
8723                    for (UriPermission perm : perms.values()) {
8724                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8725                            result.add(perm.buildPersistedPublicApiObject());
8726                        }
8727                    }
8728                }
8729            }
8730        }
8731        return new ParceledListSlice<android.content.UriPermission>(result);
8732    }
8733
8734    @Override
8735    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8736            String packageName, int userId) {
8737        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8738                "getGrantedUriPermissions");
8739
8740        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8741        synchronized (this) {
8742            final int size = mGrantedUriPermissions.size();
8743            for (int i = 0; i < size; i++) {
8744                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8745                for (UriPermission perm : perms.values()) {
8746                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8747                            && perm.persistedModeFlags != 0) {
8748                        result.add(perm.buildPersistedPublicApiObject());
8749                    }
8750                }
8751            }
8752        }
8753        return new ParceledListSlice<android.content.UriPermission>(result);
8754    }
8755
8756    @Override
8757    public void clearGrantedUriPermissions(String packageName, int userId) {
8758        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8759                "clearGrantedUriPermissions");
8760        removeUriPermissionsForPackageLocked(packageName, userId, true);
8761    }
8762
8763    @Override
8764    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8765        synchronized (this) {
8766            ProcessRecord app =
8767                who != null ? getRecordForAppLocked(who) : null;
8768            if (app == null) return;
8769
8770            Message msg = Message.obtain();
8771            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8772            msg.obj = app;
8773            msg.arg1 = waiting ? 1 : 0;
8774            mUiHandler.sendMessage(msg);
8775        }
8776    }
8777
8778    @Override
8779    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8780        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8781        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8782        outInfo.availMem = Process.getFreeMemory();
8783        outInfo.totalMem = Process.getTotalMemory();
8784        outInfo.threshold = homeAppMem;
8785        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8786        outInfo.hiddenAppThreshold = cachedAppMem;
8787        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8788                ProcessList.SERVICE_ADJ);
8789        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8790                ProcessList.VISIBLE_APP_ADJ);
8791        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8792                ProcessList.FOREGROUND_APP_ADJ);
8793    }
8794
8795    // =========================================================
8796    // TASK MANAGEMENT
8797    // =========================================================
8798
8799    @Override
8800    public List<IAppTask> getAppTasks(String callingPackage) {
8801        int callingUid = Binder.getCallingUid();
8802        long ident = Binder.clearCallingIdentity();
8803
8804        synchronized(this) {
8805            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8806            try {
8807                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8808
8809                final int N = mRecentTasks.size();
8810                for (int i = 0; i < N; i++) {
8811                    TaskRecord tr = mRecentTasks.get(i);
8812                    // Skip tasks that do not match the caller.  We don't need to verify
8813                    // callingPackage, because we are also limiting to callingUid and know
8814                    // that will limit to the correct security sandbox.
8815                    if (tr.effectiveUid != callingUid) {
8816                        continue;
8817                    }
8818                    Intent intent = tr.getBaseIntent();
8819                    if (intent == null ||
8820                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8821                        continue;
8822                    }
8823                    ActivityManager.RecentTaskInfo taskInfo =
8824                            createRecentTaskInfoFromTaskRecord(tr);
8825                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8826                    list.add(taskImpl);
8827                }
8828            } finally {
8829                Binder.restoreCallingIdentity(ident);
8830            }
8831            return list;
8832        }
8833    }
8834
8835    @Override
8836    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8837        final int callingUid = Binder.getCallingUid();
8838        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8839
8840        synchronized(this) {
8841            if (DEBUG_ALL) Slog.v(
8842                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8843
8844            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8845                    callingUid);
8846
8847            // TODO: Improve with MRU list from all ActivityStacks.
8848            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8849        }
8850
8851        return list;
8852    }
8853
8854    /**
8855     * Creates a new RecentTaskInfo from a TaskRecord.
8856     */
8857    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8858        // Update the task description to reflect any changes in the task stack
8859        tr.updateTaskDescription();
8860
8861        // Compose the recent task info
8862        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8863        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8864        rti.persistentId = tr.taskId;
8865        rti.baseIntent = new Intent(tr.getBaseIntent());
8866        rti.origActivity = tr.origActivity;
8867        rti.realActivity = tr.realActivity;
8868        rti.description = tr.lastDescription;
8869        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8870        rti.userId = tr.userId;
8871        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8872        rti.firstActiveTime = tr.firstActiveTime;
8873        rti.lastActiveTime = tr.lastActiveTime;
8874        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8875        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8876        rti.numActivities = 0;
8877        if (tr.mBounds != null) {
8878            rti.bounds = new Rect(tr.mBounds);
8879        }
8880        rti.isDockable = tr.canGoInDockedStack();
8881        rti.resizeMode = tr.mResizeMode;
8882
8883        ActivityRecord base = null;
8884        ActivityRecord top = null;
8885        ActivityRecord tmp;
8886
8887        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8888            tmp = tr.mActivities.get(i);
8889            if (tmp.finishing) {
8890                continue;
8891            }
8892            base = tmp;
8893            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8894                top = base;
8895            }
8896            rti.numActivities++;
8897        }
8898
8899        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8900        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8901
8902        return rti;
8903    }
8904
8905    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8906        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8907                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8908        if (!allowed) {
8909            if (checkPermission(android.Manifest.permission.GET_TASKS,
8910                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8911                // Temporary compatibility: some existing apps on the system image may
8912                // still be requesting the old permission and not switched to the new
8913                // one; if so, we'll still allow them full access.  This means we need
8914                // to see if they are holding the old permission and are a system app.
8915                try {
8916                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8917                        allowed = true;
8918                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8919                                + " is using old GET_TASKS but privileged; allowing");
8920                    }
8921                } catch (RemoteException e) {
8922                }
8923            }
8924        }
8925        if (!allowed) {
8926            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8927                    + " does not hold REAL_GET_TASKS; limiting output");
8928        }
8929        return allowed;
8930    }
8931
8932    @Override
8933    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8934        final int callingUid = Binder.getCallingUid();
8935        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8936                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8937
8938        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8939        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8940        synchronized (this) {
8941            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8942                    callingUid);
8943            final boolean detailed = checkCallingPermission(
8944                    android.Manifest.permission.GET_DETAILED_TASKS)
8945                    == PackageManager.PERMISSION_GRANTED;
8946
8947            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8948                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8949                return Collections.emptyList();
8950            }
8951            mRecentTasks.loadUserRecentsLocked(userId);
8952
8953            final int recentsCount = mRecentTasks.size();
8954            ArrayList<ActivityManager.RecentTaskInfo> res =
8955                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8956
8957            final Set<Integer> includedUsers;
8958            if (includeProfiles) {
8959                includedUsers = mUserController.getProfileIds(userId);
8960            } else {
8961                includedUsers = new HashSet<>();
8962            }
8963            includedUsers.add(Integer.valueOf(userId));
8964
8965            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8966                TaskRecord tr = mRecentTasks.get(i);
8967                // Only add calling user or related users recent tasks
8968                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8969                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8970                    continue;
8971                }
8972
8973                if (tr.realActivitySuspended) {
8974                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8975                    continue;
8976                }
8977
8978                // Return the entry if desired by the caller.  We always return
8979                // the first entry, because callers always expect this to be the
8980                // foreground app.  We may filter others if the caller has
8981                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8982                // we should exclude the entry.
8983
8984                if (i == 0
8985                        || withExcluded
8986                        || (tr.intent == null)
8987                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8988                                == 0)) {
8989                    if (!allowed) {
8990                        // If the caller doesn't have the GET_TASKS permission, then only
8991                        // allow them to see a small subset of tasks -- their own and home.
8992                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8993                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8994                            continue;
8995                        }
8996                    }
8997                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8998                        if (tr.stack != null && tr.stack.isHomeStack()) {
8999                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9000                                    "Skipping, home stack task: " + tr);
9001                            continue;
9002                        }
9003                    }
9004                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9005                        final ActivityStack stack = tr.stack;
9006                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9007                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9008                                    "Skipping, top task in docked stack: " + tr);
9009                            continue;
9010                        }
9011                    }
9012                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9013                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9014                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9015                                    "Skipping, pinned stack task: " + tr);
9016                            continue;
9017                        }
9018                    }
9019                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9020                        // Don't include auto remove tasks that are finished or finishing.
9021                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9022                                "Skipping, auto-remove without activity: " + tr);
9023                        continue;
9024                    }
9025                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9026                            && !tr.isAvailable) {
9027                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9028                                "Skipping, unavail real act: " + tr);
9029                        continue;
9030                    }
9031
9032                    if (!tr.mUserSetupComplete) {
9033                        // Don't include task launched while user is not done setting-up.
9034                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9035                                "Skipping, user setup not complete: " + tr);
9036                        continue;
9037                    }
9038
9039                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9040                    if (!detailed) {
9041                        rti.baseIntent.replaceExtras((Bundle)null);
9042                    }
9043
9044                    res.add(rti);
9045                    maxNum--;
9046                }
9047            }
9048            return res;
9049        }
9050    }
9051
9052    @Override
9053    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9054        synchronized (this) {
9055            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9056                    "getTaskThumbnail()");
9057            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9058                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9059            if (tr != null) {
9060                return tr.getTaskThumbnailLocked();
9061            }
9062        }
9063        return null;
9064    }
9065
9066    @Override
9067    public int addAppTask(IBinder activityToken, Intent intent,
9068            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9069        final int callingUid = Binder.getCallingUid();
9070        final long callingIdent = Binder.clearCallingIdentity();
9071
9072        try {
9073            synchronized (this) {
9074                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9075                if (r == null) {
9076                    throw new IllegalArgumentException("Activity does not exist; token="
9077                            + activityToken);
9078                }
9079                ComponentName comp = intent.getComponent();
9080                if (comp == null) {
9081                    throw new IllegalArgumentException("Intent " + intent
9082                            + " must specify explicit component");
9083                }
9084                if (thumbnail.getWidth() != mThumbnailWidth
9085                        || thumbnail.getHeight() != mThumbnailHeight) {
9086                    throw new IllegalArgumentException("Bad thumbnail size: got "
9087                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9088                            + mThumbnailWidth + "x" + mThumbnailHeight);
9089                }
9090                if (intent.getSelector() != null) {
9091                    intent.setSelector(null);
9092                }
9093                if (intent.getSourceBounds() != null) {
9094                    intent.setSourceBounds(null);
9095                }
9096                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9097                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9098                        // The caller has added this as an auto-remove task...  that makes no
9099                        // sense, so turn off auto-remove.
9100                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9101                    }
9102                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9103                    // Must be a new task.
9104                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9105                }
9106                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9107                    mLastAddedTaskActivity = null;
9108                }
9109                ActivityInfo ainfo = mLastAddedTaskActivity;
9110                if (ainfo == null) {
9111                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9112                            comp, 0, UserHandle.getUserId(callingUid));
9113                    if (ainfo.applicationInfo.uid != callingUid) {
9114                        throw new SecurityException(
9115                                "Can't add task for another application: target uid="
9116                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9117                    }
9118                }
9119
9120                // Use the full screen as the context for the task thumbnail
9121                final Point displaySize = new Point();
9122                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9123                r.task.stack.getDisplaySize(displaySize);
9124                thumbnailInfo.taskWidth = displaySize.x;
9125                thumbnailInfo.taskHeight = displaySize.y;
9126                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9127
9128                TaskRecord task = new TaskRecord(this,
9129                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9130                        ainfo, intent, description, thumbnailInfo);
9131
9132                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9133                if (trimIdx >= 0) {
9134                    // If this would have caused a trim, then we'll abort because that
9135                    // means it would be added at the end of the list but then just removed.
9136                    return INVALID_TASK_ID;
9137                }
9138
9139                final int N = mRecentTasks.size();
9140                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9141                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9142                    tr.removedFromRecents();
9143                }
9144
9145                task.inRecents = true;
9146                mRecentTasks.add(task);
9147                r.task.stack.addTask(task, false, "addAppTask");
9148
9149                task.setLastThumbnailLocked(thumbnail);
9150                task.freeLastThumbnail();
9151
9152                return task.taskId;
9153            }
9154        } finally {
9155            Binder.restoreCallingIdentity(callingIdent);
9156        }
9157    }
9158
9159    @Override
9160    public Point getAppTaskThumbnailSize() {
9161        synchronized (this) {
9162            return new Point(mThumbnailWidth,  mThumbnailHeight);
9163        }
9164    }
9165
9166    @Override
9167    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9168        synchronized (this) {
9169            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9170            if (r != null) {
9171                r.setTaskDescription(td);
9172                r.task.updateTaskDescription();
9173            }
9174        }
9175    }
9176
9177    @Override
9178    public void setTaskResizeable(int taskId, int resizeableMode) {
9179        synchronized (this) {
9180            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9181                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9182            if (task == null) {
9183                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9184                return;
9185            }
9186            if (task.mResizeMode != resizeableMode) {
9187                task.mResizeMode = resizeableMode;
9188                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9189                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9190                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9191            }
9192        }
9193    }
9194
9195    @Override
9196    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9197        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9198        long ident = Binder.clearCallingIdentity();
9199        try {
9200            synchronized (this) {
9201                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9202                if (task == null) {
9203                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9204                    return;
9205                }
9206                int stackId = task.stack.mStackId;
9207                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9208                // in crop windows resize mode or if the task size is affected by the docked stack
9209                // changing size. No need to update configuration.
9210                if (bounds != null && task.inCropWindowsResizeMode()
9211                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9212                    mWindowManager.scrollTask(task.taskId, bounds);
9213                    return;
9214                }
9215
9216                // Place the task in the right stack if it isn't there already based on
9217                // the requested bounds.
9218                // The stack transition logic is:
9219                // - a null bounds on a freeform task moves that task to fullscreen
9220                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9221                //   that task to freeform
9222                // - otherwise the task is not moved
9223                if (!StackId.isTaskResizeAllowed(stackId)) {
9224                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9225                }
9226                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9227                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9228                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9229                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9230                }
9231                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9232                if (stackId != task.stack.mStackId) {
9233                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9234                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9235                    preserveWindow = false;
9236                }
9237
9238                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9239                        false /* deferResume */);
9240            }
9241        } finally {
9242            Binder.restoreCallingIdentity(ident);
9243        }
9244    }
9245
9246    @Override
9247    public Rect getTaskBounds(int taskId) {
9248        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9249        long ident = Binder.clearCallingIdentity();
9250        Rect rect = new Rect();
9251        try {
9252            synchronized (this) {
9253                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9254                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9255                if (task == null) {
9256                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9257                    return rect;
9258                }
9259                if (task.stack != null) {
9260                    // Return the bounds from window manager since it will be adjusted for various
9261                    // things like the presense of a docked stack for tasks that aren't resizeable.
9262                    mWindowManager.getTaskBounds(task.taskId, rect);
9263                } else {
9264                    // Task isn't in window manager yet since it isn't associated with a stack.
9265                    // Return the persist value from activity manager
9266                    if (task.mBounds != null) {
9267                        rect.set(task.mBounds);
9268                    } else if (task.mLastNonFullscreenBounds != null) {
9269                        rect.set(task.mLastNonFullscreenBounds);
9270                    }
9271                }
9272            }
9273        } finally {
9274            Binder.restoreCallingIdentity(ident);
9275        }
9276        return rect;
9277    }
9278
9279    @Override
9280    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9281        if (userId != UserHandle.getCallingUserId()) {
9282            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9283                    "getTaskDescriptionIcon");
9284        }
9285        final File passedIconFile = new File(filePath);
9286        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9287                passedIconFile.getName());
9288        if (!legitIconFile.getPath().equals(filePath)
9289                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9290            throw new IllegalArgumentException("Bad file path: " + filePath
9291                    + " passed for userId " + userId);
9292        }
9293        return mRecentTasks.getTaskDescriptionIcon(filePath);
9294    }
9295
9296    @Override
9297    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9298            throws RemoteException {
9299        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9300                opts.getCustomInPlaceResId() == 0) {
9301            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9302                    "with valid animation");
9303        }
9304        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9305        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9306                opts.getCustomInPlaceResId());
9307        mWindowManager.executeAppTransition();
9308    }
9309
9310    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9311            boolean removeFromRecents) {
9312        if (removeFromRecents) {
9313            mRecentTasks.remove(tr);
9314            tr.removedFromRecents();
9315        }
9316        ComponentName component = tr.getBaseIntent().getComponent();
9317        if (component == null) {
9318            Slog.w(TAG, "No component for base intent of task: " + tr);
9319            return;
9320        }
9321
9322        // Find any running services associated with this app and stop if needed.
9323        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9324
9325        if (!killProcess) {
9326            return;
9327        }
9328
9329        // Determine if the process(es) for this task should be killed.
9330        final String pkg = component.getPackageName();
9331        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9332        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9333        for (int i = 0; i < pmap.size(); i++) {
9334
9335            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9336            for (int j = 0; j < uids.size(); j++) {
9337                ProcessRecord proc = uids.valueAt(j);
9338                if (proc.userId != tr.userId) {
9339                    // Don't kill process for a different user.
9340                    continue;
9341                }
9342                if (proc == mHomeProcess) {
9343                    // Don't kill the home process along with tasks from the same package.
9344                    continue;
9345                }
9346                if (!proc.pkgList.containsKey(pkg)) {
9347                    // Don't kill process that is not associated with this task.
9348                    continue;
9349                }
9350
9351                for (int k = 0; k < proc.activities.size(); k++) {
9352                    TaskRecord otherTask = proc.activities.get(k).task;
9353                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9354                        // Don't kill process(es) that has an activity in a different task that is
9355                        // also in recents.
9356                        return;
9357                    }
9358                }
9359
9360                if (proc.foregroundServices) {
9361                    // Don't kill process(es) with foreground service.
9362                    return;
9363                }
9364
9365                // Add process to kill list.
9366                procsToKill.add(proc);
9367            }
9368        }
9369
9370        // Kill the running processes.
9371        for (int i = 0; i < procsToKill.size(); i++) {
9372            ProcessRecord pr = procsToKill.get(i);
9373            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9374                    && pr.curReceiver == null) {
9375                pr.kill("remove task", true);
9376            } else {
9377                // We delay killing processes that are not in the background or running a receiver.
9378                pr.waitingToKill = "remove task";
9379            }
9380        }
9381    }
9382
9383    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9384        // Remove all tasks with activities in the specified package from the list of recent tasks
9385        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9386            TaskRecord tr = mRecentTasks.get(i);
9387            if (tr.userId != userId) continue;
9388
9389            ComponentName cn = tr.intent.getComponent();
9390            if (cn != null && cn.getPackageName().equals(packageName)) {
9391                // If the package name matches, remove the task.
9392                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9393            }
9394        }
9395    }
9396
9397    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9398            int userId) {
9399
9400        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9401            TaskRecord tr = mRecentTasks.get(i);
9402            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9403                continue;
9404            }
9405
9406            ComponentName cn = tr.intent.getComponent();
9407            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9408                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9409            if (sameComponent) {
9410                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9411            }
9412        }
9413    }
9414
9415    /**
9416     * Removes the task with the specified task id.
9417     *
9418     * @param taskId Identifier of the task to be removed.
9419     * @param killProcess Kill any process associated with the task if possible.
9420     * @param removeFromRecents Whether to also remove the task from recents.
9421     * @return Returns true if the given task was found and removed.
9422     */
9423    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9424            boolean removeFromRecents) {
9425        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9426                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9427        if (tr != null) {
9428            tr.removeTaskActivitiesLocked();
9429            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9430            if (tr.isPersistable) {
9431                notifyTaskPersisterLocked(null, true);
9432            }
9433            return true;
9434        }
9435        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9436        return false;
9437    }
9438
9439    @Override
9440    public void removeStack(int stackId) {
9441        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9442        if (stackId == HOME_STACK_ID) {
9443            throw new IllegalArgumentException("Removing home stack is not allowed.");
9444        }
9445
9446        synchronized (this) {
9447            final long ident = Binder.clearCallingIdentity();
9448            try {
9449                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9450                if (stack == null) {
9451                    return;
9452                }
9453                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9454                for (int i = tasks.size() - 1; i >= 0; i--) {
9455                    removeTaskByIdLocked(
9456                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9457                }
9458            } finally {
9459                Binder.restoreCallingIdentity(ident);
9460            }
9461        }
9462    }
9463
9464    @Override
9465    public boolean removeTask(int taskId) {
9466        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9467        synchronized (this) {
9468            final long ident = Binder.clearCallingIdentity();
9469            try {
9470                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9471            } finally {
9472                Binder.restoreCallingIdentity(ident);
9473            }
9474        }
9475    }
9476
9477    /**
9478     * TODO: Add mController hook
9479     */
9480    @Override
9481    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9482        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9483
9484        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9485        synchronized(this) {
9486            moveTaskToFrontLocked(taskId, flags, bOptions);
9487        }
9488    }
9489
9490    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9491        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9492
9493        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9494                Binder.getCallingUid(), -1, -1, "Task to front")) {
9495            ActivityOptions.abort(options);
9496            return;
9497        }
9498        final long origId = Binder.clearCallingIdentity();
9499        try {
9500            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9501            if (task == null) {
9502                Slog.d(TAG, "Could not find task for id: "+ taskId);
9503                return;
9504            }
9505            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9506                mStackSupervisor.showLockTaskToast();
9507                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9508                return;
9509            }
9510            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9511            if (prev != null && prev.isRecentsActivity()) {
9512                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9513            }
9514            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9515                    false /* forceNonResizable */);
9516        } finally {
9517            Binder.restoreCallingIdentity(origId);
9518        }
9519        ActivityOptions.abort(options);
9520    }
9521
9522    /**
9523     * Moves an activity, and all of the other activities within the same task, to the bottom
9524     * of the history stack.  The activity's order within the task is unchanged.
9525     *
9526     * @param token A reference to the activity we wish to move
9527     * @param nonRoot If false then this only works if the activity is the root
9528     *                of a task; if true it will work for any activity in a task.
9529     * @return Returns true if the move completed, false if not.
9530     */
9531    @Override
9532    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9533        enforceNotIsolatedCaller("moveActivityTaskToBack");
9534        synchronized(this) {
9535            final long origId = Binder.clearCallingIdentity();
9536            try {
9537                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9538                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9539                if (task != null) {
9540                    if (mStackSupervisor.isLockedTask(task)) {
9541                        mStackSupervisor.showLockTaskToast();
9542                        return false;
9543                    }
9544                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9545                }
9546            } finally {
9547                Binder.restoreCallingIdentity(origId);
9548            }
9549        }
9550        return false;
9551    }
9552
9553    @Override
9554    public void moveTaskBackwards(int task) {
9555        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9556                "moveTaskBackwards()");
9557
9558        synchronized(this) {
9559            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9560                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9561                return;
9562            }
9563            final long origId = Binder.clearCallingIdentity();
9564            moveTaskBackwardsLocked(task);
9565            Binder.restoreCallingIdentity(origId);
9566        }
9567    }
9568
9569    private final void moveTaskBackwardsLocked(int task) {
9570        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9571    }
9572
9573    @Override
9574    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9575            IActivityContainerCallback callback) throws RemoteException {
9576        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9577        synchronized (this) {
9578            if (parentActivityToken == null) {
9579                throw new IllegalArgumentException("parent token must not be null");
9580            }
9581            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9582            if (r == null) {
9583                return null;
9584            }
9585            if (callback == null) {
9586                throw new IllegalArgumentException("callback must not be null");
9587            }
9588            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9589        }
9590    }
9591
9592    @Override
9593    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9594        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9595        synchronized (this) {
9596            mStackSupervisor.deleteActivityContainer(container);
9597        }
9598    }
9599
9600    @Override
9601    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9602        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9603        synchronized (this) {
9604            final int stackId = mStackSupervisor.getNextStackId();
9605            final ActivityStack stack =
9606                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9607            if (stack == null) {
9608                return null;
9609            }
9610            return stack.mActivityContainer;
9611        }
9612    }
9613
9614    @Override
9615    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9616        synchronized (this) {
9617            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9618            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9619                return stack.mActivityContainer.getDisplayId();
9620            }
9621            return Display.DEFAULT_DISPLAY;
9622        }
9623    }
9624
9625    @Override
9626    public int getActivityStackId(IBinder token) throws RemoteException {
9627        synchronized (this) {
9628            ActivityStack stack = ActivityRecord.getStackLocked(token);
9629            if (stack == null) {
9630                return INVALID_STACK_ID;
9631            }
9632            return stack.mStackId;
9633        }
9634    }
9635
9636    @Override
9637    public void exitFreeformMode(IBinder token) throws RemoteException {
9638        synchronized (this) {
9639            long ident = Binder.clearCallingIdentity();
9640            try {
9641                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9642                if (r == null) {
9643                    throw new IllegalArgumentException(
9644                            "exitFreeformMode: No activity record matching token=" + token);
9645                }
9646                final ActivityStack stack = r.getStackLocked(token);
9647                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9648                    throw new IllegalStateException(
9649                            "exitFreeformMode: You can only go fullscreen from freeform.");
9650                }
9651                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9652                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9653                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9654            } finally {
9655                Binder.restoreCallingIdentity(ident);
9656            }
9657        }
9658    }
9659
9660    @Override
9661    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9662        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9663        if (stackId == HOME_STACK_ID) {
9664            throw new IllegalArgumentException(
9665                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9666        }
9667        synchronized (this) {
9668            long ident = Binder.clearCallingIdentity();
9669            try {
9670                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9671                        + " to stackId=" + stackId + " toTop=" + toTop);
9672                if (stackId == DOCKED_STACK_ID) {
9673                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9674                            null /* initialBounds */);
9675                }
9676                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9677                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9678                if (result && stackId == DOCKED_STACK_ID) {
9679                    // If task moved to docked stack - show recents if needed.
9680                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9681                            "moveTaskToDockedStack");
9682                }
9683            } finally {
9684                Binder.restoreCallingIdentity(ident);
9685            }
9686        }
9687    }
9688
9689    @Override
9690    public void swapDockedAndFullscreenStack() throws RemoteException {
9691        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9692        synchronized (this) {
9693            long ident = Binder.clearCallingIdentity();
9694            try {
9695                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9696                        FULLSCREEN_WORKSPACE_STACK_ID);
9697                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9698                        : null;
9699                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9700                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9701                        : null;
9702                if (topTask == null || tasks == null || tasks.size() == 0) {
9703                    Slog.w(TAG,
9704                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9705                    return;
9706                }
9707
9708                // TODO: App transition
9709                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9710
9711                // Defer the resume so resume/pausing while moving stacks is dangerous.
9712                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9713                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9714                        ANIMATE, true /* deferResume */);
9715                final int size = tasks.size();
9716                for (int i = 0; i < size; i++) {
9717                    final int id = tasks.get(i).taskId;
9718                    if (id == topTask.taskId) {
9719                        continue;
9720                    }
9721                    mStackSupervisor.moveTaskToStackLocked(id,
9722                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9723                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9724                }
9725
9726                // Because we deferred the resume, to avoid conflicts with stack switches while
9727                // resuming, we need to do it after all the tasks are moved.
9728                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9729                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9730
9731                mWindowManager.executeAppTransition();
9732            } finally {
9733                Binder.restoreCallingIdentity(ident);
9734            }
9735        }
9736    }
9737
9738    /**
9739     * Moves the input task to the docked stack.
9740     *
9741     * @param taskId Id of task to move.
9742     * @param createMode The mode the docked stack should be created in if it doesn't exist
9743     *                   already. See
9744     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9745     *                   and
9746     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9747     * @param toTop If the task and stack should be moved to the top.
9748     * @param animate Whether we should play an animation for the moving the task
9749     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9750     *                      docked stack. Pass {@code null} to use default bounds.
9751     */
9752    @Override
9753    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9754            Rect initialBounds, boolean moveHomeStackFront) {
9755        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9756        synchronized (this) {
9757            long ident = Binder.clearCallingIdentity();
9758            try {
9759                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9760                        + " to createMode=" + createMode + " toTop=" + toTop);
9761                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9762                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9763                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9764                        animate, DEFER_RESUME);
9765                if (moved) {
9766                    if (moveHomeStackFront) {
9767                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9768                    }
9769                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9770                }
9771                return moved;
9772            } finally {
9773                Binder.restoreCallingIdentity(ident);
9774            }
9775        }
9776    }
9777
9778    /**
9779     * Moves the top activity in the input stackId to the pinned stack.
9780     *
9781     * @param stackId Id of stack to move the top activity to pinned stack.
9782     * @param bounds Bounds to use for pinned stack.
9783     *
9784     * @return True if the top activity of the input stack was successfully moved to the pinned
9785     *          stack.
9786     */
9787    @Override
9788    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9789        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9790        synchronized (this) {
9791            if (!mSupportsPictureInPicture) {
9792                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9793                        + "Device doesn't support picture-in-pciture mode");
9794            }
9795
9796            long ident = Binder.clearCallingIdentity();
9797            try {
9798                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9799            } finally {
9800                Binder.restoreCallingIdentity(ident);
9801            }
9802        }
9803    }
9804
9805    @Override
9806    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9807            boolean preserveWindows, boolean animate, int animationDuration) {
9808        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9809        long ident = Binder.clearCallingIdentity();
9810        try {
9811            synchronized (this) {
9812                if (animate) {
9813                    if (stackId == PINNED_STACK_ID) {
9814                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9815                    } else {
9816                        throw new IllegalArgumentException("Stack: " + stackId
9817                                + " doesn't support animated resize.");
9818                    }
9819                } else {
9820                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9821                            null /* tempTaskInsetBounds */, preserveWindows,
9822                            allowResizeInDockedMode, !DEFER_RESUME);
9823                }
9824            }
9825        } finally {
9826            Binder.restoreCallingIdentity(ident);
9827        }
9828    }
9829
9830    @Override
9831    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9832            Rect tempDockedTaskInsetBounds,
9833            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9834        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9835                "resizeDockedStack()");
9836        long ident = Binder.clearCallingIdentity();
9837        try {
9838            synchronized (this) {
9839                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9840                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9841                        PRESERVE_WINDOWS);
9842            }
9843        } finally {
9844            Binder.restoreCallingIdentity(ident);
9845        }
9846    }
9847
9848    @Override
9849    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9850        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9851                "resizePinnedStack()");
9852        final long ident = Binder.clearCallingIdentity();
9853        try {
9854            synchronized (this) {
9855                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9856            }
9857        } finally {
9858            Binder.restoreCallingIdentity(ident);
9859        }
9860    }
9861
9862    @Override
9863    public void positionTaskInStack(int taskId, int stackId, int position) {
9864        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9865        if (stackId == HOME_STACK_ID) {
9866            throw new IllegalArgumentException(
9867                    "positionTaskInStack: Attempt to change the position of task "
9868                    + taskId + " in/to home stack");
9869        }
9870        synchronized (this) {
9871            long ident = Binder.clearCallingIdentity();
9872            try {
9873                if (DEBUG_STACK) Slog.d(TAG_STACK,
9874                        "positionTaskInStack: positioning task=" + taskId
9875                        + " in stackId=" + stackId + " at position=" + position);
9876                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9877            } finally {
9878                Binder.restoreCallingIdentity(ident);
9879            }
9880        }
9881    }
9882
9883    @Override
9884    public List<StackInfo> getAllStackInfos() {
9885        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9886        long ident = Binder.clearCallingIdentity();
9887        try {
9888            synchronized (this) {
9889                return mStackSupervisor.getAllStackInfosLocked();
9890            }
9891        } finally {
9892            Binder.restoreCallingIdentity(ident);
9893        }
9894    }
9895
9896    @Override
9897    public StackInfo getStackInfo(int stackId) {
9898        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9899        long ident = Binder.clearCallingIdentity();
9900        try {
9901            synchronized (this) {
9902                return mStackSupervisor.getStackInfoLocked(stackId);
9903            }
9904        } finally {
9905            Binder.restoreCallingIdentity(ident);
9906        }
9907    }
9908
9909    @Override
9910    public boolean isInHomeStack(int taskId) {
9911        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9912        long ident = Binder.clearCallingIdentity();
9913        try {
9914            synchronized (this) {
9915                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9916                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9917                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9918            }
9919        } finally {
9920            Binder.restoreCallingIdentity(ident);
9921        }
9922    }
9923
9924    @Override
9925    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9926        synchronized(this) {
9927            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9928        }
9929    }
9930
9931    @Override
9932    public void updateDeviceOwner(String packageName) {
9933        final int callingUid = Binder.getCallingUid();
9934        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9935            throw new SecurityException("updateDeviceOwner called from non-system process");
9936        }
9937        synchronized (this) {
9938            mDeviceOwnerName = packageName;
9939        }
9940    }
9941
9942    @Override
9943    public void updateLockTaskPackages(int userId, String[] packages) {
9944        final int callingUid = Binder.getCallingUid();
9945        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9946            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9947                    "updateLockTaskPackages()");
9948        }
9949        synchronized (this) {
9950            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9951                    Arrays.toString(packages));
9952            mLockTaskPackages.put(userId, packages);
9953            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9954        }
9955    }
9956
9957
9958    void startLockTaskModeLocked(TaskRecord task) {
9959        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9960        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9961            return;
9962        }
9963
9964        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9965        // is initiated by system after the pinning request was shown and locked mode is initiated
9966        // by an authorized app directly
9967        final int callingUid = Binder.getCallingUid();
9968        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9969        long ident = Binder.clearCallingIdentity();
9970        try {
9971            if (!isSystemInitiated) {
9972                task.mLockTaskUid = callingUid;
9973                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9974                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9975                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9976                    StatusBarManagerInternal statusBarManager =
9977                            LocalServices.getService(StatusBarManagerInternal.class);
9978                    if (statusBarManager != null) {
9979                        statusBarManager.showScreenPinningRequest(task.taskId);
9980                    }
9981                    return;
9982                }
9983
9984                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9985                if (stack == null || task != stack.topTask()) {
9986                    throw new IllegalArgumentException("Invalid task, not in foreground");
9987                }
9988            }
9989            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9990                    "Locking fully");
9991            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9992                    ActivityManager.LOCK_TASK_MODE_PINNED :
9993                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9994                    "startLockTask", true);
9995        } finally {
9996            Binder.restoreCallingIdentity(ident);
9997        }
9998    }
9999
10000    @Override
10001    public void startLockTaskMode(int taskId) {
10002        synchronized (this) {
10003            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10004            if (task != null) {
10005                startLockTaskModeLocked(task);
10006            }
10007        }
10008    }
10009
10010    @Override
10011    public void startLockTaskMode(IBinder token) {
10012        synchronized (this) {
10013            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10014            if (r == null) {
10015                return;
10016            }
10017            final TaskRecord task = r.task;
10018            if (task != null) {
10019                startLockTaskModeLocked(task);
10020            }
10021        }
10022    }
10023
10024    @Override
10025    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10026        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10027        // This makes inner call to look as if it was initiated by system.
10028        long ident = Binder.clearCallingIdentity();
10029        try {
10030            synchronized (this) {
10031                startLockTaskMode(taskId);
10032            }
10033        } finally {
10034            Binder.restoreCallingIdentity(ident);
10035        }
10036    }
10037
10038    @Override
10039    public void stopLockTaskMode() {
10040        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10041        if (lockTask == null) {
10042            // Our work here is done.
10043            return;
10044        }
10045
10046        final int callingUid = Binder.getCallingUid();
10047        final int lockTaskUid = lockTask.mLockTaskUid;
10048        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10049        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10050            // Done.
10051            return;
10052        } else {
10053            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10054            // It is possible lockTaskMode was started by the system process because
10055            // android:lockTaskMode is set to a locking value in the application manifest
10056            // instead of the app calling startLockTaskMode. In this case
10057            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10058            // {@link TaskRecord.effectiveUid} instead. Also caller with
10059            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10060            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10061                    && callingUid != lockTaskUid
10062                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10063                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10064                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10065            }
10066        }
10067        long ident = Binder.clearCallingIdentity();
10068        try {
10069            Log.d(TAG, "stopLockTaskMode");
10070            // Stop lock task
10071            synchronized (this) {
10072                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10073                        "stopLockTask", true);
10074            }
10075        } finally {
10076            Binder.restoreCallingIdentity(ident);
10077        }
10078    }
10079
10080    /**
10081     * This API should be called by SystemUI only when user perform certain action to dismiss
10082     * lock task mode. We should only dismiss pinned lock task mode in this case.
10083     */
10084    @Override
10085    public void stopSystemLockTaskMode() throws RemoteException {
10086        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10087            stopLockTaskMode();
10088        } else {
10089            mStackSupervisor.showLockTaskToast();
10090        }
10091    }
10092
10093    @Override
10094    public boolean isInLockTaskMode() {
10095        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10096    }
10097
10098    @Override
10099    public int getLockTaskModeState() {
10100        synchronized (this) {
10101            return mStackSupervisor.getLockTaskModeState();
10102        }
10103    }
10104
10105    @Override
10106    public void showLockTaskEscapeMessage(IBinder token) {
10107        synchronized (this) {
10108            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10109            if (r == null) {
10110                return;
10111            }
10112            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10113        }
10114    }
10115
10116    // =========================================================
10117    // CONTENT PROVIDERS
10118    // =========================================================
10119
10120    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10121        List<ProviderInfo> providers = null;
10122        try {
10123            providers = AppGlobals.getPackageManager()
10124                    .queryContentProviders(app.processName, app.uid,
10125                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10126                                    | MATCH_DEBUG_TRIAGED_MISSING)
10127                    .getList();
10128        } catch (RemoteException ex) {
10129        }
10130        if (DEBUG_MU) Slog.v(TAG_MU,
10131                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10132        int userId = app.userId;
10133        if (providers != null) {
10134            int N = providers.size();
10135            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10136            for (int i=0; i<N; i++) {
10137                ProviderInfo cpi =
10138                    (ProviderInfo)providers.get(i);
10139                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10140                        cpi.name, cpi.flags);
10141                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10142                    // This is a singleton provider, but a user besides the
10143                    // default user is asking to initialize a process it runs
10144                    // in...  well, no, it doesn't actually run in this process,
10145                    // it runs in the process of the default user.  Get rid of it.
10146                    providers.remove(i);
10147                    N--;
10148                    i--;
10149                    continue;
10150                }
10151
10152                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10153                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10154                if (cpr == null) {
10155                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10156                    mProviderMap.putProviderByClass(comp, cpr);
10157                }
10158                if (DEBUG_MU) Slog.v(TAG_MU,
10159                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10160                app.pubProviders.put(cpi.name, cpr);
10161                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10162                    // Don't add this if it is a platform component that is marked
10163                    // to run in multiple processes, because this is actually
10164                    // part of the framework so doesn't make sense to track as a
10165                    // separate apk in the process.
10166                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10167                            mProcessStats);
10168                }
10169                notifyPackageUse(cpi.applicationInfo.packageName,
10170                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10171            }
10172        }
10173        return providers;
10174    }
10175
10176    /**
10177     * Check if {@link ProcessRecord} has a possible chance at accessing the
10178     * given {@link ProviderInfo}. Final permission checking is always done
10179     * in {@link ContentProvider}.
10180     */
10181    private final String checkContentProviderPermissionLocked(
10182            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10183        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10184        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10185        boolean checkedGrants = false;
10186        if (checkUser) {
10187            // Looking for cross-user grants before enforcing the typical cross-users permissions
10188            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10189            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10190                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10191                    return null;
10192                }
10193                checkedGrants = true;
10194            }
10195            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10196                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10197            if (userId != tmpTargetUserId) {
10198                // When we actually went to determine the final targer user ID, this ended
10199                // up different than our initial check for the authority.  This is because
10200                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10201                // SELF.  So we need to re-check the grants again.
10202                checkedGrants = false;
10203            }
10204        }
10205        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10206                cpi.applicationInfo.uid, cpi.exported)
10207                == PackageManager.PERMISSION_GRANTED) {
10208            return null;
10209        }
10210        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10211                cpi.applicationInfo.uid, cpi.exported)
10212                == PackageManager.PERMISSION_GRANTED) {
10213            return null;
10214        }
10215
10216        PathPermission[] pps = cpi.pathPermissions;
10217        if (pps != null) {
10218            int i = pps.length;
10219            while (i > 0) {
10220                i--;
10221                PathPermission pp = pps[i];
10222                String pprperm = pp.getReadPermission();
10223                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10224                        cpi.applicationInfo.uid, cpi.exported)
10225                        == PackageManager.PERMISSION_GRANTED) {
10226                    return null;
10227                }
10228                String ppwperm = pp.getWritePermission();
10229                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10230                        cpi.applicationInfo.uid, cpi.exported)
10231                        == PackageManager.PERMISSION_GRANTED) {
10232                    return null;
10233                }
10234            }
10235        }
10236        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10237            return null;
10238        }
10239
10240        String msg;
10241        if (!cpi.exported) {
10242            msg = "Permission Denial: opening provider " + cpi.name
10243                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10244                    + ", uid=" + callingUid + ") that is not exported from uid "
10245                    + cpi.applicationInfo.uid;
10246        } else {
10247            msg = "Permission Denial: opening provider " + cpi.name
10248                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10249                    + ", uid=" + callingUid + ") requires "
10250                    + cpi.readPermission + " or " + cpi.writePermission;
10251        }
10252        Slog.w(TAG, msg);
10253        return msg;
10254    }
10255
10256    /**
10257     * Returns if the ContentProvider has granted a uri to callingUid
10258     */
10259    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10260        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10261        if (perms != null) {
10262            for (int i=perms.size()-1; i>=0; i--) {
10263                GrantUri grantUri = perms.keyAt(i);
10264                if (grantUri.sourceUserId == userId || !checkUser) {
10265                    if (matchesProvider(grantUri.uri, cpi)) {
10266                        return true;
10267                    }
10268                }
10269            }
10270        }
10271        return false;
10272    }
10273
10274    /**
10275     * Returns true if the uri authority is one of the authorities specified in the provider.
10276     */
10277    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10278        String uriAuth = uri.getAuthority();
10279        String cpiAuth = cpi.authority;
10280        if (cpiAuth.indexOf(';') == -1) {
10281            return cpiAuth.equals(uriAuth);
10282        }
10283        String[] cpiAuths = cpiAuth.split(";");
10284        int length = cpiAuths.length;
10285        for (int i = 0; i < length; i++) {
10286            if (cpiAuths[i].equals(uriAuth)) return true;
10287        }
10288        return false;
10289    }
10290
10291    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10292            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10293        if (r != null) {
10294            for (int i=0; i<r.conProviders.size(); i++) {
10295                ContentProviderConnection conn = r.conProviders.get(i);
10296                if (conn.provider == cpr) {
10297                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10298                            "Adding provider requested by "
10299                            + r.processName + " from process "
10300                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10301                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10302                    if (stable) {
10303                        conn.stableCount++;
10304                        conn.numStableIncs++;
10305                    } else {
10306                        conn.unstableCount++;
10307                        conn.numUnstableIncs++;
10308                    }
10309                    return conn;
10310                }
10311            }
10312            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10313            if (stable) {
10314                conn.stableCount = 1;
10315                conn.numStableIncs = 1;
10316            } else {
10317                conn.unstableCount = 1;
10318                conn.numUnstableIncs = 1;
10319            }
10320            cpr.connections.add(conn);
10321            r.conProviders.add(conn);
10322            startAssociationLocked(r.uid, r.processName, r.curProcState,
10323                    cpr.uid, cpr.name, cpr.info.processName);
10324            return conn;
10325        }
10326        cpr.addExternalProcessHandleLocked(externalProcessToken);
10327        return null;
10328    }
10329
10330    boolean decProviderCountLocked(ContentProviderConnection conn,
10331            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10332        if (conn != null) {
10333            cpr = conn.provider;
10334            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10335                    "Removing provider requested by "
10336                    + conn.client.processName + " from process "
10337                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10338                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10339            if (stable) {
10340                conn.stableCount--;
10341            } else {
10342                conn.unstableCount--;
10343            }
10344            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10345                cpr.connections.remove(conn);
10346                conn.client.conProviders.remove(conn);
10347                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10348                    // The client is more important than last activity -- note the time this
10349                    // is happening, so we keep the old provider process around a bit as last
10350                    // activity to avoid thrashing it.
10351                    if (cpr.proc != null) {
10352                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10353                    }
10354                }
10355                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10356                return true;
10357            }
10358            return false;
10359        }
10360        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10361        return false;
10362    }
10363
10364    private void checkTime(long startTime, String where) {
10365        long now = SystemClock.uptimeMillis();
10366        if ((now-startTime) > 50) {
10367            // If we are taking more than 50ms, log about it.
10368            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10369        }
10370    }
10371
10372    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10373            String name, IBinder token, boolean stable, int userId) {
10374        ContentProviderRecord cpr;
10375        ContentProviderConnection conn = null;
10376        ProviderInfo cpi = null;
10377
10378        synchronized(this) {
10379            long startTime = SystemClock.uptimeMillis();
10380
10381            ProcessRecord r = null;
10382            if (caller != null) {
10383                r = getRecordForAppLocked(caller);
10384                if (r == null) {
10385                    throw new SecurityException(
10386                            "Unable to find app for caller " + caller
10387                          + " (pid=" + Binder.getCallingPid()
10388                          + ") when getting content provider " + name);
10389                }
10390            }
10391
10392            boolean checkCrossUser = true;
10393
10394            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10395
10396            // First check if this content provider has been published...
10397            cpr = mProviderMap.getProviderByName(name, userId);
10398            // If that didn't work, check if it exists for user 0 and then
10399            // verify that it's a singleton provider before using it.
10400            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10401                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10402                if (cpr != null) {
10403                    cpi = cpr.info;
10404                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10405                            cpi.name, cpi.flags)
10406                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10407                        userId = UserHandle.USER_SYSTEM;
10408                        checkCrossUser = false;
10409                    } else {
10410                        cpr = null;
10411                        cpi = null;
10412                    }
10413                }
10414            }
10415
10416            boolean providerRunning = cpr != null;
10417            if (providerRunning) {
10418                cpi = cpr.info;
10419                String msg;
10420                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10421                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10422                        != null) {
10423                    throw new SecurityException(msg);
10424                }
10425                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10426
10427                if (r != null && cpr.canRunHere(r)) {
10428                    // This provider has been published or is in the process
10429                    // of being published...  but it is also allowed to run
10430                    // in the caller's process, so don't make a connection
10431                    // and just let the caller instantiate its own instance.
10432                    ContentProviderHolder holder = cpr.newHolder(null);
10433                    // don't give caller the provider object, it needs
10434                    // to make its own.
10435                    holder.provider = null;
10436                    return holder;
10437                }
10438
10439                final long origId = Binder.clearCallingIdentity();
10440
10441                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10442
10443                // In this case the provider instance already exists, so we can
10444                // return it right away.
10445                conn = incProviderCountLocked(r, cpr, token, stable);
10446                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10447                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10448                        // If this is a perceptible app accessing the provider,
10449                        // make sure to count it as being accessed and thus
10450                        // back up on the LRU list.  This is good because
10451                        // content providers are often expensive to start.
10452                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10453                        updateLruProcessLocked(cpr.proc, false, null);
10454                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10455                    }
10456                }
10457
10458                if (cpr.proc != null) {
10459                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10460                    boolean success = updateOomAdjLocked(cpr.proc);
10461                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10462                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10463                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10464                    // NOTE: there is still a race here where a signal could be
10465                    // pending on the process even though we managed to update its
10466                    // adj level.  Not sure what to do about this, but at least
10467                    // the race is now smaller.
10468                    if (!success) {
10469                        // Uh oh...  it looks like the provider's process
10470                        // has been killed on us.  We need to wait for a new
10471                        // process to be started, and make sure its death
10472                        // doesn't kill our process.
10473                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10474                                + " is crashing; detaching " + r);
10475                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10476                        checkTime(startTime, "getContentProviderImpl: before appDied");
10477                        appDiedLocked(cpr.proc);
10478                        checkTime(startTime, "getContentProviderImpl: after appDied");
10479                        if (!lastRef) {
10480                            // This wasn't the last ref our process had on
10481                            // the provider...  we have now been killed, bail.
10482                            return null;
10483                        }
10484                        providerRunning = false;
10485                        conn = null;
10486                    }
10487                }
10488
10489                Binder.restoreCallingIdentity(origId);
10490            }
10491
10492            if (!providerRunning) {
10493                try {
10494                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10495                    cpi = AppGlobals.getPackageManager().
10496                        resolveContentProvider(name,
10497                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10498                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10499                } catch (RemoteException ex) {
10500                }
10501                if (cpi == null) {
10502                    return null;
10503                }
10504                // If the provider is a singleton AND
10505                // (it's a call within the same user || the provider is a
10506                // privileged app)
10507                // Then allow connecting to the singleton provider
10508                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10509                        cpi.name, cpi.flags)
10510                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10511                if (singleton) {
10512                    userId = UserHandle.USER_SYSTEM;
10513                }
10514                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10515                checkTime(startTime, "getContentProviderImpl: got app info for user");
10516
10517                String msg;
10518                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10519                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10520                        != null) {
10521                    throw new SecurityException(msg);
10522                }
10523                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10524
10525                if (!mProcessesReady
10526                        && !cpi.processName.equals("system")) {
10527                    // If this content provider does not run in the system
10528                    // process, and the system is not yet ready to run other
10529                    // processes, then fail fast instead of hanging.
10530                    throw new IllegalArgumentException(
10531                            "Attempt to launch content provider before system ready");
10532                }
10533
10534                // Make sure that the user who owns this provider is running.  If not,
10535                // we don't want to allow it to run.
10536                if (!mUserController.isUserRunningLocked(userId, 0)) {
10537                    Slog.w(TAG, "Unable to launch app "
10538                            + cpi.applicationInfo.packageName + "/"
10539                            + cpi.applicationInfo.uid + " for provider "
10540                            + name + ": user " + userId + " is stopped");
10541                    return null;
10542                }
10543
10544                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10545                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10546                cpr = mProviderMap.getProviderByClass(comp, userId);
10547                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10548                final boolean firstClass = cpr == null;
10549                if (firstClass) {
10550                    final long ident = Binder.clearCallingIdentity();
10551
10552                    // If permissions need a review before any of the app components can run,
10553                    // we return no provider and launch a review activity if the calling app
10554                    // is in the foreground.
10555                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10556                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10557                            return null;
10558                        }
10559                    }
10560
10561                    try {
10562                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10563                        ApplicationInfo ai =
10564                            AppGlobals.getPackageManager().
10565                                getApplicationInfo(
10566                                        cpi.applicationInfo.packageName,
10567                                        STOCK_PM_FLAGS, userId);
10568                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10569                        if (ai == null) {
10570                            Slog.w(TAG, "No package info for content provider "
10571                                    + cpi.name);
10572                            return null;
10573                        }
10574                        ai = getAppInfoForUser(ai, userId);
10575                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10576                    } catch (RemoteException ex) {
10577                        // pm is in same process, this will never happen.
10578                    } finally {
10579                        Binder.restoreCallingIdentity(ident);
10580                    }
10581                }
10582
10583                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10584
10585                if (r != null && cpr.canRunHere(r)) {
10586                    // If this is a multiprocess provider, then just return its
10587                    // info and allow the caller to instantiate it.  Only do
10588                    // this if the provider is the same user as the caller's
10589                    // process, or can run as root (so can be in any process).
10590                    return cpr.newHolder(null);
10591                }
10592
10593                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10594                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10595                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10596
10597                // This is single process, and our app is now connecting to it.
10598                // See if we are already in the process of launching this
10599                // provider.
10600                final int N = mLaunchingProviders.size();
10601                int i;
10602                for (i = 0; i < N; i++) {
10603                    if (mLaunchingProviders.get(i) == cpr) {
10604                        break;
10605                    }
10606                }
10607
10608                // If the provider is not already being launched, then get it
10609                // started.
10610                if (i >= N) {
10611                    final long origId = Binder.clearCallingIdentity();
10612
10613                    try {
10614                        // Content provider is now in use, its package can't be stopped.
10615                        try {
10616                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10617                            AppGlobals.getPackageManager().setPackageStoppedState(
10618                                    cpr.appInfo.packageName, false, userId);
10619                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10620                        } catch (RemoteException e) {
10621                        } catch (IllegalArgumentException e) {
10622                            Slog.w(TAG, "Failed trying to unstop package "
10623                                    + cpr.appInfo.packageName + ": " + e);
10624                        }
10625
10626                        // Use existing process if already started
10627                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10628                        ProcessRecord proc = getProcessRecordLocked(
10629                                cpi.processName, cpr.appInfo.uid, false);
10630                        if (proc != null && proc.thread != null) {
10631                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10632                                    "Installing in existing process " + proc);
10633                            if (!proc.pubProviders.containsKey(cpi.name)) {
10634                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10635                                proc.pubProviders.put(cpi.name, cpr);
10636                                try {
10637                                    proc.thread.scheduleInstallProvider(cpi);
10638                                } catch (RemoteException e) {
10639                                }
10640                            }
10641                        } else {
10642                            checkTime(startTime, "getContentProviderImpl: before start process");
10643                            proc = startProcessLocked(cpi.processName,
10644                                    cpr.appInfo, false, 0, "content provider",
10645                                    new ComponentName(cpi.applicationInfo.packageName,
10646                                            cpi.name), false, false, false);
10647                            checkTime(startTime, "getContentProviderImpl: after start process");
10648                            if (proc == null) {
10649                                Slog.w(TAG, "Unable to launch app "
10650                                        + cpi.applicationInfo.packageName + "/"
10651                                        + cpi.applicationInfo.uid + " for provider "
10652                                        + name + ": process is bad");
10653                                return null;
10654                            }
10655                        }
10656                        cpr.launchingApp = proc;
10657                        mLaunchingProviders.add(cpr);
10658                    } finally {
10659                        Binder.restoreCallingIdentity(origId);
10660                    }
10661                }
10662
10663                checkTime(startTime, "getContentProviderImpl: updating data structures");
10664
10665                // Make sure the provider is published (the same provider class
10666                // may be published under multiple names).
10667                if (firstClass) {
10668                    mProviderMap.putProviderByClass(comp, cpr);
10669                }
10670
10671                mProviderMap.putProviderByName(name, cpr);
10672                conn = incProviderCountLocked(r, cpr, token, stable);
10673                if (conn != null) {
10674                    conn.waiting = true;
10675                }
10676            }
10677            checkTime(startTime, "getContentProviderImpl: done!");
10678        }
10679
10680        // Wait for the provider to be published...
10681        synchronized (cpr) {
10682            while (cpr.provider == null) {
10683                if (cpr.launchingApp == null) {
10684                    Slog.w(TAG, "Unable to launch app "
10685                            + cpi.applicationInfo.packageName + "/"
10686                            + cpi.applicationInfo.uid + " for provider "
10687                            + name + ": launching app became null");
10688                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10689                            UserHandle.getUserId(cpi.applicationInfo.uid),
10690                            cpi.applicationInfo.packageName,
10691                            cpi.applicationInfo.uid, name);
10692                    return null;
10693                }
10694                try {
10695                    if (DEBUG_MU) Slog.v(TAG_MU,
10696                            "Waiting to start provider " + cpr
10697                            + " launchingApp=" + cpr.launchingApp);
10698                    if (conn != null) {
10699                        conn.waiting = true;
10700                    }
10701                    cpr.wait();
10702                } catch (InterruptedException ex) {
10703                } finally {
10704                    if (conn != null) {
10705                        conn.waiting = false;
10706                    }
10707                }
10708            }
10709        }
10710        return cpr != null ? cpr.newHolder(conn) : null;
10711    }
10712
10713    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10714            ProcessRecord r, final int userId) {
10715        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10716                cpi.packageName, userId)) {
10717
10718            final boolean callerForeground = r == null || r.setSchedGroup
10719                    != ProcessList.SCHED_GROUP_BACKGROUND;
10720
10721            // Show a permission review UI only for starting from a foreground app
10722            if (!callerForeground) {
10723                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10724                        + cpi.packageName + " requires a permissions review");
10725                return false;
10726            }
10727
10728            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10729            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10730                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10731            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10732
10733            if (DEBUG_PERMISSIONS_REVIEW) {
10734                Slog.i(TAG, "u" + userId + " Launching permission review "
10735                        + "for package " + cpi.packageName);
10736            }
10737
10738            final UserHandle userHandle = new UserHandle(userId);
10739            mHandler.post(new Runnable() {
10740                @Override
10741                public void run() {
10742                    mContext.startActivityAsUser(intent, userHandle);
10743                }
10744            });
10745
10746            return false;
10747        }
10748
10749        return true;
10750    }
10751
10752    PackageManagerInternal getPackageManagerInternalLocked() {
10753        if (mPackageManagerInt == null) {
10754            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10755        }
10756        return mPackageManagerInt;
10757    }
10758
10759    @Override
10760    public final ContentProviderHolder getContentProvider(
10761            IApplicationThread caller, String name, int userId, boolean stable) {
10762        enforceNotIsolatedCaller("getContentProvider");
10763        if (caller == null) {
10764            String msg = "null IApplicationThread when getting content provider "
10765                    + name;
10766            Slog.w(TAG, msg);
10767            throw new SecurityException(msg);
10768        }
10769        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10770        // with cross-user grant.
10771        return getContentProviderImpl(caller, name, null, stable, userId);
10772    }
10773
10774    public ContentProviderHolder getContentProviderExternal(
10775            String name, int userId, IBinder token) {
10776        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10777            "Do not have permission in call getContentProviderExternal()");
10778        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10779                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10780        return getContentProviderExternalUnchecked(name, token, userId);
10781    }
10782
10783    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10784            IBinder token, int userId) {
10785        return getContentProviderImpl(null, name, token, true, userId);
10786    }
10787
10788    /**
10789     * Drop a content provider from a ProcessRecord's bookkeeping
10790     */
10791    public void removeContentProvider(IBinder connection, boolean stable) {
10792        enforceNotIsolatedCaller("removeContentProvider");
10793        long ident = Binder.clearCallingIdentity();
10794        try {
10795            synchronized (this) {
10796                ContentProviderConnection conn;
10797                try {
10798                    conn = (ContentProviderConnection)connection;
10799                } catch (ClassCastException e) {
10800                    String msg ="removeContentProvider: " + connection
10801                            + " not a ContentProviderConnection";
10802                    Slog.w(TAG, msg);
10803                    throw new IllegalArgumentException(msg);
10804                }
10805                if (conn == null) {
10806                    throw new NullPointerException("connection is null");
10807                }
10808                if (decProviderCountLocked(conn, null, null, stable)) {
10809                    updateOomAdjLocked();
10810                }
10811            }
10812        } finally {
10813            Binder.restoreCallingIdentity(ident);
10814        }
10815    }
10816
10817    public void removeContentProviderExternal(String name, IBinder token) {
10818        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10819            "Do not have permission in call removeContentProviderExternal()");
10820        int userId = UserHandle.getCallingUserId();
10821        long ident = Binder.clearCallingIdentity();
10822        try {
10823            removeContentProviderExternalUnchecked(name, token, userId);
10824        } finally {
10825            Binder.restoreCallingIdentity(ident);
10826        }
10827    }
10828
10829    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10830        synchronized (this) {
10831            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10832            if(cpr == null) {
10833                //remove from mProvidersByClass
10834                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10835                return;
10836            }
10837
10838            //update content provider record entry info
10839            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10840            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10841            if (localCpr.hasExternalProcessHandles()) {
10842                if (localCpr.removeExternalProcessHandleLocked(token)) {
10843                    updateOomAdjLocked();
10844                } else {
10845                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10846                            + " with no external reference for token: "
10847                            + token + ".");
10848                }
10849            } else {
10850                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10851                        + " with no external references.");
10852            }
10853        }
10854    }
10855
10856    public final void publishContentProviders(IApplicationThread caller,
10857            List<ContentProviderHolder> providers) {
10858        if (providers == null) {
10859            return;
10860        }
10861
10862        enforceNotIsolatedCaller("publishContentProviders");
10863        synchronized (this) {
10864            final ProcessRecord r = getRecordForAppLocked(caller);
10865            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10866            if (r == null) {
10867                throw new SecurityException(
10868                        "Unable to find app for caller " + caller
10869                      + " (pid=" + Binder.getCallingPid()
10870                      + ") when publishing content providers");
10871            }
10872
10873            final long origId = Binder.clearCallingIdentity();
10874
10875            final int N = providers.size();
10876            for (int i = 0; i < N; i++) {
10877                ContentProviderHolder src = providers.get(i);
10878                if (src == null || src.info == null || src.provider == null) {
10879                    continue;
10880                }
10881                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10882                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10883                if (dst != null) {
10884                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10885                    mProviderMap.putProviderByClass(comp, dst);
10886                    String names[] = dst.info.authority.split(";");
10887                    for (int j = 0; j < names.length; j++) {
10888                        mProviderMap.putProviderByName(names[j], dst);
10889                    }
10890
10891                    int launchingCount = mLaunchingProviders.size();
10892                    int j;
10893                    boolean wasInLaunchingProviders = false;
10894                    for (j = 0; j < launchingCount; j++) {
10895                        if (mLaunchingProviders.get(j) == dst) {
10896                            mLaunchingProviders.remove(j);
10897                            wasInLaunchingProviders = true;
10898                            j--;
10899                            launchingCount--;
10900                        }
10901                    }
10902                    if (wasInLaunchingProviders) {
10903                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10904                    }
10905                    synchronized (dst) {
10906                        dst.provider = src.provider;
10907                        dst.proc = r;
10908                        dst.notifyAll();
10909                    }
10910                    updateOomAdjLocked(r);
10911                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10912                            src.info.authority);
10913                }
10914            }
10915
10916            Binder.restoreCallingIdentity(origId);
10917        }
10918    }
10919
10920    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10921        ContentProviderConnection conn;
10922        try {
10923            conn = (ContentProviderConnection)connection;
10924        } catch (ClassCastException e) {
10925            String msg ="refContentProvider: " + connection
10926                    + " not a ContentProviderConnection";
10927            Slog.w(TAG, msg);
10928            throw new IllegalArgumentException(msg);
10929        }
10930        if (conn == null) {
10931            throw new NullPointerException("connection is null");
10932        }
10933
10934        synchronized (this) {
10935            if (stable > 0) {
10936                conn.numStableIncs += stable;
10937            }
10938            stable = conn.stableCount + stable;
10939            if (stable < 0) {
10940                throw new IllegalStateException("stableCount < 0: " + stable);
10941            }
10942
10943            if (unstable > 0) {
10944                conn.numUnstableIncs += unstable;
10945            }
10946            unstable = conn.unstableCount + unstable;
10947            if (unstable < 0) {
10948                throw new IllegalStateException("unstableCount < 0: " + unstable);
10949            }
10950
10951            if ((stable+unstable) <= 0) {
10952                throw new IllegalStateException("ref counts can't go to zero here: stable="
10953                        + stable + " unstable=" + unstable);
10954            }
10955            conn.stableCount = stable;
10956            conn.unstableCount = unstable;
10957            return !conn.dead;
10958        }
10959    }
10960
10961    public void unstableProviderDied(IBinder connection) {
10962        ContentProviderConnection conn;
10963        try {
10964            conn = (ContentProviderConnection)connection;
10965        } catch (ClassCastException e) {
10966            String msg ="refContentProvider: " + connection
10967                    + " not a ContentProviderConnection";
10968            Slog.w(TAG, msg);
10969            throw new IllegalArgumentException(msg);
10970        }
10971        if (conn == null) {
10972            throw new NullPointerException("connection is null");
10973        }
10974
10975        // Safely retrieve the content provider associated with the connection.
10976        IContentProvider provider;
10977        synchronized (this) {
10978            provider = conn.provider.provider;
10979        }
10980
10981        if (provider == null) {
10982            // Um, yeah, we're way ahead of you.
10983            return;
10984        }
10985
10986        // Make sure the caller is being honest with us.
10987        if (provider.asBinder().pingBinder()) {
10988            // Er, no, still looks good to us.
10989            synchronized (this) {
10990                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10991                        + " says " + conn + " died, but we don't agree");
10992                return;
10993            }
10994        }
10995
10996        // Well look at that!  It's dead!
10997        synchronized (this) {
10998            if (conn.provider.provider != provider) {
10999                // But something changed...  good enough.
11000                return;
11001            }
11002
11003            ProcessRecord proc = conn.provider.proc;
11004            if (proc == null || proc.thread == null) {
11005                // Seems like the process is already cleaned up.
11006                return;
11007            }
11008
11009            // As far as we're concerned, this is just like receiving a
11010            // death notification...  just a bit prematurely.
11011            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11012                    + ") early provider death");
11013            final long ident = Binder.clearCallingIdentity();
11014            try {
11015                appDiedLocked(proc);
11016            } finally {
11017                Binder.restoreCallingIdentity(ident);
11018            }
11019        }
11020    }
11021
11022    @Override
11023    public void appNotRespondingViaProvider(IBinder connection) {
11024        enforceCallingPermission(
11025                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11026
11027        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11028        if (conn == null) {
11029            Slog.w(TAG, "ContentProviderConnection is null");
11030            return;
11031        }
11032
11033        final ProcessRecord host = conn.provider.proc;
11034        if (host == null) {
11035            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11036            return;
11037        }
11038
11039        mHandler.post(new Runnable() {
11040            @Override
11041            public void run() {
11042                mAppErrors.appNotResponding(host, null, null, false,
11043                        "ContentProvider not responding");
11044            }
11045        });
11046    }
11047
11048    public final void installSystemProviders() {
11049        List<ProviderInfo> providers;
11050        synchronized (this) {
11051            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11052            providers = generateApplicationProvidersLocked(app);
11053            if (providers != null) {
11054                for (int i=providers.size()-1; i>=0; i--) {
11055                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11056                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11057                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11058                                + ": not system .apk");
11059                        providers.remove(i);
11060                    }
11061                }
11062            }
11063        }
11064        if (providers != null) {
11065            mSystemThread.installSystemProviders(providers);
11066        }
11067
11068        mCoreSettingsObserver = new CoreSettingsObserver(this);
11069        mFontScaleSettingObserver = new FontScaleSettingObserver();
11070
11071        //mUsageStatsService.monitorPackages();
11072    }
11073
11074    private void startPersistentApps(int matchFlags) {
11075        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11076
11077        synchronized (this) {
11078            try {
11079                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11080                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11081                for (ApplicationInfo app : apps) {
11082                    if (!"android".equals(app.packageName)) {
11083                        addAppLocked(app, false, null /* ABI override */);
11084                    }
11085                }
11086            } catch (RemoteException ex) {
11087            }
11088        }
11089    }
11090
11091    /**
11092     * When a user is unlocked, we need to install encryption-unaware providers
11093     * belonging to any running apps.
11094     */
11095    private void installEncryptionUnawareProviders(int userId) {
11096        // We're only interested in providers that are encryption unaware, and
11097        // we don't care about uninstalled apps, since there's no way they're
11098        // running at this point.
11099        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11100
11101        synchronized (this) {
11102            final int NP = mProcessNames.getMap().size();
11103            for (int ip = 0; ip < NP; ip++) {
11104                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11105                final int NA = apps.size();
11106                for (int ia = 0; ia < NA; ia++) {
11107                    final ProcessRecord app = apps.valueAt(ia);
11108                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11109
11110                    final int NG = app.pkgList.size();
11111                    for (int ig = 0; ig < NG; ig++) {
11112                        try {
11113                            final String pkgName = app.pkgList.keyAt(ig);
11114                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11115                                    .getPackageInfo(pkgName, matchFlags, userId);
11116                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11117                                for (ProviderInfo provInfo : pkgInfo.providers) {
11118                                    Log.v(TAG, "Installing " + provInfo);
11119                                    app.thread.scheduleInstallProvider(provInfo);
11120                                }
11121                            }
11122                        } catch (RemoteException ignored) {
11123                        }
11124                    }
11125                }
11126            }
11127        }
11128    }
11129
11130    /**
11131     * Allows apps to retrieve the MIME type of a URI.
11132     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11133     * users, then it does not need permission to access the ContentProvider.
11134     * Either, it needs cross-user uri grants.
11135     *
11136     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11137     *
11138     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11139     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11140     */
11141    public String getProviderMimeType(Uri uri, int userId) {
11142        enforceNotIsolatedCaller("getProviderMimeType");
11143        final String name = uri.getAuthority();
11144        int callingUid = Binder.getCallingUid();
11145        int callingPid = Binder.getCallingPid();
11146        long ident = 0;
11147        boolean clearedIdentity = false;
11148        synchronized (this) {
11149            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11150        }
11151        if (canClearIdentity(callingPid, callingUid, userId)) {
11152            clearedIdentity = true;
11153            ident = Binder.clearCallingIdentity();
11154        }
11155        ContentProviderHolder holder = null;
11156        try {
11157            holder = getContentProviderExternalUnchecked(name, null, userId);
11158            if (holder != null) {
11159                return holder.provider.getType(uri);
11160            }
11161        } catch (RemoteException e) {
11162            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11163            return null;
11164        } finally {
11165            // We need to clear the identity to call removeContentProviderExternalUnchecked
11166            if (!clearedIdentity) {
11167                ident = Binder.clearCallingIdentity();
11168            }
11169            try {
11170                if (holder != null) {
11171                    removeContentProviderExternalUnchecked(name, null, userId);
11172                }
11173            } finally {
11174                Binder.restoreCallingIdentity(ident);
11175            }
11176        }
11177
11178        return null;
11179    }
11180
11181    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11182        if (UserHandle.getUserId(callingUid) == userId) {
11183            return true;
11184        }
11185        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11186                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11187                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11188                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11189                return true;
11190        }
11191        return false;
11192    }
11193
11194    // =========================================================
11195    // GLOBAL MANAGEMENT
11196    // =========================================================
11197
11198    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11199            boolean isolated, int isolatedUid) {
11200        String proc = customProcess != null ? customProcess : info.processName;
11201        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11202        final int userId = UserHandle.getUserId(info.uid);
11203        int uid = info.uid;
11204        if (isolated) {
11205            if (isolatedUid == 0) {
11206                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11207                while (true) {
11208                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11209                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11210                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11211                    }
11212                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11213                    mNextIsolatedProcessUid++;
11214                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11215                        // No process for this uid, use it.
11216                        break;
11217                    }
11218                    stepsLeft--;
11219                    if (stepsLeft <= 0) {
11220                        return null;
11221                    }
11222                }
11223            } else {
11224                // Special case for startIsolatedProcess (internal only), where
11225                // the uid of the isolated process is specified by the caller.
11226                uid = isolatedUid;
11227            }
11228        }
11229        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11230        if (!mBooted && !mBooting
11231                && userId == UserHandle.USER_SYSTEM
11232                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11233            r.persistent = true;
11234        }
11235        addProcessNameLocked(r);
11236        return r;
11237    }
11238
11239    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11240            String abiOverride) {
11241        ProcessRecord app;
11242        if (!isolated) {
11243            app = getProcessRecordLocked(info.processName, info.uid, true);
11244        } else {
11245            app = null;
11246        }
11247
11248        if (app == null) {
11249            app = newProcessRecordLocked(info, null, isolated, 0);
11250            updateLruProcessLocked(app, false, null);
11251            updateOomAdjLocked();
11252        }
11253
11254        // This package really, really can not be stopped.
11255        try {
11256            AppGlobals.getPackageManager().setPackageStoppedState(
11257                    info.packageName, false, UserHandle.getUserId(app.uid));
11258        } catch (RemoteException e) {
11259        } catch (IllegalArgumentException e) {
11260            Slog.w(TAG, "Failed trying to unstop package "
11261                    + info.packageName + ": " + e);
11262        }
11263
11264        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11265            app.persistent = true;
11266            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11267        }
11268        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11269            mPersistentStartingProcesses.add(app);
11270            startProcessLocked(app, "added application", app.processName, abiOverride,
11271                    null /* entryPoint */, null /* entryPointArgs */);
11272        }
11273
11274        return app;
11275    }
11276
11277    public void unhandledBack() {
11278        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11279                "unhandledBack()");
11280
11281        synchronized(this) {
11282            final long origId = Binder.clearCallingIdentity();
11283            try {
11284                getFocusedStack().unhandledBackLocked();
11285            } finally {
11286                Binder.restoreCallingIdentity(origId);
11287            }
11288        }
11289    }
11290
11291    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11292        enforceNotIsolatedCaller("openContentUri");
11293        final int userId = UserHandle.getCallingUserId();
11294        String name = uri.getAuthority();
11295        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11296        ParcelFileDescriptor pfd = null;
11297        if (cph != null) {
11298            // We record the binder invoker's uid in thread-local storage before
11299            // going to the content provider to open the file.  Later, in the code
11300            // that handles all permissions checks, we look for this uid and use
11301            // that rather than the Activity Manager's own uid.  The effect is that
11302            // we do the check against the caller's permissions even though it looks
11303            // to the content provider like the Activity Manager itself is making
11304            // the request.
11305            Binder token = new Binder();
11306            sCallerIdentity.set(new Identity(
11307                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11308            try {
11309                pfd = cph.provider.openFile(null, uri, "r", null, token);
11310            } catch (FileNotFoundException e) {
11311                // do nothing; pfd will be returned null
11312            } finally {
11313                // Ensure that whatever happens, we clean up the identity state
11314                sCallerIdentity.remove();
11315                // Ensure we're done with the provider.
11316                removeContentProviderExternalUnchecked(name, null, userId);
11317            }
11318        } else {
11319            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11320        }
11321        return pfd;
11322    }
11323
11324    // Actually is sleeping or shutting down or whatever else in the future
11325    // is an inactive state.
11326    public boolean isSleepingOrShuttingDown() {
11327        return isSleeping() || mShuttingDown;
11328    }
11329
11330    public boolean isSleeping() {
11331        return mSleeping;
11332    }
11333
11334    void onWakefulnessChanged(int wakefulness) {
11335        synchronized(this) {
11336            mWakefulness = wakefulness;
11337            updateSleepIfNeededLocked();
11338        }
11339    }
11340
11341    void finishRunningVoiceLocked() {
11342        if (mRunningVoice != null) {
11343            mRunningVoice = null;
11344            mVoiceWakeLock.release();
11345            updateSleepIfNeededLocked();
11346        }
11347    }
11348
11349    void startTimeTrackingFocusedActivityLocked() {
11350        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11351            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11352        }
11353    }
11354
11355    void updateSleepIfNeededLocked() {
11356        if (mSleeping && !shouldSleepLocked()) {
11357            mSleeping = false;
11358            startTimeTrackingFocusedActivityLocked();
11359            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11360            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11361            updateOomAdjLocked();
11362        } else if (!mSleeping && shouldSleepLocked()) {
11363            mSleeping = true;
11364            if (mCurAppTimeTracker != null) {
11365                mCurAppTimeTracker.stop();
11366            }
11367            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11368            mStackSupervisor.goingToSleepLocked();
11369            updateOomAdjLocked();
11370
11371            // Initialize the wake times of all processes.
11372            checkExcessivePowerUsageLocked(false);
11373            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11374            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11375            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11376        }
11377    }
11378
11379    private boolean shouldSleepLocked() {
11380        // Resume applications while running a voice interactor.
11381        if (mRunningVoice != null) {
11382            return false;
11383        }
11384
11385        // TODO: Transform the lock screen state into a sleep token instead.
11386        switch (mWakefulness) {
11387            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11388            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11389            case PowerManagerInternal.WAKEFULNESS_DOZING:
11390                // Pause applications whenever the lock screen is shown or any sleep
11391                // tokens have been acquired.
11392                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11393            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11394            default:
11395                // If we're asleep then pause applications unconditionally.
11396                return true;
11397        }
11398    }
11399
11400    /** Pokes the task persister. */
11401    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11402        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11403    }
11404
11405    /** Notifies all listeners when the task stack has changed. */
11406    void notifyTaskStackChangedLocked() {
11407        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11408        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11409        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11410        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11411    }
11412
11413    /** Notifies all listeners when an Activity is pinned. */
11414    void notifyActivityPinnedLocked() {
11415        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11416        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11417    }
11418
11419    /**
11420     * Notifies all listeners when an attempt was made to start an an activity that is already
11421     * running in the pinned stack and the activity was not actually started, but the task is
11422     * either brought to the front or a new Intent is delivered to it.
11423     */
11424    void notifyPinnedActivityRestartAttemptLocked() {
11425        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11426        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11427    }
11428
11429    /** Notifies all listeners when the pinned stack animation ends. */
11430    @Override
11431    public void notifyPinnedStackAnimationEnded() {
11432        synchronized (this) {
11433            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11434            mHandler.obtainMessage(
11435                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11436        }
11437    }
11438
11439    @Override
11440    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11441        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11442    }
11443
11444    @Override
11445    public boolean shutdown(int timeout) {
11446        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11447                != PackageManager.PERMISSION_GRANTED) {
11448            throw new SecurityException("Requires permission "
11449                    + android.Manifest.permission.SHUTDOWN);
11450        }
11451
11452        boolean timedout = false;
11453
11454        synchronized(this) {
11455            mShuttingDown = true;
11456            updateEventDispatchingLocked();
11457            timedout = mStackSupervisor.shutdownLocked(timeout);
11458        }
11459
11460        mAppOpsService.shutdown();
11461        if (mUsageStatsService != null) {
11462            mUsageStatsService.prepareShutdown();
11463        }
11464        mBatteryStatsService.shutdown();
11465        synchronized (this) {
11466            mProcessStats.shutdownLocked();
11467            notifyTaskPersisterLocked(null, true);
11468        }
11469
11470        return timedout;
11471    }
11472
11473    public final void activitySlept(IBinder token) {
11474        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11475
11476        final long origId = Binder.clearCallingIdentity();
11477
11478        synchronized (this) {
11479            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11480            if (r != null) {
11481                mStackSupervisor.activitySleptLocked(r);
11482            }
11483        }
11484
11485        Binder.restoreCallingIdentity(origId);
11486    }
11487
11488    private String lockScreenShownToString() {
11489        switch (mLockScreenShown) {
11490            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11491            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11492            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11493            default: return "Unknown=" + mLockScreenShown;
11494        }
11495    }
11496
11497    void logLockScreen(String msg) {
11498        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11499                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11500                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11501                + " mSleeping=" + mSleeping);
11502    }
11503
11504    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11505        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11506        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11507        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11508            boolean wasRunningVoice = mRunningVoice != null;
11509            mRunningVoice = session;
11510            if (!wasRunningVoice) {
11511                mVoiceWakeLock.acquire();
11512                updateSleepIfNeededLocked();
11513            }
11514        }
11515    }
11516
11517    private void updateEventDispatchingLocked() {
11518        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11519    }
11520
11521    public void setLockScreenShown(boolean showing, boolean occluded) {
11522        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11523                != PackageManager.PERMISSION_GRANTED) {
11524            throw new SecurityException("Requires permission "
11525                    + android.Manifest.permission.DEVICE_POWER);
11526        }
11527
11528        synchronized(this) {
11529            long ident = Binder.clearCallingIdentity();
11530            try {
11531                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11532                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11533                if (showing && occluded) {
11534                    // The lock screen is currently showing, but is occluded by a window that can
11535                    // show on top of the lock screen. In this can we want to dismiss the docked
11536                    // stack since it will be complicated/risky to try to put the activity on top
11537                    // of the lock screen in the right fullscreen configuration.
11538                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11539                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11540                }
11541
11542                updateSleepIfNeededLocked();
11543            } finally {
11544                Binder.restoreCallingIdentity(ident);
11545            }
11546        }
11547    }
11548
11549    @Override
11550    public void notifyLockedProfile(@UserIdInt int userId) {
11551        try {
11552            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11553                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11554            }
11555        } catch (RemoteException ex) {
11556            throw new SecurityException("Fail to check is caller a privileged app", ex);
11557        }
11558
11559        synchronized (this) {
11560            if (mStackSupervisor.isUserLockedProfile(userId)) {
11561                final long ident = Binder.clearCallingIdentity();
11562                try {
11563                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11564                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11565                        // If there is no device lock, we will show the profile's credential page.
11566                        mActivityStarter.showConfirmDeviceCredential(userId);
11567                    } else {
11568                        // Showing launcher to avoid user entering credential twice.
11569                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11570                    }
11571                } finally {
11572                    Binder.restoreCallingIdentity(ident);
11573                }
11574            }
11575        }
11576    }
11577
11578    @Override
11579    public void startConfirmDeviceCredentialIntent(Intent intent) {
11580        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11581        synchronized (this) {
11582            final long ident = Binder.clearCallingIdentity();
11583            try {
11584                mActivityStarter.startConfirmCredentialIntent(intent);
11585            } finally {
11586                Binder.restoreCallingIdentity(ident);
11587            }
11588        }
11589    }
11590
11591    @Override
11592    public void stopAppSwitches() {
11593        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11594                != PackageManager.PERMISSION_GRANTED) {
11595            throw new SecurityException("viewquires permission "
11596                    + android.Manifest.permission.STOP_APP_SWITCHES);
11597        }
11598
11599        synchronized(this) {
11600            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11601                    + APP_SWITCH_DELAY_TIME;
11602            mDidAppSwitch = false;
11603            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11604            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11605            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11606        }
11607    }
11608
11609    public void resumeAppSwitches() {
11610        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11611                != PackageManager.PERMISSION_GRANTED) {
11612            throw new SecurityException("Requires permission "
11613                    + android.Manifest.permission.STOP_APP_SWITCHES);
11614        }
11615
11616        synchronized(this) {
11617            // Note that we don't execute any pending app switches... we will
11618            // let those wait until either the timeout, or the next start
11619            // activity request.
11620            mAppSwitchesAllowedTime = 0;
11621        }
11622    }
11623
11624    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11625            int callingPid, int callingUid, String name) {
11626        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11627            return true;
11628        }
11629
11630        int perm = checkComponentPermission(
11631                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11632                sourceUid, -1, true);
11633        if (perm == PackageManager.PERMISSION_GRANTED) {
11634            return true;
11635        }
11636
11637        // If the actual IPC caller is different from the logical source, then
11638        // also see if they are allowed to control app switches.
11639        if (callingUid != -1 && callingUid != sourceUid) {
11640            perm = checkComponentPermission(
11641                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11642                    callingUid, -1, true);
11643            if (perm == PackageManager.PERMISSION_GRANTED) {
11644                return true;
11645            }
11646        }
11647
11648        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11649        return false;
11650    }
11651
11652    public void setDebugApp(String packageName, boolean waitForDebugger,
11653            boolean persistent) {
11654        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11655                "setDebugApp()");
11656
11657        long ident = Binder.clearCallingIdentity();
11658        try {
11659            // Note that this is not really thread safe if there are multiple
11660            // callers into it at the same time, but that's not a situation we
11661            // care about.
11662            if (persistent) {
11663                final ContentResolver resolver = mContext.getContentResolver();
11664                Settings.Global.putString(
11665                    resolver, Settings.Global.DEBUG_APP,
11666                    packageName);
11667                Settings.Global.putInt(
11668                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11669                    waitForDebugger ? 1 : 0);
11670            }
11671
11672            synchronized (this) {
11673                if (!persistent) {
11674                    mOrigDebugApp = mDebugApp;
11675                    mOrigWaitForDebugger = mWaitForDebugger;
11676                }
11677                mDebugApp = packageName;
11678                mWaitForDebugger = waitForDebugger;
11679                mDebugTransient = !persistent;
11680                if (packageName != null) {
11681                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11682                            false, UserHandle.USER_ALL, "set debug app");
11683                }
11684            }
11685        } finally {
11686            Binder.restoreCallingIdentity(ident);
11687        }
11688    }
11689
11690    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11691        synchronized (this) {
11692            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11693            if (!isDebuggable) {
11694                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11695                    throw new SecurityException("Process not debuggable: " + app.packageName);
11696                }
11697            }
11698
11699            mTrackAllocationApp = processName;
11700        }
11701    }
11702
11703    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11704        synchronized (this) {
11705            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11706            if (!isDebuggable) {
11707                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11708                    throw new SecurityException("Process not debuggable: " + app.packageName);
11709                }
11710            }
11711            mProfileApp = processName;
11712            mProfileFile = profilerInfo.profileFile;
11713            if (mProfileFd != null) {
11714                try {
11715                    mProfileFd.close();
11716                } catch (IOException e) {
11717                }
11718                mProfileFd = null;
11719            }
11720            mProfileFd = profilerInfo.profileFd;
11721            mSamplingInterval = profilerInfo.samplingInterval;
11722            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11723            mProfileType = 0;
11724        }
11725    }
11726
11727    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11728        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11729        if (!isDebuggable) {
11730            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11731                throw new SecurityException("Process not debuggable: " + app.packageName);
11732            }
11733        }
11734        mNativeDebuggingApp = processName;
11735    }
11736
11737    @Override
11738    public void setAlwaysFinish(boolean enabled) {
11739        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11740                "setAlwaysFinish()");
11741
11742        long ident = Binder.clearCallingIdentity();
11743        try {
11744            Settings.Global.putInt(
11745                    mContext.getContentResolver(),
11746                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11747
11748            synchronized (this) {
11749                mAlwaysFinishActivities = enabled;
11750            }
11751        } finally {
11752            Binder.restoreCallingIdentity(ident);
11753        }
11754    }
11755
11756    @Override
11757    public void setLenientBackgroundCheck(boolean enabled) {
11758        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11759                "setLenientBackgroundCheck()");
11760
11761        long ident = Binder.clearCallingIdentity();
11762        try {
11763            Settings.Global.putInt(
11764                    mContext.getContentResolver(),
11765                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11766
11767            synchronized (this) {
11768                mLenientBackgroundCheck = enabled;
11769            }
11770        } finally {
11771            Binder.restoreCallingIdentity(ident);
11772        }
11773    }
11774
11775    @Override
11776    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11777        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11778                "setActivityController()");
11779        synchronized (this) {
11780            mController = controller;
11781            mControllerIsAMonkey = imAMonkey;
11782            Watchdog.getInstance().setActivityController(controller);
11783        }
11784    }
11785
11786    @Override
11787    public void setUserIsMonkey(boolean userIsMonkey) {
11788        synchronized (this) {
11789            synchronized (mPidsSelfLocked) {
11790                final int callingPid = Binder.getCallingPid();
11791                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11792                if (precessRecord == null) {
11793                    throw new SecurityException("Unknown process: " + callingPid);
11794                }
11795                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11796                    throw new SecurityException("Only an instrumentation process "
11797                            + "with a UiAutomation can call setUserIsMonkey");
11798                }
11799            }
11800            mUserIsMonkey = userIsMonkey;
11801        }
11802    }
11803
11804    @Override
11805    public boolean isUserAMonkey() {
11806        synchronized (this) {
11807            // If there is a controller also implies the user is a monkey.
11808            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11809        }
11810    }
11811
11812    public void requestBugReport(int bugreportType) {
11813        String service = null;
11814        switch (bugreportType) {
11815            case ActivityManager.BUGREPORT_OPTION_FULL:
11816                service = "bugreport";
11817                break;
11818            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11819                service = "bugreportplus";
11820                break;
11821            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11822                service = "bugreportremote";
11823                break;
11824        }
11825        if (service == null) {
11826            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11827                    + bugreportType);
11828        }
11829        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11830        SystemProperties.set("ctl.start", service);
11831    }
11832
11833    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11834        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11835    }
11836
11837    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11838        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11839            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11840        }
11841        return KEY_DISPATCHING_TIMEOUT;
11842    }
11843
11844    @Override
11845    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11846        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11847                != PackageManager.PERMISSION_GRANTED) {
11848            throw new SecurityException("Requires permission "
11849                    + android.Manifest.permission.FILTER_EVENTS);
11850        }
11851        ProcessRecord proc;
11852        long timeout;
11853        synchronized (this) {
11854            synchronized (mPidsSelfLocked) {
11855                proc = mPidsSelfLocked.get(pid);
11856            }
11857            timeout = getInputDispatchingTimeoutLocked(proc);
11858        }
11859
11860        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11861            return -1;
11862        }
11863
11864        return timeout;
11865    }
11866
11867    /**
11868     * Handle input dispatching timeouts.
11869     * Returns whether input dispatching should be aborted or not.
11870     */
11871    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11872            final ActivityRecord activity, final ActivityRecord parent,
11873            final boolean aboveSystem, String reason) {
11874        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11875                != PackageManager.PERMISSION_GRANTED) {
11876            throw new SecurityException("Requires permission "
11877                    + android.Manifest.permission.FILTER_EVENTS);
11878        }
11879
11880        final String annotation;
11881        if (reason == null) {
11882            annotation = "Input dispatching timed out";
11883        } else {
11884            annotation = "Input dispatching timed out (" + reason + ")";
11885        }
11886
11887        if (proc != null) {
11888            synchronized (this) {
11889                if (proc.debugging) {
11890                    return false;
11891                }
11892
11893                if (mDidDexOpt) {
11894                    // Give more time since we were dexopting.
11895                    mDidDexOpt = false;
11896                    return false;
11897                }
11898
11899                if (proc.instrumentationClass != null) {
11900                    Bundle info = new Bundle();
11901                    info.putString("shortMsg", "keyDispatchingTimedOut");
11902                    info.putString("longMsg", annotation);
11903                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11904                    return true;
11905                }
11906            }
11907            mHandler.post(new Runnable() {
11908                @Override
11909                public void run() {
11910                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11911                }
11912            });
11913        }
11914
11915        return true;
11916    }
11917
11918    @Override
11919    public Bundle getAssistContextExtras(int requestType) {
11920        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11921                null, null, true /* focused */, true /* newSessionId */,
11922                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11923        if (pae == null) {
11924            return null;
11925        }
11926        synchronized (pae) {
11927            while (!pae.haveResult) {
11928                try {
11929                    pae.wait();
11930                } catch (InterruptedException e) {
11931                }
11932            }
11933        }
11934        synchronized (this) {
11935            buildAssistBundleLocked(pae, pae.result);
11936            mPendingAssistExtras.remove(pae);
11937            mUiHandler.removeCallbacks(pae);
11938        }
11939        return pae.extras;
11940    }
11941
11942    @Override
11943    public boolean isAssistDataAllowedOnCurrentActivity() {
11944        int userId;
11945        synchronized (this) {
11946            userId = mUserController.getCurrentUserIdLocked();
11947            ActivityRecord activity = getFocusedStack().topActivity();
11948            if (activity == null) {
11949                return false;
11950            }
11951            userId = activity.userId;
11952        }
11953        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11954                Context.DEVICE_POLICY_SERVICE);
11955        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11956    }
11957
11958    @Override
11959    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11960        long ident = Binder.clearCallingIdentity();
11961        try {
11962            synchronized (this) {
11963                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11964                ActivityRecord top = getFocusedStack().topActivity();
11965                if (top != caller) {
11966                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11967                            + " is not current top " + top);
11968                    return false;
11969                }
11970                if (!top.nowVisible) {
11971                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11972                            + " is not visible");
11973                    return false;
11974                }
11975            }
11976            AssistUtils utils = new AssistUtils(mContext);
11977            return utils.showSessionForActiveService(args,
11978                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11979        } finally {
11980            Binder.restoreCallingIdentity(ident);
11981        }
11982    }
11983
11984    @Override
11985    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11986            Bundle receiverExtras,
11987            IBinder activityToken, boolean focused, boolean newSessionId) {
11988        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11989                activityToken, focused, newSessionId,
11990                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11991                != null;
11992    }
11993
11994    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11995            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
11996            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
11997        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11998                "enqueueAssistContext()");
11999        synchronized (this) {
12000            ActivityRecord activity = getFocusedStack().topActivity();
12001            if (activity == null) {
12002                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12003                return null;
12004            }
12005            if (activity.app == null || activity.app.thread == null) {
12006                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12007                return null;
12008            }
12009            if (focused) {
12010                if (activityToken != null) {
12011                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12012                    if (activity != caller) {
12013                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12014                                + " is not current top " + activity);
12015                        return null;
12016                    }
12017                }
12018            } else {
12019                activity = ActivityRecord.forTokenLocked(activityToken);
12020                if (activity == null) {
12021                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12022                            + " couldn't be found");
12023                    return null;
12024                }
12025            }
12026
12027            PendingAssistExtras pae;
12028            Bundle extras = new Bundle();
12029            if (args != null) {
12030                extras.putAll(args);
12031            }
12032            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12033            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12034            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12035                    userHandle);
12036            // Increment the sessionId if necessary
12037            if (newSessionId) {
12038                mViSessionId++;
12039            }
12040            try {
12041                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12042                        requestType, mViSessionId);
12043                mPendingAssistExtras.add(pae);
12044                mUiHandler.postDelayed(pae, timeout);
12045            } catch (RemoteException e) {
12046                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12047                return null;
12048            }
12049            return pae;
12050        }
12051    }
12052
12053    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12054        IResultReceiver receiver;
12055        synchronized (this) {
12056            mPendingAssistExtras.remove(pae);
12057            receiver = pae.receiver;
12058        }
12059        if (receiver != null) {
12060            // Caller wants result sent back to them.
12061            Bundle sendBundle = new Bundle();
12062            // At least return the receiver extras
12063            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12064                    pae.receiverExtras);
12065            try {
12066                pae.receiver.send(0, sendBundle);
12067            } catch (RemoteException e) {
12068            }
12069        }
12070    }
12071
12072    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12073        if (result != null) {
12074            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12075        }
12076        if (pae.hint != null) {
12077            pae.extras.putBoolean(pae.hint, true);
12078        }
12079    }
12080
12081    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12082            AssistContent content, Uri referrer) {
12083        PendingAssistExtras pae = (PendingAssistExtras)token;
12084        synchronized (pae) {
12085            pae.result = extras;
12086            pae.structure = structure;
12087            pae.content = content;
12088            if (referrer != null) {
12089                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12090            }
12091            pae.haveResult = true;
12092            pae.notifyAll();
12093            if (pae.intent == null && pae.receiver == null) {
12094                // Caller is just waiting for the result.
12095                return;
12096            }
12097        }
12098
12099        // We are now ready to launch the assist activity.
12100        IResultReceiver sendReceiver = null;
12101        Bundle sendBundle = null;
12102        synchronized (this) {
12103            buildAssistBundleLocked(pae, extras);
12104            boolean exists = mPendingAssistExtras.remove(pae);
12105            mUiHandler.removeCallbacks(pae);
12106            if (!exists) {
12107                // Timed out.
12108                return;
12109            }
12110            if ((sendReceiver=pae.receiver) != null) {
12111                // Caller wants result sent back to them.
12112                sendBundle = new Bundle();
12113                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12114                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12115                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12116                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12117                        pae.receiverExtras);
12118            }
12119        }
12120        if (sendReceiver != null) {
12121            try {
12122                sendReceiver.send(0, sendBundle);
12123            } catch (RemoteException e) {
12124            }
12125            return;
12126        }
12127
12128        long ident = Binder.clearCallingIdentity();
12129        try {
12130            pae.intent.replaceExtras(pae.extras);
12131            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12132                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12133                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12134            closeSystemDialogs("assist");
12135            try {
12136                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12137            } catch (ActivityNotFoundException e) {
12138                Slog.w(TAG, "No activity to handle assist action.", e);
12139            }
12140        } finally {
12141            Binder.restoreCallingIdentity(ident);
12142        }
12143    }
12144
12145    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12146            Bundle args) {
12147        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12148                true /* focused */, true /* newSessionId */,
12149                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12150    }
12151
12152    public void registerProcessObserver(IProcessObserver observer) {
12153        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12154                "registerProcessObserver()");
12155        synchronized (this) {
12156            mProcessObservers.register(observer);
12157        }
12158    }
12159
12160    @Override
12161    public void unregisterProcessObserver(IProcessObserver observer) {
12162        synchronized (this) {
12163            mProcessObservers.unregister(observer);
12164        }
12165    }
12166
12167    @Override
12168    public void registerUidObserver(IUidObserver observer, int which) {
12169        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12170                "registerUidObserver()");
12171        synchronized (this) {
12172            mUidObservers.register(observer, which);
12173        }
12174    }
12175
12176    @Override
12177    public void unregisterUidObserver(IUidObserver observer) {
12178        synchronized (this) {
12179            mUidObservers.unregister(observer);
12180        }
12181    }
12182
12183    @Override
12184    public boolean convertFromTranslucent(IBinder token) {
12185        final long origId = Binder.clearCallingIdentity();
12186        try {
12187            synchronized (this) {
12188                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12189                if (r == null) {
12190                    return false;
12191                }
12192                final boolean translucentChanged = r.changeWindowTranslucency(true);
12193                if (translucentChanged) {
12194                    r.task.stack.releaseBackgroundResources(r);
12195                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12196                }
12197                mWindowManager.setAppFullscreen(token, true);
12198                return translucentChanged;
12199            }
12200        } finally {
12201            Binder.restoreCallingIdentity(origId);
12202        }
12203    }
12204
12205    @Override
12206    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12207        final long origId = Binder.clearCallingIdentity();
12208        try {
12209            synchronized (this) {
12210                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12211                if (r == null) {
12212                    return false;
12213                }
12214                int index = r.task.mActivities.lastIndexOf(r);
12215                if (index > 0) {
12216                    ActivityRecord under = r.task.mActivities.get(index - 1);
12217                    under.returningOptions = options;
12218                }
12219                final boolean translucentChanged = r.changeWindowTranslucency(false);
12220                if (translucentChanged) {
12221                    r.task.stack.convertActivityToTranslucent(r);
12222                }
12223                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12224                mWindowManager.setAppFullscreen(token, false);
12225                return translucentChanged;
12226            }
12227        } finally {
12228            Binder.restoreCallingIdentity(origId);
12229        }
12230    }
12231
12232    @Override
12233    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12234        final long origId = Binder.clearCallingIdentity();
12235        try {
12236            synchronized (this) {
12237                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12238                if (r != null) {
12239                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12240                }
12241            }
12242            return false;
12243        } finally {
12244            Binder.restoreCallingIdentity(origId);
12245        }
12246    }
12247
12248    @Override
12249    public boolean isBackgroundVisibleBehind(IBinder token) {
12250        final long origId = Binder.clearCallingIdentity();
12251        try {
12252            synchronized (this) {
12253                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12254                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12255                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12256                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12257                return visible;
12258            }
12259        } finally {
12260            Binder.restoreCallingIdentity(origId);
12261        }
12262    }
12263
12264    @Override
12265    public ActivityOptions getActivityOptions(IBinder token) {
12266        final long origId = Binder.clearCallingIdentity();
12267        try {
12268            synchronized (this) {
12269                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12270                if (r != null) {
12271                    final ActivityOptions activityOptions = r.pendingOptions;
12272                    r.pendingOptions = null;
12273                    return activityOptions;
12274                }
12275                return null;
12276            }
12277        } finally {
12278            Binder.restoreCallingIdentity(origId);
12279        }
12280    }
12281
12282    @Override
12283    public void setImmersive(IBinder token, boolean immersive) {
12284        synchronized(this) {
12285            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12286            if (r == null) {
12287                throw new IllegalArgumentException();
12288            }
12289            r.immersive = immersive;
12290
12291            // update associated state if we're frontmost
12292            if (r == mFocusedActivity) {
12293                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12294                applyUpdateLockStateLocked(r);
12295            }
12296        }
12297    }
12298
12299    @Override
12300    public boolean isImmersive(IBinder token) {
12301        synchronized (this) {
12302            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12303            if (r == null) {
12304                throw new IllegalArgumentException();
12305            }
12306            return r.immersive;
12307        }
12308    }
12309
12310    @Override
12311    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12312        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12313            throw new UnsupportedOperationException("VR mode not supported on this device!");
12314        }
12315
12316        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12317
12318        ActivityRecord r;
12319        synchronized (this) {
12320            r = ActivityRecord.isInStackLocked(token);
12321        }
12322
12323        if (r == null) {
12324            throw new IllegalArgumentException();
12325        }
12326
12327        int err;
12328        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12329                VrManagerInternal.NO_ERROR) {
12330            return err;
12331        }
12332
12333        synchronized(this) {
12334            r.requestedVrComponent = (enabled) ? packageName : null;
12335
12336            // Update associated state if this activity is currently focused
12337            if (r == mFocusedActivity) {
12338                applyUpdateVrModeLocked(r);
12339            }
12340            return 0;
12341        }
12342    }
12343
12344    @Override
12345    public boolean isVrModePackageEnabled(ComponentName packageName) {
12346        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12347            throw new UnsupportedOperationException("VR mode not supported on this device!");
12348        }
12349
12350        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12351
12352        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12353                VrManagerInternal.NO_ERROR;
12354    }
12355
12356    public boolean isTopActivityImmersive() {
12357        enforceNotIsolatedCaller("startActivity");
12358        synchronized (this) {
12359            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12360            return (r != null) ? r.immersive : false;
12361        }
12362    }
12363
12364    @Override
12365    public boolean isTopOfTask(IBinder token) {
12366        synchronized (this) {
12367            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12368            if (r == null) {
12369                throw new IllegalArgumentException();
12370            }
12371            return r.task.getTopActivity() == r;
12372        }
12373    }
12374
12375    public final void enterSafeMode() {
12376        synchronized(this) {
12377            // It only makes sense to do this before the system is ready
12378            // and started launching other packages.
12379            if (!mSystemReady) {
12380                try {
12381                    AppGlobals.getPackageManager().enterSafeMode();
12382                } catch (RemoteException e) {
12383                }
12384            }
12385
12386            mSafeMode = true;
12387        }
12388    }
12389
12390    public final void showSafeModeOverlay() {
12391        View v = LayoutInflater.from(mContext).inflate(
12392                com.android.internal.R.layout.safe_mode, null);
12393        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12394        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12395        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12396        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12397        lp.gravity = Gravity.BOTTOM | Gravity.START;
12398        lp.format = v.getBackground().getOpacity();
12399        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12400                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12401        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12402        ((WindowManager)mContext.getSystemService(
12403                Context.WINDOW_SERVICE)).addView(v, lp);
12404    }
12405
12406    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12407        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12408            return;
12409        }
12410        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12411        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12412        synchronized (stats) {
12413            if (mBatteryStatsService.isOnBattery()) {
12414                mBatteryStatsService.enforceCallingPermission();
12415                int MY_UID = Binder.getCallingUid();
12416                final int uid;
12417                if (sender == null) {
12418                    uid = sourceUid;
12419                } else {
12420                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12421                }
12422                BatteryStatsImpl.Uid.Pkg pkg =
12423                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12424                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12425                pkg.noteWakeupAlarmLocked(tag);
12426            }
12427        }
12428    }
12429
12430    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12431        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12432            return;
12433        }
12434        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12435        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12436        synchronized (stats) {
12437            mBatteryStatsService.enforceCallingPermission();
12438            int MY_UID = Binder.getCallingUid();
12439            final int uid;
12440            if (sender == null) {
12441                uid = sourceUid;
12442            } else {
12443                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12444            }
12445            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12446        }
12447    }
12448
12449    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12450        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12451            return;
12452        }
12453        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12454        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12455        synchronized (stats) {
12456            mBatteryStatsService.enforceCallingPermission();
12457            int MY_UID = Binder.getCallingUid();
12458            final int uid;
12459            if (sender == null) {
12460                uid = sourceUid;
12461            } else {
12462                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12463            }
12464            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12465        }
12466    }
12467
12468    public boolean killPids(int[] pids, String pReason, boolean secure) {
12469        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12470            throw new SecurityException("killPids only available to the system");
12471        }
12472        String reason = (pReason == null) ? "Unknown" : pReason;
12473        // XXX Note: don't acquire main activity lock here, because the window
12474        // manager calls in with its locks held.
12475
12476        boolean killed = false;
12477        synchronized (mPidsSelfLocked) {
12478            int worstType = 0;
12479            for (int i=0; i<pids.length; i++) {
12480                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12481                if (proc != null) {
12482                    int type = proc.setAdj;
12483                    if (type > worstType) {
12484                        worstType = type;
12485                    }
12486                }
12487            }
12488
12489            // If the worst oom_adj is somewhere in the cached proc LRU range,
12490            // then constrain it so we will kill all cached procs.
12491            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12492                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12493                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12494            }
12495
12496            // If this is not a secure call, don't let it kill processes that
12497            // are important.
12498            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12499                worstType = ProcessList.SERVICE_ADJ;
12500            }
12501
12502            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12503            for (int i=0; i<pids.length; i++) {
12504                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12505                if (proc == null) {
12506                    continue;
12507                }
12508                int adj = proc.setAdj;
12509                if (adj >= worstType && !proc.killedByAm) {
12510                    proc.kill(reason, true);
12511                    killed = true;
12512                }
12513            }
12514        }
12515        return killed;
12516    }
12517
12518    @Override
12519    public void killUid(int appId, int userId, String reason) {
12520        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12521        synchronized (this) {
12522            final long identity = Binder.clearCallingIdentity();
12523            try {
12524                killPackageProcessesLocked(null, appId, userId,
12525                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12526                        reason != null ? reason : "kill uid");
12527            } finally {
12528                Binder.restoreCallingIdentity(identity);
12529            }
12530        }
12531    }
12532
12533    @Override
12534    public boolean killProcessesBelowForeground(String reason) {
12535        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12536            throw new SecurityException("killProcessesBelowForeground() only available to system");
12537        }
12538
12539        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12540    }
12541
12542    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12543        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12544            throw new SecurityException("killProcessesBelowAdj() only available to system");
12545        }
12546
12547        boolean killed = false;
12548        synchronized (mPidsSelfLocked) {
12549            final int size = mPidsSelfLocked.size();
12550            for (int i = 0; i < size; i++) {
12551                final int pid = mPidsSelfLocked.keyAt(i);
12552                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12553                if (proc == null) continue;
12554
12555                final int adj = proc.setAdj;
12556                if (adj > belowAdj && !proc.killedByAm) {
12557                    proc.kill(reason, true);
12558                    killed = true;
12559                }
12560            }
12561        }
12562        return killed;
12563    }
12564
12565    @Override
12566    public void hang(final IBinder who, boolean allowRestart) {
12567        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12568                != PackageManager.PERMISSION_GRANTED) {
12569            throw new SecurityException("Requires permission "
12570                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12571        }
12572
12573        final IBinder.DeathRecipient death = new DeathRecipient() {
12574            @Override
12575            public void binderDied() {
12576                synchronized (this) {
12577                    notifyAll();
12578                }
12579            }
12580        };
12581
12582        try {
12583            who.linkToDeath(death, 0);
12584        } catch (RemoteException e) {
12585            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12586            return;
12587        }
12588
12589        synchronized (this) {
12590            Watchdog.getInstance().setAllowRestart(allowRestart);
12591            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12592            synchronized (death) {
12593                while (who.isBinderAlive()) {
12594                    try {
12595                        death.wait();
12596                    } catch (InterruptedException e) {
12597                    }
12598                }
12599            }
12600            Watchdog.getInstance().setAllowRestart(true);
12601        }
12602    }
12603
12604    @Override
12605    public void restart() {
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        Log.i(TAG, "Sending shutdown broadcast...");
12613
12614        BroadcastReceiver br = new BroadcastReceiver() {
12615            @Override public void onReceive(Context context, Intent intent) {
12616                // Now the broadcast is done, finish up the low-level shutdown.
12617                Log.i(TAG, "Shutting down activity manager...");
12618                shutdown(10000);
12619                Log.i(TAG, "Shutdown complete, restarting!");
12620                Process.killProcess(Process.myPid());
12621                System.exit(10);
12622            }
12623        };
12624
12625        // First send the high-level shut down broadcast.
12626        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12627        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12628        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12629        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12630        mContext.sendOrderedBroadcastAsUser(intent,
12631                UserHandle.ALL, null, br, mHandler, 0, null, null);
12632        */
12633        br.onReceive(mContext, intent);
12634    }
12635
12636    private long getLowRamTimeSinceIdle(long now) {
12637        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12638    }
12639
12640    @Override
12641    public void performIdleMaintenance() {
12642        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12643                != PackageManager.PERMISSION_GRANTED) {
12644            throw new SecurityException("Requires permission "
12645                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12646        }
12647
12648        synchronized (this) {
12649            final long now = SystemClock.uptimeMillis();
12650            final long timeSinceLastIdle = now - mLastIdleTime;
12651            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12652            mLastIdleTime = now;
12653            mLowRamTimeSinceLastIdle = 0;
12654            if (mLowRamStartTime != 0) {
12655                mLowRamStartTime = now;
12656            }
12657
12658            StringBuilder sb = new StringBuilder(128);
12659            sb.append("Idle maintenance over ");
12660            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12661            sb.append(" low RAM for ");
12662            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12663            Slog.i(TAG, sb.toString());
12664
12665            // If at least 1/3 of our time since the last idle period has been spent
12666            // with RAM low, then we want to kill processes.
12667            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12668
12669            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12670                ProcessRecord proc = mLruProcesses.get(i);
12671                if (proc.notCachedSinceIdle) {
12672                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12673                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12674                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12675                        if (doKilling && proc.initialIdlePss != 0
12676                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12677                            sb = new StringBuilder(128);
12678                            sb.append("Kill");
12679                            sb.append(proc.processName);
12680                            sb.append(" in idle maint: pss=");
12681                            sb.append(proc.lastPss);
12682                            sb.append(", swapPss=");
12683                            sb.append(proc.lastSwapPss);
12684                            sb.append(", initialPss=");
12685                            sb.append(proc.initialIdlePss);
12686                            sb.append(", period=");
12687                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12688                            sb.append(", lowRamPeriod=");
12689                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12690                            Slog.wtfQuiet(TAG, sb.toString());
12691                            proc.kill("idle maint (pss " + proc.lastPss
12692                                    + " from " + proc.initialIdlePss + ")", true);
12693                        }
12694                    }
12695                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12696                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12697                    proc.notCachedSinceIdle = true;
12698                    proc.initialIdlePss = 0;
12699                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12700                            mTestPssMode, isSleeping(), now);
12701                }
12702            }
12703
12704            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12705            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12706        }
12707    }
12708
12709    @Override
12710    public void sendIdleJobTrigger() {
12711        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12712                != PackageManager.PERMISSION_GRANTED) {
12713            throw new SecurityException("Requires permission "
12714                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12715        }
12716
12717        final long ident = Binder.clearCallingIdentity();
12718        try {
12719            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12720                    .setPackage("android")
12721                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12722            broadcastIntent(null, intent, null, null, 0, null, null, null,
12723                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12724        } finally {
12725            Binder.restoreCallingIdentity(ident);
12726        }
12727    }
12728
12729    private void retrieveSettings() {
12730        final ContentResolver resolver = mContext.getContentResolver();
12731        final boolean freeformWindowManagement =
12732                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12733                        || Settings.Global.getInt(
12734                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12735        final boolean supportsPictureInPicture =
12736                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12737
12738        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12739        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12740        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12741        final boolean alwaysFinishActivities =
12742                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12743        final boolean lenientBackgroundCheck =
12744                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12745        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12746        final boolean forceResizable = Settings.Global.getInt(
12747                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12748        // Transfer any global setting for forcing RTL layout, into a System Property
12749        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12750
12751        final Configuration configuration = new Configuration();
12752        Settings.System.getConfiguration(resolver, configuration);
12753        if (forceRtl) {
12754            // This will take care of setting the correct layout direction flags
12755            configuration.setLayoutDirection(configuration.locale);
12756        }
12757
12758        synchronized (this) {
12759            mDebugApp = mOrigDebugApp = debugApp;
12760            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12761            mAlwaysFinishActivities = alwaysFinishActivities;
12762            mLenientBackgroundCheck = lenientBackgroundCheck;
12763            mForceResizableActivities = forceResizable;
12764            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12765            if (supportsMultiWindow || forceResizable) {
12766                mSupportsMultiWindow = true;
12767                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12768                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12769            } else {
12770                mSupportsMultiWindow = false;
12771                mSupportsFreeformWindowManagement = false;
12772                mSupportsPictureInPicture = false;
12773            }
12774            // This happens before any activities are started, so we can
12775            // change mConfiguration in-place.
12776            updateConfigurationLocked(configuration, null, true);
12777            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12778                    "Initial config: " + mConfiguration);
12779
12780            // Load resources only after the current configuration has been set.
12781            final Resources res = mContext.getResources();
12782            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12783            mThumbnailWidth = res.getDimensionPixelSize(
12784                    com.android.internal.R.dimen.thumbnail_width);
12785            mThumbnailHeight = res.getDimensionPixelSize(
12786                    com.android.internal.R.dimen.thumbnail_height);
12787            mFullscreenThumbnailScale = res.getFraction(
12788                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12789            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12790                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12791            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12792                    com.android.internal.R.string.config_appsNotReportingCrashes));
12793        }
12794    }
12795
12796    public boolean testIsSystemReady() {
12797        // no need to synchronize(this) just to read & return the value
12798        return mSystemReady;
12799    }
12800
12801    public void systemReady(final Runnable goingCallback) {
12802        synchronized(this) {
12803            if (mSystemReady) {
12804                // If we're done calling all the receivers, run the next "boot phase" passed in
12805                // by the SystemServer
12806                if (goingCallback != null) {
12807                    goingCallback.run();
12808                }
12809                return;
12810            }
12811
12812            mLocalDeviceIdleController
12813                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12814
12815            // Make sure we have the current profile info, since it is needed for security checks.
12816            mUserController.onSystemReady();
12817            mRecentTasks.onSystemReadyLocked();
12818            mAppOpsService.systemReady();
12819            mSystemReady = true;
12820        }
12821
12822        ArrayList<ProcessRecord> procsToKill = null;
12823        synchronized(mPidsSelfLocked) {
12824            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12825                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12826                if (!isAllowedWhileBooting(proc.info)){
12827                    if (procsToKill == null) {
12828                        procsToKill = new ArrayList<ProcessRecord>();
12829                    }
12830                    procsToKill.add(proc);
12831                }
12832            }
12833        }
12834
12835        synchronized(this) {
12836            if (procsToKill != null) {
12837                for (int i=procsToKill.size()-1; i>=0; i--) {
12838                    ProcessRecord proc = procsToKill.get(i);
12839                    Slog.i(TAG, "Removing system update proc: " + proc);
12840                    removeProcessLocked(proc, true, false, "system update done");
12841                }
12842            }
12843
12844            // Now that we have cleaned up any update processes, we
12845            // are ready to start launching real processes and know that
12846            // we won't trample on them any more.
12847            mProcessesReady = true;
12848        }
12849
12850        Slog.i(TAG, "System now ready");
12851        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12852            SystemClock.uptimeMillis());
12853
12854        synchronized(this) {
12855            // Make sure we have no pre-ready processes sitting around.
12856
12857            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12858                ResolveInfo ri = mContext.getPackageManager()
12859                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12860                                STOCK_PM_FLAGS);
12861                CharSequence errorMsg = null;
12862                if (ri != null) {
12863                    ActivityInfo ai = ri.activityInfo;
12864                    ApplicationInfo app = ai.applicationInfo;
12865                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12866                        mTopAction = Intent.ACTION_FACTORY_TEST;
12867                        mTopData = null;
12868                        mTopComponent = new ComponentName(app.packageName,
12869                                ai.name);
12870                    } else {
12871                        errorMsg = mContext.getResources().getText(
12872                                com.android.internal.R.string.factorytest_not_system);
12873                    }
12874                } else {
12875                    errorMsg = mContext.getResources().getText(
12876                            com.android.internal.R.string.factorytest_no_action);
12877                }
12878                if (errorMsg != null) {
12879                    mTopAction = null;
12880                    mTopData = null;
12881                    mTopComponent = null;
12882                    Message msg = Message.obtain();
12883                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12884                    msg.getData().putCharSequence("msg", errorMsg);
12885                    mUiHandler.sendMessage(msg);
12886                }
12887            }
12888        }
12889
12890        retrieveSettings();
12891        final int currentUserId;
12892        synchronized (this) {
12893            currentUserId = mUserController.getCurrentUserIdLocked();
12894            readGrantedUriPermissionsLocked();
12895        }
12896
12897        if (goingCallback != null) goingCallback.run();
12898
12899        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12900                Integer.toString(currentUserId), currentUserId);
12901        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12902                Integer.toString(currentUserId), currentUserId);
12903        mSystemServiceManager.startUser(currentUserId);
12904
12905        synchronized (this) {
12906            // Only start up encryption-aware persistent apps; once user is
12907            // unlocked we'll come back around and start unaware apps
12908            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12909
12910            // Start up initial activity.
12911            mBooting = true;
12912            // Enable home activity for system user, so that the system can always boot. We don't
12913            // do this when the system user is not setup since the setup wizard should be the one
12914            // to handle home activity in this case.
12915            if (UserManager.isSplitSystemUser() &&
12916                    Settings.Secure.getInt(mContext.getContentResolver(),
12917                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
12918                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12919                try {
12920                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12921                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12922                            UserHandle.USER_SYSTEM);
12923                } catch (RemoteException e) {
12924                    throw e.rethrowAsRuntimeException();
12925                }
12926            }
12927            startHomeActivityLocked(currentUserId, "systemReady");
12928
12929            try {
12930                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12931                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12932                            + " data partition or your device will be unstable.");
12933                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12934                }
12935            } catch (RemoteException e) {
12936            }
12937
12938            if (!Build.isBuildConsistent()) {
12939                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12940                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12941            }
12942
12943            long ident = Binder.clearCallingIdentity();
12944            try {
12945                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12946                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12947                        | Intent.FLAG_RECEIVER_FOREGROUND);
12948                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12949                broadcastIntentLocked(null, null, intent,
12950                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12951                        null, false, false, MY_PID, Process.SYSTEM_UID,
12952                        currentUserId);
12953                intent = new Intent(Intent.ACTION_USER_STARTING);
12954                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12955                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12956                broadcastIntentLocked(null, null, intent,
12957                        null, new IIntentReceiver.Stub() {
12958                            @Override
12959                            public void performReceive(Intent intent, int resultCode, String data,
12960                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12961                                    throws RemoteException {
12962                            }
12963                        }, 0, null, null,
12964                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12965                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12966            } catch (Throwable t) {
12967                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12968            } finally {
12969                Binder.restoreCallingIdentity(ident);
12970            }
12971            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12972            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12973        }
12974    }
12975
12976    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12977        synchronized (this) {
12978            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12979        }
12980    }
12981
12982    void skipCurrentReceiverLocked(ProcessRecord app) {
12983        for (BroadcastQueue queue : mBroadcastQueues) {
12984            queue.skipCurrentReceiverLocked(app);
12985        }
12986    }
12987
12988    /**
12989     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12990     * The application process will exit immediately after this call returns.
12991     * @param app object of the crashing app, null for the system server
12992     * @param crashInfo describing the exception
12993     */
12994    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12995        ProcessRecord r = findAppProcess(app, "Crash");
12996        final String processName = app == null ? "system_server"
12997                : (r == null ? "unknown" : r.processName);
12998
12999        handleApplicationCrashInner("crash", r, processName, crashInfo);
13000    }
13001
13002    /* Native crash reporting uses this inner version because it needs to be somewhat
13003     * decoupled from the AM-managed cleanup lifecycle
13004     */
13005    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13006            ApplicationErrorReport.CrashInfo crashInfo) {
13007        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13008                UserHandle.getUserId(Binder.getCallingUid()), processName,
13009                r == null ? -1 : r.info.flags,
13010                crashInfo.exceptionClassName,
13011                crashInfo.exceptionMessage,
13012                crashInfo.throwFileName,
13013                crashInfo.throwLineNumber);
13014
13015        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13016
13017        mAppErrors.crashApplication(r, crashInfo);
13018    }
13019
13020    public void handleApplicationStrictModeViolation(
13021            IBinder app,
13022            int violationMask,
13023            StrictMode.ViolationInfo info) {
13024        ProcessRecord r = findAppProcess(app, "StrictMode");
13025        if (r == null) {
13026            return;
13027        }
13028
13029        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13030            Integer stackFingerprint = info.hashCode();
13031            boolean logIt = true;
13032            synchronized (mAlreadyLoggedViolatedStacks) {
13033                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13034                    logIt = false;
13035                    // TODO: sub-sample into EventLog for these, with
13036                    // the info.durationMillis?  Then we'd get
13037                    // the relative pain numbers, without logging all
13038                    // the stack traces repeatedly.  We'd want to do
13039                    // likewise in the client code, which also does
13040                    // dup suppression, before the Binder call.
13041                } else {
13042                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13043                        mAlreadyLoggedViolatedStacks.clear();
13044                    }
13045                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13046                }
13047            }
13048            if (logIt) {
13049                logStrictModeViolationToDropBox(r, info);
13050            }
13051        }
13052
13053        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13054            AppErrorResult result = new AppErrorResult();
13055            synchronized (this) {
13056                final long origId = Binder.clearCallingIdentity();
13057
13058                Message msg = Message.obtain();
13059                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13060                HashMap<String, Object> data = new HashMap<String, Object>();
13061                data.put("result", result);
13062                data.put("app", r);
13063                data.put("violationMask", violationMask);
13064                data.put("info", info);
13065                msg.obj = data;
13066                mUiHandler.sendMessage(msg);
13067
13068                Binder.restoreCallingIdentity(origId);
13069            }
13070            int res = result.get();
13071            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13072        }
13073    }
13074
13075    // Depending on the policy in effect, there could be a bunch of
13076    // these in quick succession so we try to batch these together to
13077    // minimize disk writes, number of dropbox entries, and maximize
13078    // compression, by having more fewer, larger records.
13079    private void logStrictModeViolationToDropBox(
13080            ProcessRecord process,
13081            StrictMode.ViolationInfo info) {
13082        if (info == null) {
13083            return;
13084        }
13085        final boolean isSystemApp = process == null ||
13086                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13087                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13088        final String processName = process == null ? "unknown" : process.processName;
13089        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13090        final DropBoxManager dbox = (DropBoxManager)
13091                mContext.getSystemService(Context.DROPBOX_SERVICE);
13092
13093        // Exit early if the dropbox isn't configured to accept this report type.
13094        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13095
13096        boolean bufferWasEmpty;
13097        boolean needsFlush;
13098        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13099        synchronized (sb) {
13100            bufferWasEmpty = sb.length() == 0;
13101            appendDropBoxProcessHeaders(process, processName, sb);
13102            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13103            sb.append("System-App: ").append(isSystemApp).append("\n");
13104            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13105            if (info.violationNumThisLoop != 0) {
13106                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13107            }
13108            if (info.numAnimationsRunning != 0) {
13109                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13110            }
13111            if (info.broadcastIntentAction != null) {
13112                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13113            }
13114            if (info.durationMillis != -1) {
13115                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13116            }
13117            if (info.numInstances != -1) {
13118                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13119            }
13120            if (info.tags != null) {
13121                for (String tag : info.tags) {
13122                    sb.append("Span-Tag: ").append(tag).append("\n");
13123                }
13124            }
13125            sb.append("\n");
13126            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13127                sb.append(info.crashInfo.stackTrace);
13128                sb.append("\n");
13129            }
13130            if (info.message != null) {
13131                sb.append(info.message);
13132                sb.append("\n");
13133            }
13134
13135            // Only buffer up to ~64k.  Various logging bits truncate
13136            // things at 128k.
13137            needsFlush = (sb.length() > 64 * 1024);
13138        }
13139
13140        // Flush immediately if the buffer's grown too large, or this
13141        // is a non-system app.  Non-system apps are isolated with a
13142        // different tag & policy and not batched.
13143        //
13144        // Batching is useful during internal testing with
13145        // StrictMode settings turned up high.  Without batching,
13146        // thousands of separate files could be created on boot.
13147        if (!isSystemApp || needsFlush) {
13148            new Thread("Error dump: " + dropboxTag) {
13149                @Override
13150                public void run() {
13151                    String report;
13152                    synchronized (sb) {
13153                        report = sb.toString();
13154                        sb.delete(0, sb.length());
13155                        sb.trimToSize();
13156                    }
13157                    if (report.length() != 0) {
13158                        dbox.addText(dropboxTag, report);
13159                    }
13160                }
13161            }.start();
13162            return;
13163        }
13164
13165        // System app batching:
13166        if (!bufferWasEmpty) {
13167            // An existing dropbox-writing thread is outstanding, so
13168            // we don't need to start it up.  The existing thread will
13169            // catch the buffer appends we just did.
13170            return;
13171        }
13172
13173        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13174        // (After this point, we shouldn't access AMS internal data structures.)
13175        new Thread("Error dump: " + dropboxTag) {
13176            @Override
13177            public void run() {
13178                // 5 second sleep to let stacks arrive and be batched together
13179                try {
13180                    Thread.sleep(5000);  // 5 seconds
13181                } catch (InterruptedException e) {}
13182
13183                String errorReport;
13184                synchronized (mStrictModeBuffer) {
13185                    errorReport = mStrictModeBuffer.toString();
13186                    if (errorReport.length() == 0) {
13187                        return;
13188                    }
13189                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13190                    mStrictModeBuffer.trimToSize();
13191                }
13192                dbox.addText(dropboxTag, errorReport);
13193            }
13194        }.start();
13195    }
13196
13197    /**
13198     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13199     * @param app object of the crashing app, null for the system server
13200     * @param tag reported by the caller
13201     * @param system whether this wtf is coming from the system
13202     * @param crashInfo describing the context of the error
13203     * @return true if the process should exit immediately (WTF is fatal)
13204     */
13205    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13206            final ApplicationErrorReport.CrashInfo crashInfo) {
13207        final int callingUid = Binder.getCallingUid();
13208        final int callingPid = Binder.getCallingPid();
13209
13210        if (system) {
13211            // If this is coming from the system, we could very well have low-level
13212            // system locks held, so we want to do this all asynchronously.  And we
13213            // never want this to become fatal, so there is that too.
13214            mHandler.post(new Runnable() {
13215                @Override public void run() {
13216                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13217                }
13218            });
13219            return false;
13220        }
13221
13222        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13223                crashInfo);
13224
13225        if (r != null && r.pid != Process.myPid() &&
13226                Settings.Global.getInt(mContext.getContentResolver(),
13227                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13228            mAppErrors.crashApplication(r, crashInfo);
13229            return true;
13230        } else {
13231            return false;
13232        }
13233    }
13234
13235    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13236            final ApplicationErrorReport.CrashInfo crashInfo) {
13237        final ProcessRecord r = findAppProcess(app, "WTF");
13238        final String processName = app == null ? "system_server"
13239                : (r == null ? "unknown" : r.processName);
13240
13241        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13242                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13243
13244        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13245
13246        return r;
13247    }
13248
13249    /**
13250     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13251     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13252     */
13253    private ProcessRecord findAppProcess(IBinder app, String reason) {
13254        if (app == null) {
13255            return null;
13256        }
13257
13258        synchronized (this) {
13259            final int NP = mProcessNames.getMap().size();
13260            for (int ip=0; ip<NP; ip++) {
13261                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13262                final int NA = apps.size();
13263                for (int ia=0; ia<NA; ia++) {
13264                    ProcessRecord p = apps.valueAt(ia);
13265                    if (p.thread != null && p.thread.asBinder() == app) {
13266                        return p;
13267                    }
13268                }
13269            }
13270
13271            Slog.w(TAG, "Can't find mystery application for " + reason
13272                    + " from pid=" + Binder.getCallingPid()
13273                    + " uid=" + Binder.getCallingUid() + ": " + app);
13274            return null;
13275        }
13276    }
13277
13278    /**
13279     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13280     * to append various headers to the dropbox log text.
13281     */
13282    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13283            StringBuilder sb) {
13284        // Watchdog thread ends up invoking this function (with
13285        // a null ProcessRecord) to add the stack file to dropbox.
13286        // Do not acquire a lock on this (am) in such cases, as it
13287        // could cause a potential deadlock, if and when watchdog
13288        // is invoked due to unavailability of lock on am and it
13289        // would prevent watchdog from killing system_server.
13290        if (process == null) {
13291            sb.append("Process: ").append(processName).append("\n");
13292            return;
13293        }
13294        // Note: ProcessRecord 'process' is guarded by the service
13295        // instance.  (notably process.pkgList, which could otherwise change
13296        // concurrently during execution of this method)
13297        synchronized (this) {
13298            sb.append("Process: ").append(processName).append("\n");
13299            int flags = process.info.flags;
13300            IPackageManager pm = AppGlobals.getPackageManager();
13301            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13302            for (int ip=0; ip<process.pkgList.size(); ip++) {
13303                String pkg = process.pkgList.keyAt(ip);
13304                sb.append("Package: ").append(pkg);
13305                try {
13306                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13307                    if (pi != null) {
13308                        sb.append(" v").append(pi.versionCode);
13309                        if (pi.versionName != null) {
13310                            sb.append(" (").append(pi.versionName).append(")");
13311                        }
13312                    }
13313                } catch (RemoteException e) {
13314                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13315                }
13316                sb.append("\n");
13317            }
13318        }
13319    }
13320
13321    private static String processClass(ProcessRecord process) {
13322        if (process == null || process.pid == MY_PID) {
13323            return "system_server";
13324        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13325            return "system_app";
13326        } else {
13327            return "data_app";
13328        }
13329    }
13330
13331    private volatile long mWtfClusterStart;
13332    private volatile int mWtfClusterCount;
13333
13334    /**
13335     * Write a description of an error (crash, WTF, ANR) to the drop box.
13336     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13337     * @param process which caused the error, null means the system server
13338     * @param activity which triggered the error, null if unknown
13339     * @param parent activity related to the error, null if unknown
13340     * @param subject line related to the error, null if absent
13341     * @param report in long form describing the error, null if absent
13342     * @param logFile to include in the report, null if none
13343     * @param crashInfo giving an application stack trace, null if absent
13344     */
13345    public void addErrorToDropBox(String eventType,
13346            ProcessRecord process, String processName, ActivityRecord activity,
13347            ActivityRecord parent, String subject,
13348            final String report, final File logFile,
13349            final ApplicationErrorReport.CrashInfo crashInfo) {
13350        // NOTE -- this must never acquire the ActivityManagerService lock,
13351        // otherwise the watchdog may be prevented from resetting the system.
13352
13353        final String dropboxTag = processClass(process) + "_" + eventType;
13354        final DropBoxManager dbox = (DropBoxManager)
13355                mContext.getSystemService(Context.DROPBOX_SERVICE);
13356
13357        // Exit early if the dropbox isn't configured to accept this report type.
13358        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13359
13360        // Rate-limit how often we're willing to do the heavy lifting below to
13361        // collect and record logs; currently 5 logs per 10 second period.
13362        final long now = SystemClock.elapsedRealtime();
13363        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13364            mWtfClusterStart = now;
13365            mWtfClusterCount = 1;
13366        } else {
13367            if (mWtfClusterCount++ >= 5) return;
13368        }
13369
13370        final StringBuilder sb = new StringBuilder(1024);
13371        appendDropBoxProcessHeaders(process, processName, sb);
13372        if (process != null) {
13373            sb.append("Foreground: ")
13374                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13375                    .append("\n");
13376        }
13377        if (activity != null) {
13378            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13379        }
13380        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13381            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13382        }
13383        if (parent != null && parent != activity) {
13384            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13385        }
13386        if (subject != null) {
13387            sb.append("Subject: ").append(subject).append("\n");
13388        }
13389        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13390        if (Debug.isDebuggerConnected()) {
13391            sb.append("Debugger: Connected\n");
13392        }
13393        sb.append("\n");
13394
13395        // Do the rest in a worker thread to avoid blocking the caller on I/O
13396        // (After this point, we shouldn't access AMS internal data structures.)
13397        Thread worker = new Thread("Error dump: " + dropboxTag) {
13398            @Override
13399            public void run() {
13400                if (report != null) {
13401                    sb.append(report);
13402                }
13403                if (logFile != null) {
13404                    try {
13405                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13406                                    "\n\n[[TRUNCATED]]"));
13407                    } catch (IOException e) {
13408                        Slog.e(TAG, "Error reading " + logFile, e);
13409                    }
13410                }
13411                if (crashInfo != null && crashInfo.stackTrace != null) {
13412                    sb.append(crashInfo.stackTrace);
13413                }
13414
13415                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13416                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13417                if (lines > 0) {
13418                    sb.append("\n");
13419
13420                    // Merge several logcat streams, and take the last N lines
13421                    InputStreamReader input = null;
13422                    try {
13423                        java.lang.Process logcat = new ProcessBuilder(
13424                                "/system/bin/timeout", "-k", "15s", "10s",
13425                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13426                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13427                                        .redirectErrorStream(true).start();
13428
13429                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13430                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13431                        input = new InputStreamReader(logcat.getInputStream());
13432
13433                        int num;
13434                        char[] buf = new char[8192];
13435                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13436                    } catch (IOException e) {
13437                        Slog.e(TAG, "Error running logcat", e);
13438                    } finally {
13439                        if (input != null) try { input.close(); } catch (IOException e) {}
13440                    }
13441                }
13442
13443                dbox.addText(dropboxTag, sb.toString());
13444            }
13445        };
13446
13447        if (process == null) {
13448            // If process is null, we are being called from some internal code
13449            // and may be about to die -- run this synchronously.
13450            worker.run();
13451        } else {
13452            worker.start();
13453        }
13454    }
13455
13456    @Override
13457    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13458        enforceNotIsolatedCaller("getProcessesInErrorState");
13459        // assume our apps are happy - lazy create the list
13460        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13461
13462        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13463                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13464        int userId = UserHandle.getUserId(Binder.getCallingUid());
13465
13466        synchronized (this) {
13467
13468            // iterate across all processes
13469            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13470                ProcessRecord app = mLruProcesses.get(i);
13471                if (!allUsers && app.userId != userId) {
13472                    continue;
13473                }
13474                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13475                    // This one's in trouble, so we'll generate a report for it
13476                    // crashes are higher priority (in case there's a crash *and* an anr)
13477                    ActivityManager.ProcessErrorStateInfo report = null;
13478                    if (app.crashing) {
13479                        report = app.crashingReport;
13480                    } else if (app.notResponding) {
13481                        report = app.notRespondingReport;
13482                    }
13483
13484                    if (report != null) {
13485                        if (errList == null) {
13486                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13487                        }
13488                        errList.add(report);
13489                    } else {
13490                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13491                                " crashing = " + app.crashing +
13492                                " notResponding = " + app.notResponding);
13493                    }
13494                }
13495            }
13496        }
13497
13498        return errList;
13499    }
13500
13501    static int procStateToImportance(int procState, int memAdj,
13502            ActivityManager.RunningAppProcessInfo currApp) {
13503        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13504        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13505            currApp.lru = memAdj;
13506        } else {
13507            currApp.lru = 0;
13508        }
13509        return imp;
13510    }
13511
13512    private void fillInProcMemInfo(ProcessRecord app,
13513            ActivityManager.RunningAppProcessInfo outInfo) {
13514        outInfo.pid = app.pid;
13515        outInfo.uid = app.info.uid;
13516        if (mHeavyWeightProcess == app) {
13517            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13518        }
13519        if (app.persistent) {
13520            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13521        }
13522        if (app.activities.size() > 0) {
13523            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13524        }
13525        outInfo.lastTrimLevel = app.trimMemoryLevel;
13526        int adj = app.curAdj;
13527        int procState = app.curProcState;
13528        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13529        outInfo.importanceReasonCode = app.adjTypeCode;
13530        outInfo.processState = app.curProcState;
13531    }
13532
13533    @Override
13534    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13535        enforceNotIsolatedCaller("getRunningAppProcesses");
13536
13537        final int callingUid = Binder.getCallingUid();
13538
13539        // Lazy instantiation of list
13540        List<ActivityManager.RunningAppProcessInfo> runList = null;
13541        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13542                callingUid) == PackageManager.PERMISSION_GRANTED;
13543        final int userId = UserHandle.getUserId(callingUid);
13544        final boolean allUids = isGetTasksAllowed(
13545                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13546
13547        synchronized (this) {
13548            // Iterate across all processes
13549            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13550                ProcessRecord app = mLruProcesses.get(i);
13551                if ((!allUsers && app.userId != userId)
13552                        || (!allUids && app.uid != callingUid)) {
13553                    continue;
13554                }
13555                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13556                    // Generate process state info for running application
13557                    ActivityManager.RunningAppProcessInfo currApp =
13558                        new ActivityManager.RunningAppProcessInfo(app.processName,
13559                                app.pid, app.getPackageList());
13560                    fillInProcMemInfo(app, currApp);
13561                    if (app.adjSource instanceof ProcessRecord) {
13562                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13563                        currApp.importanceReasonImportance =
13564                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13565                                        app.adjSourceProcState);
13566                    } else if (app.adjSource instanceof ActivityRecord) {
13567                        ActivityRecord r = (ActivityRecord)app.adjSource;
13568                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13569                    }
13570                    if (app.adjTarget instanceof ComponentName) {
13571                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13572                    }
13573                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13574                    //        + " lru=" + currApp.lru);
13575                    if (runList == null) {
13576                        runList = new ArrayList<>();
13577                    }
13578                    runList.add(currApp);
13579                }
13580            }
13581        }
13582        return runList;
13583    }
13584
13585    @Override
13586    public List<ApplicationInfo> getRunningExternalApplications() {
13587        enforceNotIsolatedCaller("getRunningExternalApplications");
13588        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13589        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13590        if (runningApps != null && runningApps.size() > 0) {
13591            Set<String> extList = new HashSet<String>();
13592            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13593                if (app.pkgList != null) {
13594                    for (String pkg : app.pkgList) {
13595                        extList.add(pkg);
13596                    }
13597                }
13598            }
13599            IPackageManager pm = AppGlobals.getPackageManager();
13600            for (String pkg : extList) {
13601                try {
13602                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13603                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13604                        retList.add(info);
13605                    }
13606                } catch (RemoteException e) {
13607                }
13608            }
13609        }
13610        return retList;
13611    }
13612
13613    @Override
13614    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13615        enforceNotIsolatedCaller("getMyMemoryState");
13616        synchronized (this) {
13617            ProcessRecord proc;
13618            synchronized (mPidsSelfLocked) {
13619                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13620            }
13621            fillInProcMemInfo(proc, outInfo);
13622        }
13623    }
13624
13625    @Override
13626    public int getMemoryTrimLevel() {
13627        enforceNotIsolatedCaller("getMyMemoryState");
13628        synchronized (this) {
13629            return mLastMemoryLevel;
13630        }
13631    }
13632
13633    @Override
13634    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13635            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13636        (new ActivityManagerShellCommand(this, false)).exec(
13637                this, in, out, err, args, resultReceiver);
13638    }
13639
13640    @Override
13641    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13642        if (checkCallingPermission(android.Manifest.permission.DUMP)
13643                != PackageManager.PERMISSION_GRANTED) {
13644            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13645                    + Binder.getCallingPid()
13646                    + ", uid=" + Binder.getCallingUid()
13647                    + " without permission "
13648                    + android.Manifest.permission.DUMP);
13649            return;
13650        }
13651
13652        boolean dumpAll = false;
13653        boolean dumpClient = false;
13654        String dumpPackage = null;
13655
13656        int opti = 0;
13657        while (opti < args.length) {
13658            String opt = args[opti];
13659            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13660                break;
13661            }
13662            opti++;
13663            if ("-a".equals(opt)) {
13664                dumpAll = true;
13665            } else if ("-c".equals(opt)) {
13666                dumpClient = true;
13667            } else if ("-p".equals(opt)) {
13668                if (opti < args.length) {
13669                    dumpPackage = args[opti];
13670                    opti++;
13671                } else {
13672                    pw.println("Error: -p option requires package argument");
13673                    return;
13674                }
13675                dumpClient = true;
13676            } else if ("-h".equals(opt)) {
13677                ActivityManagerShellCommand.dumpHelp(pw, true);
13678                return;
13679            } else {
13680                pw.println("Unknown argument: " + opt + "; use -h for help");
13681            }
13682        }
13683
13684        long origId = Binder.clearCallingIdentity();
13685        boolean more = false;
13686        // Is the caller requesting to dump a particular piece of data?
13687        if (opti < args.length) {
13688            String cmd = args[opti];
13689            opti++;
13690            if ("activities".equals(cmd) || "a".equals(cmd)) {
13691                synchronized (this) {
13692                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13693                }
13694            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13695                synchronized (this) {
13696                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13697                }
13698            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13699                String[] newArgs;
13700                String name;
13701                if (opti >= args.length) {
13702                    name = null;
13703                    newArgs = EMPTY_STRING_ARRAY;
13704                } else {
13705                    dumpPackage = args[opti];
13706                    opti++;
13707                    newArgs = new String[args.length - opti];
13708                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13709                            args.length - opti);
13710                }
13711                synchronized (this) {
13712                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13713                }
13714            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13715                String[] newArgs;
13716                String name;
13717                if (opti >= args.length) {
13718                    name = null;
13719                    newArgs = EMPTY_STRING_ARRAY;
13720                } else {
13721                    dumpPackage = args[opti];
13722                    opti++;
13723                    newArgs = new String[args.length - opti];
13724                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13725                            args.length - opti);
13726                }
13727                synchronized (this) {
13728                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13729                }
13730            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13731                String[] newArgs;
13732                String name;
13733                if (opti >= args.length) {
13734                    name = null;
13735                    newArgs = EMPTY_STRING_ARRAY;
13736                } else {
13737                    dumpPackage = args[opti];
13738                    opti++;
13739                    newArgs = new String[args.length - opti];
13740                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13741                            args.length - opti);
13742                }
13743                synchronized (this) {
13744                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13745                }
13746            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13747                synchronized (this) {
13748                    dumpOomLocked(fd, pw, args, opti, true);
13749                }
13750            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13751                synchronized (this) {
13752                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13753                }
13754            } else if ("provider".equals(cmd)) {
13755                String[] newArgs;
13756                String name;
13757                if (opti >= args.length) {
13758                    name = null;
13759                    newArgs = EMPTY_STRING_ARRAY;
13760                } else {
13761                    name = args[opti];
13762                    opti++;
13763                    newArgs = new String[args.length - opti];
13764                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13765                }
13766                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13767                    pw.println("No providers match: " + name);
13768                    pw.println("Use -h for help.");
13769                }
13770            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13771                synchronized (this) {
13772                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13773                }
13774            } else if ("service".equals(cmd)) {
13775                String[] newArgs;
13776                String name;
13777                if (opti >= args.length) {
13778                    name = null;
13779                    newArgs = EMPTY_STRING_ARRAY;
13780                } else {
13781                    name = args[opti];
13782                    opti++;
13783                    newArgs = new String[args.length - opti];
13784                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13785                            args.length - opti);
13786                }
13787                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13788                    pw.println("No services match: " + name);
13789                    pw.println("Use -h for help.");
13790                }
13791            } else if ("package".equals(cmd)) {
13792                String[] newArgs;
13793                if (opti >= args.length) {
13794                    pw.println("package: no package name specified");
13795                    pw.println("Use -h for help.");
13796                } else {
13797                    dumpPackage = args[opti];
13798                    opti++;
13799                    newArgs = new String[args.length - opti];
13800                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13801                            args.length - opti);
13802                    args = newArgs;
13803                    opti = 0;
13804                    more = true;
13805                }
13806            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13807                synchronized (this) {
13808                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13809                }
13810            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13811                if (dumpClient) {
13812                    ActiveServices.ServiceDumper dumper;
13813                    synchronized (this) {
13814                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13815                                dumpPackage);
13816                    }
13817                    dumper.dumpWithClient();
13818                } else {
13819                    synchronized (this) {
13820                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13821                                dumpPackage).dumpLocked();
13822                    }
13823                }
13824            } else if ("locks".equals(cmd)) {
13825                LockGuard.dump(fd, pw, args);
13826            } else {
13827                // Dumping a single activity?
13828                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13829                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13830                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13831                    if (res < 0) {
13832                        pw.println("Bad activity command, or no activities match: " + cmd);
13833                        pw.println("Use -h for help.");
13834                    }
13835                }
13836            }
13837            if (!more) {
13838                Binder.restoreCallingIdentity(origId);
13839                return;
13840            }
13841        }
13842
13843        // No piece of data specified, dump everything.
13844        if (dumpClient) {
13845            ActiveServices.ServiceDumper sdumper;
13846            synchronized (this) {
13847                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13848                pw.println();
13849                if (dumpAll) {
13850                    pw.println("-------------------------------------------------------------------------------");
13851                }
13852                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13853                pw.println();
13854                if (dumpAll) {
13855                    pw.println("-------------------------------------------------------------------------------");
13856                }
13857                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13858                pw.println();
13859                if (dumpAll) {
13860                    pw.println("-------------------------------------------------------------------------------");
13861                }
13862                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13863                pw.println();
13864                if (dumpAll) {
13865                    pw.println("-------------------------------------------------------------------------------");
13866                }
13867                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13868                        dumpPackage);
13869            }
13870            sdumper.dumpWithClient();
13871            pw.println();
13872            synchronized (this) {
13873                if (dumpAll) {
13874                    pw.println("-------------------------------------------------------------------------------");
13875                }
13876                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13877                pw.println();
13878                if (dumpAll) {
13879                    pw.println("-------------------------------------------------------------------------------");
13880                }
13881                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13882                if (mAssociations.size() > 0) {
13883                    pw.println();
13884                    if (dumpAll) {
13885                        pw.println("-------------------------------------------------------------------------------");
13886                    }
13887                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13888                }
13889                pw.println();
13890                if (dumpAll) {
13891                    pw.println("-------------------------------------------------------------------------------");
13892                }
13893                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13894            }
13895
13896        } else {
13897            synchronized (this) {
13898                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13899                pw.println();
13900                if (dumpAll) {
13901                    pw.println("-------------------------------------------------------------------------------");
13902                }
13903                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13904                pw.println();
13905                if (dumpAll) {
13906                    pw.println("-------------------------------------------------------------------------------");
13907                }
13908                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13909                pw.println();
13910                if (dumpAll) {
13911                    pw.println("-------------------------------------------------------------------------------");
13912                }
13913                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13914                pw.println();
13915                if (dumpAll) {
13916                    pw.println("-------------------------------------------------------------------------------");
13917                }
13918                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
13919                        .dumpLocked();
13920                pw.println();
13921                if (dumpAll) {
13922                    pw.println("-------------------------------------------------------------------------------");
13923                }
13924                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13925                pw.println();
13926                if (dumpAll) {
13927                    pw.println("-------------------------------------------------------------------------------");
13928                }
13929                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13930                if (mAssociations.size() > 0) {
13931                    pw.println();
13932                    if (dumpAll) {
13933                        pw.println("-------------------------------------------------------------------------------");
13934                    }
13935                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13936                }
13937                pw.println();
13938                if (dumpAll) {
13939                    pw.println("-------------------------------------------------------------------------------");
13940                }
13941                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13942            }
13943        }
13944        Binder.restoreCallingIdentity(origId);
13945    }
13946
13947    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13948            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13949        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13950
13951        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13952                dumpPackage);
13953        boolean needSep = printedAnything;
13954
13955        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13956                dumpPackage, needSep, "  mFocusedActivity: ");
13957        if (printed) {
13958            printedAnything = true;
13959            needSep = false;
13960        }
13961
13962        if (dumpPackage == null) {
13963            if (needSep) {
13964                pw.println();
13965            }
13966            needSep = true;
13967            printedAnything = true;
13968            mStackSupervisor.dump(pw, "  ");
13969        }
13970
13971        if (!printedAnything) {
13972            pw.println("  (nothing)");
13973        }
13974    }
13975
13976    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13977            int opti, boolean dumpAll, String dumpPackage) {
13978        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13979
13980        boolean printedAnything = false;
13981
13982        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13983            boolean printedHeader = false;
13984
13985            final int N = mRecentTasks.size();
13986            for (int i=0; i<N; i++) {
13987                TaskRecord tr = mRecentTasks.get(i);
13988                if (dumpPackage != null) {
13989                    if (tr.realActivity == null ||
13990                            !dumpPackage.equals(tr.realActivity)) {
13991                        continue;
13992                    }
13993                }
13994                if (!printedHeader) {
13995                    pw.println("  Recent tasks:");
13996                    printedHeader = true;
13997                    printedAnything = true;
13998                }
13999                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14000                        pw.println(tr);
14001                if (dumpAll) {
14002                    mRecentTasks.get(i).dump(pw, "    ");
14003                }
14004            }
14005        }
14006
14007        if (!printedAnything) {
14008            pw.println("  (nothing)");
14009        }
14010    }
14011
14012    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14013            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14014        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14015
14016        int dumpUid = 0;
14017        if (dumpPackage != null) {
14018            IPackageManager pm = AppGlobals.getPackageManager();
14019            try {
14020                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14021            } catch (RemoteException e) {
14022            }
14023        }
14024
14025        boolean printedAnything = false;
14026
14027        final long now = SystemClock.uptimeMillis();
14028
14029        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14030            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14031                    = mAssociations.valueAt(i1);
14032            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14033                SparseArray<ArrayMap<String, Association>> sourceUids
14034                        = targetComponents.valueAt(i2);
14035                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14036                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14037                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14038                        Association ass = sourceProcesses.valueAt(i4);
14039                        if (dumpPackage != null) {
14040                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14041                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14042                                continue;
14043                            }
14044                        }
14045                        printedAnything = true;
14046                        pw.print("  ");
14047                        pw.print(ass.mTargetProcess);
14048                        pw.print("/");
14049                        UserHandle.formatUid(pw, ass.mTargetUid);
14050                        pw.print(" <- ");
14051                        pw.print(ass.mSourceProcess);
14052                        pw.print("/");
14053                        UserHandle.formatUid(pw, ass.mSourceUid);
14054                        pw.println();
14055                        pw.print("    via ");
14056                        pw.print(ass.mTargetComponent.flattenToShortString());
14057                        pw.println();
14058                        pw.print("    ");
14059                        long dur = ass.mTime;
14060                        if (ass.mNesting > 0) {
14061                            dur += now - ass.mStartTime;
14062                        }
14063                        TimeUtils.formatDuration(dur, pw);
14064                        pw.print(" (");
14065                        pw.print(ass.mCount);
14066                        pw.print(" times)");
14067                        pw.print("  ");
14068                        for (int i=0; i<ass.mStateTimes.length; i++) {
14069                            long amt = ass.mStateTimes[i];
14070                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14071                                amt += now - ass.mLastStateUptime;
14072                            }
14073                            if (amt != 0) {
14074                                pw.print(" ");
14075                                pw.print(ProcessList.makeProcStateString(
14076                                            i + ActivityManager.MIN_PROCESS_STATE));
14077                                pw.print("=");
14078                                TimeUtils.formatDuration(amt, pw);
14079                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14080                                    pw.print("*");
14081                                }
14082                            }
14083                        }
14084                        pw.println();
14085                        if (ass.mNesting > 0) {
14086                            pw.print("    Currently active: ");
14087                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14088                            pw.println();
14089                        }
14090                    }
14091                }
14092            }
14093
14094        }
14095
14096        if (!printedAnything) {
14097            pw.println("  (nothing)");
14098        }
14099    }
14100
14101    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14102            String header, boolean needSep) {
14103        boolean printed = false;
14104        int whichAppId = -1;
14105        if (dumpPackage != null) {
14106            try {
14107                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14108                        dumpPackage, 0);
14109                whichAppId = UserHandle.getAppId(info.uid);
14110            } catch (NameNotFoundException e) {
14111                e.printStackTrace();
14112            }
14113        }
14114        for (int i=0; i<uids.size(); i++) {
14115            UidRecord uidRec = uids.valueAt(i);
14116            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14117                continue;
14118            }
14119            if (!printed) {
14120                printed = true;
14121                if (needSep) {
14122                    pw.println();
14123                }
14124                pw.print("  ");
14125                pw.println(header);
14126                needSep = true;
14127            }
14128            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14129            pw.print(": "); pw.println(uidRec);
14130        }
14131        return printed;
14132    }
14133
14134    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14135            int opti, boolean dumpAll, String dumpPackage) {
14136        boolean needSep = false;
14137        boolean printedAnything = false;
14138        int numPers = 0;
14139
14140        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14141
14142        if (dumpAll) {
14143            final int NP = mProcessNames.getMap().size();
14144            for (int ip=0; ip<NP; ip++) {
14145                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14146                final int NA = procs.size();
14147                for (int ia=0; ia<NA; ia++) {
14148                    ProcessRecord r = procs.valueAt(ia);
14149                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14150                        continue;
14151                    }
14152                    if (!needSep) {
14153                        pw.println("  All known processes:");
14154                        needSep = true;
14155                        printedAnything = true;
14156                    }
14157                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14158                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14159                        pw.print(" "); pw.println(r);
14160                    r.dump(pw, "    ");
14161                    if (r.persistent) {
14162                        numPers++;
14163                    }
14164                }
14165            }
14166        }
14167
14168        if (mIsolatedProcesses.size() > 0) {
14169            boolean printed = false;
14170            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14171                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14172                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14173                    continue;
14174                }
14175                if (!printed) {
14176                    if (needSep) {
14177                        pw.println();
14178                    }
14179                    pw.println("  Isolated process list (sorted by uid):");
14180                    printedAnything = true;
14181                    printed = true;
14182                    needSep = true;
14183                }
14184                pw.println(String.format("%sIsolated #%2d: %s",
14185                        "    ", i, r.toString()));
14186            }
14187        }
14188
14189        if (mActiveUids.size() > 0) {
14190            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14191                printedAnything = needSep = true;
14192            }
14193        }
14194        if (mValidateUids.size() > 0) {
14195            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14196                printedAnything = needSep = true;
14197            }
14198        }
14199
14200        if (mLruProcesses.size() > 0) {
14201            if (needSep) {
14202                pw.println();
14203            }
14204            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14205                    pw.print(" total, non-act at ");
14206                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14207                    pw.print(", non-svc at ");
14208                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14209                    pw.println("):");
14210            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14211            needSep = true;
14212            printedAnything = true;
14213        }
14214
14215        if (dumpAll || dumpPackage != null) {
14216            synchronized (mPidsSelfLocked) {
14217                boolean printed = false;
14218                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14219                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14220                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14221                        continue;
14222                    }
14223                    if (!printed) {
14224                        if (needSep) pw.println();
14225                        needSep = true;
14226                        pw.println("  PID mappings:");
14227                        printed = true;
14228                        printedAnything = true;
14229                    }
14230                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14231                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14232                }
14233            }
14234        }
14235
14236        if (mForegroundProcesses.size() > 0) {
14237            synchronized (mPidsSelfLocked) {
14238                boolean printed = false;
14239                for (int i=0; i<mForegroundProcesses.size(); i++) {
14240                    ProcessRecord r = mPidsSelfLocked.get(
14241                            mForegroundProcesses.valueAt(i).pid);
14242                    if (dumpPackage != null && (r == null
14243                            || !r.pkgList.containsKey(dumpPackage))) {
14244                        continue;
14245                    }
14246                    if (!printed) {
14247                        if (needSep) pw.println();
14248                        needSep = true;
14249                        pw.println("  Foreground Processes:");
14250                        printed = true;
14251                        printedAnything = true;
14252                    }
14253                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14254                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14255                }
14256            }
14257        }
14258
14259        if (mPersistentStartingProcesses.size() > 0) {
14260            if (needSep) pw.println();
14261            needSep = true;
14262            printedAnything = true;
14263            pw.println("  Persisent processes that are starting:");
14264            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14265                    "Starting Norm", "Restarting PERS", dumpPackage);
14266        }
14267
14268        if (mRemovedProcesses.size() > 0) {
14269            if (needSep) pw.println();
14270            needSep = true;
14271            printedAnything = true;
14272            pw.println("  Processes that are being removed:");
14273            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14274                    "Removed Norm", "Removed PERS", dumpPackage);
14275        }
14276
14277        if (mProcessesOnHold.size() > 0) {
14278            if (needSep) pw.println();
14279            needSep = true;
14280            printedAnything = true;
14281            pw.println("  Processes that are on old until the system is ready:");
14282            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14283                    "OnHold Norm", "OnHold PERS", dumpPackage);
14284        }
14285
14286        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14287
14288        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14289        if (needSep) {
14290            printedAnything = true;
14291        }
14292
14293        if (dumpPackage == null) {
14294            pw.println();
14295            needSep = false;
14296            mUserController.dump(pw, dumpAll);
14297        }
14298        if (mHomeProcess != null && (dumpPackage == null
14299                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14300            if (needSep) {
14301                pw.println();
14302                needSep = false;
14303            }
14304            pw.println("  mHomeProcess: " + mHomeProcess);
14305        }
14306        if (mPreviousProcess != null && (dumpPackage == null
14307                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14308            if (needSep) {
14309                pw.println();
14310                needSep = false;
14311            }
14312            pw.println("  mPreviousProcess: " + mPreviousProcess);
14313        }
14314        if (dumpAll) {
14315            StringBuilder sb = new StringBuilder(128);
14316            sb.append("  mPreviousProcessVisibleTime: ");
14317            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14318            pw.println(sb);
14319        }
14320        if (mHeavyWeightProcess != null && (dumpPackage == null
14321                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14322            if (needSep) {
14323                pw.println();
14324                needSep = false;
14325            }
14326            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14327        }
14328        if (dumpPackage == null) {
14329            pw.println("  mConfiguration: " + mConfiguration);
14330        }
14331        if (dumpAll) {
14332            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14333            if (mCompatModePackages.getPackages().size() > 0) {
14334                boolean printed = false;
14335                for (Map.Entry<String, Integer> entry
14336                        : mCompatModePackages.getPackages().entrySet()) {
14337                    String pkg = entry.getKey();
14338                    int mode = entry.getValue();
14339                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14340                        continue;
14341                    }
14342                    if (!printed) {
14343                        pw.println("  mScreenCompatPackages:");
14344                        printed = true;
14345                    }
14346                    pw.print("    "); pw.print(pkg); pw.print(": ");
14347                            pw.print(mode); pw.println();
14348                }
14349            }
14350        }
14351        if (dumpPackage == null) {
14352            pw.println("  mWakefulness="
14353                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14354            pw.println("  mSleepTokens=" + mSleepTokens);
14355            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14356                    + lockScreenShownToString());
14357            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14358            if (mRunningVoice != null) {
14359                pw.println("  mRunningVoice=" + mRunningVoice);
14360                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14361            }
14362        }
14363        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14364                || mOrigWaitForDebugger) {
14365            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14366                    || dumpPackage.equals(mOrigDebugApp)) {
14367                if (needSep) {
14368                    pw.println();
14369                    needSep = false;
14370                }
14371                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14372                        + " mDebugTransient=" + mDebugTransient
14373                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14374            }
14375        }
14376        if (mCurAppTimeTracker != null) {
14377            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14378        }
14379        if (mMemWatchProcesses.getMap().size() > 0) {
14380            pw.println("  Mem watch processes:");
14381            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14382                    = mMemWatchProcesses.getMap();
14383            for (int i=0; i<procs.size(); i++) {
14384                final String proc = procs.keyAt(i);
14385                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14386                for (int j=0; j<uids.size(); j++) {
14387                    if (needSep) {
14388                        pw.println();
14389                        needSep = false;
14390                    }
14391                    StringBuilder sb = new StringBuilder();
14392                    sb.append("    ").append(proc).append('/');
14393                    UserHandle.formatUid(sb, uids.keyAt(j));
14394                    Pair<Long, String> val = uids.valueAt(j);
14395                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14396                    if (val.second != null) {
14397                        sb.append(", report to ").append(val.second);
14398                    }
14399                    pw.println(sb.toString());
14400                }
14401            }
14402            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14403            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14404            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14405                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14406        }
14407        if (mTrackAllocationApp != null) {
14408            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14409                if (needSep) {
14410                    pw.println();
14411                    needSep = false;
14412                }
14413                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14414            }
14415        }
14416        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14417                || mProfileFd != null) {
14418            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14419                if (needSep) {
14420                    pw.println();
14421                    needSep = false;
14422                }
14423                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14424                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14425                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14426                        + mAutoStopProfiler);
14427                pw.println("  mProfileType=" + mProfileType);
14428            }
14429        }
14430        if (mNativeDebuggingApp != null) {
14431            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14432                if (needSep) {
14433                    pw.println();
14434                    needSep = false;
14435                }
14436                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14437            }
14438        }
14439        if (dumpPackage == null) {
14440            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14441                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14442                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14443            }
14444            if (mController != null) {
14445                pw.println("  mController=" + mController
14446                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14447            }
14448            if (dumpAll) {
14449                pw.println("  Total persistent processes: " + numPers);
14450                pw.println("  mProcessesReady=" + mProcessesReady
14451                        + " mSystemReady=" + mSystemReady
14452                        + " mBooted=" + mBooted
14453                        + " mFactoryTest=" + mFactoryTest);
14454                pw.println("  mBooting=" + mBooting
14455                        + " mCallFinishBooting=" + mCallFinishBooting
14456                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14457                pw.print("  mLastPowerCheckRealtime=");
14458                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14459                        pw.println("");
14460                pw.print("  mLastPowerCheckUptime=");
14461                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14462                        pw.println("");
14463                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14464                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14465                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14466                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14467                        + " (" + mLruProcesses.size() + " total)"
14468                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14469                        + " mNumServiceProcs=" + mNumServiceProcs
14470                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14471                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14472                        + " mLastMemoryLevel=" + mLastMemoryLevel
14473                        + " mLastNumProcesses=" + mLastNumProcesses);
14474                long now = SystemClock.uptimeMillis();
14475                pw.print("  mLastIdleTime=");
14476                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14477                        pw.print(" mLowRamSinceLastIdle=");
14478                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14479                        pw.println();
14480            }
14481        }
14482
14483        if (!printedAnything) {
14484            pw.println("  (nothing)");
14485        }
14486    }
14487
14488    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14489            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14490        if (mProcessesToGc.size() > 0) {
14491            boolean printed = false;
14492            long now = SystemClock.uptimeMillis();
14493            for (int i=0; i<mProcessesToGc.size(); i++) {
14494                ProcessRecord proc = mProcessesToGc.get(i);
14495                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14496                    continue;
14497                }
14498                if (!printed) {
14499                    if (needSep) pw.println();
14500                    needSep = true;
14501                    pw.println("  Processes that are waiting to GC:");
14502                    printed = true;
14503                }
14504                pw.print("    Process "); pw.println(proc);
14505                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14506                        pw.print(", last gced=");
14507                        pw.print(now-proc.lastRequestedGc);
14508                        pw.print(" ms ago, last lowMem=");
14509                        pw.print(now-proc.lastLowMemory);
14510                        pw.println(" ms ago");
14511
14512            }
14513        }
14514        return needSep;
14515    }
14516
14517    void printOomLevel(PrintWriter pw, String name, int adj) {
14518        pw.print("    ");
14519        if (adj >= 0) {
14520            pw.print(' ');
14521            if (adj < 10) pw.print(' ');
14522        } else {
14523            if (adj > -10) pw.print(' ');
14524        }
14525        pw.print(adj);
14526        pw.print(": ");
14527        pw.print(name);
14528        pw.print(" (");
14529        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14530        pw.println(")");
14531    }
14532
14533    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14534            int opti, boolean dumpAll) {
14535        boolean needSep = false;
14536
14537        if (mLruProcesses.size() > 0) {
14538            if (needSep) pw.println();
14539            needSep = true;
14540            pw.println("  OOM levels:");
14541            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14542            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14543            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14544            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14545            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14546            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14547            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14548            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14549            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14550            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14551            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14552            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14553            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14554            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14555
14556            if (needSep) pw.println();
14557            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14558                    pw.print(" total, non-act at ");
14559                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14560                    pw.print(", non-svc at ");
14561                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14562                    pw.println("):");
14563            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14564            needSep = true;
14565        }
14566
14567        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14568
14569        pw.println();
14570        pw.println("  mHomeProcess: " + mHomeProcess);
14571        pw.println("  mPreviousProcess: " + mPreviousProcess);
14572        if (mHeavyWeightProcess != null) {
14573            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14574        }
14575
14576        return true;
14577    }
14578
14579    /**
14580     * There are three ways to call this:
14581     *  - no provider specified: dump all the providers
14582     *  - a flattened component name that matched an existing provider was specified as the
14583     *    first arg: dump that one provider
14584     *  - the first arg isn't the flattened component name of an existing provider:
14585     *    dump all providers whose component contains the first arg as a substring
14586     */
14587    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14588            int opti, boolean dumpAll) {
14589        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14590    }
14591
14592    static class ItemMatcher {
14593        ArrayList<ComponentName> components;
14594        ArrayList<String> strings;
14595        ArrayList<Integer> objects;
14596        boolean all;
14597
14598        ItemMatcher() {
14599            all = true;
14600        }
14601
14602        void build(String name) {
14603            ComponentName componentName = ComponentName.unflattenFromString(name);
14604            if (componentName != null) {
14605                if (components == null) {
14606                    components = new ArrayList<ComponentName>();
14607                }
14608                components.add(componentName);
14609                all = false;
14610            } else {
14611                int objectId = 0;
14612                // Not a '/' separated full component name; maybe an object ID?
14613                try {
14614                    objectId = Integer.parseInt(name, 16);
14615                    if (objects == null) {
14616                        objects = new ArrayList<Integer>();
14617                    }
14618                    objects.add(objectId);
14619                    all = false;
14620                } catch (RuntimeException e) {
14621                    // Not an integer; just do string match.
14622                    if (strings == null) {
14623                        strings = new ArrayList<String>();
14624                    }
14625                    strings.add(name);
14626                    all = false;
14627                }
14628            }
14629        }
14630
14631        int build(String[] args, int opti) {
14632            for (; opti<args.length; opti++) {
14633                String name = args[opti];
14634                if ("--".equals(name)) {
14635                    return opti+1;
14636                }
14637                build(name);
14638            }
14639            return opti;
14640        }
14641
14642        boolean match(Object object, ComponentName comp) {
14643            if (all) {
14644                return true;
14645            }
14646            if (components != null) {
14647                for (int i=0; i<components.size(); i++) {
14648                    if (components.get(i).equals(comp)) {
14649                        return true;
14650                    }
14651                }
14652            }
14653            if (objects != null) {
14654                for (int i=0; i<objects.size(); i++) {
14655                    if (System.identityHashCode(object) == objects.get(i)) {
14656                        return true;
14657                    }
14658                }
14659            }
14660            if (strings != null) {
14661                String flat = comp.flattenToString();
14662                for (int i=0; i<strings.size(); i++) {
14663                    if (flat.contains(strings.get(i))) {
14664                        return true;
14665                    }
14666                }
14667            }
14668            return false;
14669        }
14670    }
14671
14672    /**
14673     * There are three things that cmd can be:
14674     *  - a flattened component name that matches an existing activity
14675     *  - the cmd arg isn't the flattened component name of an existing activity:
14676     *    dump all activity whose component contains the cmd as a substring
14677     *  - A hex number of the ActivityRecord object instance.
14678     */
14679    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14680            int opti, boolean dumpAll) {
14681        ArrayList<ActivityRecord> activities;
14682
14683        synchronized (this) {
14684            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14685        }
14686
14687        if (activities.size() <= 0) {
14688            return false;
14689        }
14690
14691        String[] newArgs = new String[args.length - opti];
14692        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14693
14694        TaskRecord lastTask = null;
14695        boolean needSep = false;
14696        for (int i=activities.size()-1; i>=0; i--) {
14697            ActivityRecord r = activities.get(i);
14698            if (needSep) {
14699                pw.println();
14700            }
14701            needSep = true;
14702            synchronized (this) {
14703                if (lastTask != r.task) {
14704                    lastTask = r.task;
14705                    pw.print("TASK "); pw.print(lastTask.affinity);
14706                            pw.print(" id="); pw.println(lastTask.taskId);
14707                    if (dumpAll) {
14708                        lastTask.dump(pw, "  ");
14709                    }
14710                }
14711            }
14712            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14713        }
14714        return true;
14715    }
14716
14717    /**
14718     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14719     * there is a thread associated with the activity.
14720     */
14721    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14722            final ActivityRecord r, String[] args, boolean dumpAll) {
14723        String innerPrefix = prefix + "  ";
14724        synchronized (this) {
14725            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14726                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14727                    pw.print(" pid=");
14728                    if (r.app != null) pw.println(r.app.pid);
14729                    else pw.println("(not running)");
14730            if (dumpAll) {
14731                r.dump(pw, innerPrefix);
14732            }
14733        }
14734        if (r.app != null && r.app.thread != null) {
14735            // flush anything that is already in the PrintWriter since the thread is going
14736            // to write to the file descriptor directly
14737            pw.flush();
14738            try {
14739                TransferPipe tp = new TransferPipe();
14740                try {
14741                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14742                            r.appToken, innerPrefix, args);
14743                    tp.go(fd);
14744                } finally {
14745                    tp.kill();
14746                }
14747            } catch (IOException e) {
14748                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14749            } catch (RemoteException e) {
14750                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14751            }
14752        }
14753    }
14754
14755    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14756            int opti, boolean dumpAll, String dumpPackage) {
14757        boolean needSep = false;
14758        boolean onlyHistory = false;
14759        boolean printedAnything = false;
14760
14761        if ("history".equals(dumpPackage)) {
14762            if (opti < args.length && "-s".equals(args[opti])) {
14763                dumpAll = false;
14764            }
14765            onlyHistory = true;
14766            dumpPackage = null;
14767        }
14768
14769        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14770        if (!onlyHistory && dumpAll) {
14771            if (mRegisteredReceivers.size() > 0) {
14772                boolean printed = false;
14773                Iterator it = mRegisteredReceivers.values().iterator();
14774                while (it.hasNext()) {
14775                    ReceiverList r = (ReceiverList)it.next();
14776                    if (dumpPackage != null && (r.app == null ||
14777                            !dumpPackage.equals(r.app.info.packageName))) {
14778                        continue;
14779                    }
14780                    if (!printed) {
14781                        pw.println("  Registered Receivers:");
14782                        needSep = true;
14783                        printed = true;
14784                        printedAnything = true;
14785                    }
14786                    pw.print("  * "); pw.println(r);
14787                    r.dump(pw, "    ");
14788                }
14789            }
14790
14791            if (mReceiverResolver.dump(pw, needSep ?
14792                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14793                    "    ", dumpPackage, false, false)) {
14794                needSep = true;
14795                printedAnything = true;
14796            }
14797        }
14798
14799        for (BroadcastQueue q : mBroadcastQueues) {
14800            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14801            printedAnything |= needSep;
14802        }
14803
14804        needSep = true;
14805
14806        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14807            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14808                if (needSep) {
14809                    pw.println();
14810                }
14811                needSep = true;
14812                printedAnything = true;
14813                pw.print("  Sticky broadcasts for user ");
14814                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14815                StringBuilder sb = new StringBuilder(128);
14816                for (Map.Entry<String, ArrayList<Intent>> ent
14817                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14818                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14819                    if (dumpAll) {
14820                        pw.println(":");
14821                        ArrayList<Intent> intents = ent.getValue();
14822                        final int N = intents.size();
14823                        for (int i=0; i<N; i++) {
14824                            sb.setLength(0);
14825                            sb.append("    Intent: ");
14826                            intents.get(i).toShortString(sb, false, true, false, false);
14827                            pw.println(sb.toString());
14828                            Bundle bundle = intents.get(i).getExtras();
14829                            if (bundle != null) {
14830                                pw.print("      ");
14831                                pw.println(bundle.toString());
14832                            }
14833                        }
14834                    } else {
14835                        pw.println("");
14836                    }
14837                }
14838            }
14839        }
14840
14841        if (!onlyHistory && dumpAll) {
14842            pw.println();
14843            for (BroadcastQueue queue : mBroadcastQueues) {
14844                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14845                        + queue.mBroadcastsScheduled);
14846            }
14847            pw.println("  mHandler:");
14848            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14849            needSep = true;
14850            printedAnything = true;
14851        }
14852
14853        if (!printedAnything) {
14854            pw.println("  (nothing)");
14855        }
14856    }
14857
14858    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14859            int opti, boolean dumpAll, String dumpPackage) {
14860        boolean needSep;
14861        boolean printedAnything = false;
14862
14863        ItemMatcher matcher = new ItemMatcher();
14864        matcher.build(args, opti);
14865
14866        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14867
14868        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14869        printedAnything |= needSep;
14870
14871        if (mLaunchingProviders.size() > 0) {
14872            boolean printed = false;
14873            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14874                ContentProviderRecord r = mLaunchingProviders.get(i);
14875                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14876                    continue;
14877                }
14878                if (!printed) {
14879                    if (needSep) pw.println();
14880                    needSep = true;
14881                    pw.println("  Launching content providers:");
14882                    printed = true;
14883                    printedAnything = true;
14884                }
14885                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14886                        pw.println(r);
14887            }
14888        }
14889
14890        if (!printedAnything) {
14891            pw.println("  (nothing)");
14892        }
14893    }
14894
14895    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14896            int opti, boolean dumpAll, String dumpPackage) {
14897        boolean needSep = false;
14898        boolean printedAnything = false;
14899
14900        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14901
14902        if (mGrantedUriPermissions.size() > 0) {
14903            boolean printed = false;
14904            int dumpUid = -2;
14905            if (dumpPackage != null) {
14906                try {
14907                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14908                            MATCH_UNINSTALLED_PACKAGES, 0);
14909                } catch (NameNotFoundException e) {
14910                    dumpUid = -1;
14911                }
14912            }
14913            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14914                int uid = mGrantedUriPermissions.keyAt(i);
14915                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14916                    continue;
14917                }
14918                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14919                if (!printed) {
14920                    if (needSep) pw.println();
14921                    needSep = true;
14922                    pw.println("  Granted Uri Permissions:");
14923                    printed = true;
14924                    printedAnything = true;
14925                }
14926                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14927                for (UriPermission perm : perms.values()) {
14928                    pw.print("    "); pw.println(perm);
14929                    if (dumpAll) {
14930                        perm.dump(pw, "      ");
14931                    }
14932                }
14933            }
14934        }
14935
14936        if (!printedAnything) {
14937            pw.println("  (nothing)");
14938        }
14939    }
14940
14941    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14942            int opti, boolean dumpAll, String dumpPackage) {
14943        boolean printed = false;
14944
14945        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14946
14947        if (mIntentSenderRecords.size() > 0) {
14948            Iterator<WeakReference<PendingIntentRecord>> it
14949                    = mIntentSenderRecords.values().iterator();
14950            while (it.hasNext()) {
14951                WeakReference<PendingIntentRecord> ref = it.next();
14952                PendingIntentRecord rec = ref != null ? ref.get(): null;
14953                if (dumpPackage != null && (rec == null
14954                        || !dumpPackage.equals(rec.key.packageName))) {
14955                    continue;
14956                }
14957                printed = true;
14958                if (rec != null) {
14959                    pw.print("  * "); pw.println(rec);
14960                    if (dumpAll) {
14961                        rec.dump(pw, "    ");
14962                    }
14963                } else {
14964                    pw.print("  * "); pw.println(ref);
14965                }
14966            }
14967        }
14968
14969        if (!printed) {
14970            pw.println("  (nothing)");
14971        }
14972    }
14973
14974    private static final int dumpProcessList(PrintWriter pw,
14975            ActivityManagerService service, List list,
14976            String prefix, String normalLabel, String persistentLabel,
14977            String dumpPackage) {
14978        int numPers = 0;
14979        final int N = list.size()-1;
14980        for (int i=N; i>=0; i--) {
14981            ProcessRecord r = (ProcessRecord)list.get(i);
14982            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14983                continue;
14984            }
14985            pw.println(String.format("%s%s #%2d: %s",
14986                    prefix, (r.persistent ? persistentLabel : normalLabel),
14987                    i, r.toString()));
14988            if (r.persistent) {
14989                numPers++;
14990            }
14991        }
14992        return numPers;
14993    }
14994
14995    private static final boolean dumpProcessOomList(PrintWriter pw,
14996            ActivityManagerService service, List<ProcessRecord> origList,
14997            String prefix, String normalLabel, String persistentLabel,
14998            boolean inclDetails, String dumpPackage) {
14999
15000        ArrayList<Pair<ProcessRecord, Integer>> list
15001                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15002        for (int i=0; i<origList.size(); i++) {
15003            ProcessRecord r = origList.get(i);
15004            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15005                continue;
15006            }
15007            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15008        }
15009
15010        if (list.size() <= 0) {
15011            return false;
15012        }
15013
15014        Comparator<Pair<ProcessRecord, Integer>> comparator
15015                = new Comparator<Pair<ProcessRecord, Integer>>() {
15016            @Override
15017            public int compare(Pair<ProcessRecord, Integer> object1,
15018                    Pair<ProcessRecord, Integer> object2) {
15019                if (object1.first.setAdj != object2.first.setAdj) {
15020                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15021                }
15022                if (object1.first.setProcState != object2.first.setProcState) {
15023                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15024                }
15025                if (object1.second.intValue() != object2.second.intValue()) {
15026                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15027                }
15028                return 0;
15029            }
15030        };
15031
15032        Collections.sort(list, comparator);
15033
15034        final long curRealtime = SystemClock.elapsedRealtime();
15035        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15036        final long curUptime = SystemClock.uptimeMillis();
15037        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15038
15039        for (int i=list.size()-1; i>=0; i--) {
15040            ProcessRecord r = list.get(i).first;
15041            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15042            char schedGroup;
15043            switch (r.setSchedGroup) {
15044                case ProcessList.SCHED_GROUP_BACKGROUND:
15045                    schedGroup = 'B';
15046                    break;
15047                case ProcessList.SCHED_GROUP_DEFAULT:
15048                    schedGroup = 'F';
15049                    break;
15050                case ProcessList.SCHED_GROUP_TOP_APP:
15051                    schedGroup = 'T';
15052                    break;
15053                default:
15054                    schedGroup = '?';
15055                    break;
15056            }
15057            char foreground;
15058            if (r.foregroundActivities) {
15059                foreground = 'A';
15060            } else if (r.foregroundServices) {
15061                foreground = 'S';
15062            } else {
15063                foreground = ' ';
15064            }
15065            String procState = ProcessList.makeProcStateString(r.curProcState);
15066            pw.print(prefix);
15067            pw.print(r.persistent ? persistentLabel : normalLabel);
15068            pw.print(" #");
15069            int num = (origList.size()-1)-list.get(i).second;
15070            if (num < 10) pw.print(' ');
15071            pw.print(num);
15072            pw.print(": ");
15073            pw.print(oomAdj);
15074            pw.print(' ');
15075            pw.print(schedGroup);
15076            pw.print('/');
15077            pw.print(foreground);
15078            pw.print('/');
15079            pw.print(procState);
15080            pw.print(" trm:");
15081            if (r.trimMemoryLevel < 10) pw.print(' ');
15082            pw.print(r.trimMemoryLevel);
15083            pw.print(' ');
15084            pw.print(r.toShortString());
15085            pw.print(" (");
15086            pw.print(r.adjType);
15087            pw.println(')');
15088            if (r.adjSource != null || r.adjTarget != null) {
15089                pw.print(prefix);
15090                pw.print("    ");
15091                if (r.adjTarget instanceof ComponentName) {
15092                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15093                } else if (r.adjTarget != null) {
15094                    pw.print(r.adjTarget.toString());
15095                } else {
15096                    pw.print("{null}");
15097                }
15098                pw.print("<=");
15099                if (r.adjSource instanceof ProcessRecord) {
15100                    pw.print("Proc{");
15101                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15102                    pw.println("}");
15103                } else if (r.adjSource != null) {
15104                    pw.println(r.adjSource.toString());
15105                } else {
15106                    pw.println("{null}");
15107                }
15108            }
15109            if (inclDetails) {
15110                pw.print(prefix);
15111                pw.print("    ");
15112                pw.print("oom: max="); pw.print(r.maxAdj);
15113                pw.print(" curRaw="); pw.print(r.curRawAdj);
15114                pw.print(" setRaw="); pw.print(r.setRawAdj);
15115                pw.print(" cur="); pw.print(r.curAdj);
15116                pw.print(" set="); pw.println(r.setAdj);
15117                pw.print(prefix);
15118                pw.print("    ");
15119                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15120                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15121                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15122                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15123                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15124                pw.println();
15125                pw.print(prefix);
15126                pw.print("    ");
15127                pw.print("cached="); pw.print(r.cached);
15128                pw.print(" empty="); pw.print(r.empty);
15129                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15130
15131                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15132                    if (r.lastWakeTime != 0) {
15133                        long wtime;
15134                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15135                        synchronized (stats) {
15136                            wtime = stats.getProcessWakeTime(r.info.uid,
15137                                    r.pid, curRealtime);
15138                        }
15139                        long timeUsed = wtime - r.lastWakeTime;
15140                        pw.print(prefix);
15141                        pw.print("    ");
15142                        pw.print("keep awake over ");
15143                        TimeUtils.formatDuration(realtimeSince, pw);
15144                        pw.print(" used ");
15145                        TimeUtils.formatDuration(timeUsed, pw);
15146                        pw.print(" (");
15147                        pw.print((timeUsed*100)/realtimeSince);
15148                        pw.println("%)");
15149                    }
15150                    if (r.lastCpuTime != 0) {
15151                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15152                        pw.print(prefix);
15153                        pw.print("    ");
15154                        pw.print("run cpu over ");
15155                        TimeUtils.formatDuration(uptimeSince, pw);
15156                        pw.print(" used ");
15157                        TimeUtils.formatDuration(timeUsed, pw);
15158                        pw.print(" (");
15159                        pw.print((timeUsed*100)/uptimeSince);
15160                        pw.println("%)");
15161                    }
15162                }
15163            }
15164        }
15165        return true;
15166    }
15167
15168    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15169            String[] args) {
15170        ArrayList<ProcessRecord> procs;
15171        synchronized (this) {
15172            if (args != null && args.length > start
15173                    && args[start].charAt(0) != '-') {
15174                procs = new ArrayList<ProcessRecord>();
15175                int pid = -1;
15176                try {
15177                    pid = Integer.parseInt(args[start]);
15178                } catch (NumberFormatException e) {
15179                }
15180                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15181                    ProcessRecord proc = mLruProcesses.get(i);
15182                    if (proc.pid == pid) {
15183                        procs.add(proc);
15184                    } else if (allPkgs && proc.pkgList != null
15185                            && proc.pkgList.containsKey(args[start])) {
15186                        procs.add(proc);
15187                    } else if (proc.processName.equals(args[start])) {
15188                        procs.add(proc);
15189                    }
15190                }
15191                if (procs.size() <= 0) {
15192                    return null;
15193                }
15194            } else {
15195                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15196            }
15197        }
15198        return procs;
15199    }
15200
15201    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15202            PrintWriter pw, String[] args) {
15203        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15204        if (procs == null) {
15205            pw.println("No process found for: " + args[0]);
15206            return;
15207        }
15208
15209        long uptime = SystemClock.uptimeMillis();
15210        long realtime = SystemClock.elapsedRealtime();
15211        pw.println("Applications Graphics Acceleration Info:");
15212        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15213
15214        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15215            ProcessRecord r = procs.get(i);
15216            if (r.thread != null) {
15217                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15218                pw.flush();
15219                try {
15220                    TransferPipe tp = new TransferPipe();
15221                    try {
15222                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15223                        tp.go(fd);
15224                    } finally {
15225                        tp.kill();
15226                    }
15227                } catch (IOException e) {
15228                    pw.println("Failure while dumping the app: " + r);
15229                    pw.flush();
15230                } catch (RemoteException e) {
15231                    pw.println("Got a RemoteException while dumping the app " + r);
15232                    pw.flush();
15233                }
15234            }
15235        }
15236    }
15237
15238    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15239        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15240        if (procs == null) {
15241            pw.println("No process found for: " + args[0]);
15242            return;
15243        }
15244
15245        pw.println("Applications Database Info:");
15246
15247        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15248            ProcessRecord r = procs.get(i);
15249            if (r.thread != null) {
15250                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15251                pw.flush();
15252                try {
15253                    TransferPipe tp = new TransferPipe();
15254                    try {
15255                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15256                        tp.go(fd);
15257                    } finally {
15258                        tp.kill();
15259                    }
15260                } catch (IOException e) {
15261                    pw.println("Failure while dumping the app: " + r);
15262                    pw.flush();
15263                } catch (RemoteException e) {
15264                    pw.println("Got a RemoteException while dumping the app " + r);
15265                    pw.flush();
15266                }
15267            }
15268        }
15269    }
15270
15271    final static class MemItem {
15272        final boolean isProc;
15273        final String label;
15274        final String shortLabel;
15275        final long pss;
15276        final long swapPss;
15277        final int id;
15278        final boolean hasActivities;
15279        ArrayList<MemItem> subitems;
15280
15281        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15282                boolean _hasActivities) {
15283            isProc = true;
15284            label = _label;
15285            shortLabel = _shortLabel;
15286            pss = _pss;
15287            swapPss = _swapPss;
15288            id = _id;
15289            hasActivities = _hasActivities;
15290        }
15291
15292        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15293            isProc = false;
15294            label = _label;
15295            shortLabel = _shortLabel;
15296            pss = _pss;
15297            swapPss = _swapPss;
15298            id = _id;
15299            hasActivities = false;
15300        }
15301    }
15302
15303    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15304            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15305        if (sort && !isCompact) {
15306            Collections.sort(items, new Comparator<MemItem>() {
15307                @Override
15308                public int compare(MemItem lhs, MemItem rhs) {
15309                    if (lhs.pss < rhs.pss) {
15310                        return 1;
15311                    } else if (lhs.pss > rhs.pss) {
15312                        return -1;
15313                    }
15314                    return 0;
15315                }
15316            });
15317        }
15318
15319        for (int i=0; i<items.size(); i++) {
15320            MemItem mi = items.get(i);
15321            if (!isCompact) {
15322                if (dumpSwapPss) {
15323                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15324                            mi.label, stringifyKBSize(mi.swapPss));
15325                } else {
15326                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15327                }
15328            } else if (mi.isProc) {
15329                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15330                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15331                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15332                pw.println(mi.hasActivities ? ",a" : ",e");
15333            } else {
15334                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15335                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15336            }
15337            if (mi.subitems != null) {
15338                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15339                        true, isCompact, dumpSwapPss);
15340            }
15341        }
15342    }
15343
15344    // These are in KB.
15345    static final long[] DUMP_MEM_BUCKETS = new long[] {
15346        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15347        120*1024, 160*1024, 200*1024,
15348        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15349        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15350    };
15351
15352    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15353            boolean stackLike) {
15354        int start = label.lastIndexOf('.');
15355        if (start >= 0) start++;
15356        else start = 0;
15357        int end = label.length();
15358        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15359            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15360                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15361                out.append(bucket);
15362                out.append(stackLike ? "MB." : "MB ");
15363                out.append(label, start, end);
15364                return;
15365            }
15366        }
15367        out.append(memKB/1024);
15368        out.append(stackLike ? "MB." : "MB ");
15369        out.append(label, start, end);
15370    }
15371
15372    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15373            ProcessList.NATIVE_ADJ,
15374            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15375            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15376            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15377            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15378            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15379            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15380    };
15381    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15382            "Native",
15383            "System", "Persistent", "Persistent Service", "Foreground",
15384            "Visible", "Perceptible",
15385            "Heavy Weight", "Backup",
15386            "A Services", "Home",
15387            "Previous", "B Services", "Cached"
15388    };
15389    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15390            "native",
15391            "sys", "pers", "persvc", "fore",
15392            "vis", "percept",
15393            "heavy", "backup",
15394            "servicea", "home",
15395            "prev", "serviceb", "cached"
15396    };
15397
15398    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15399            long realtime, boolean isCheckinRequest, boolean isCompact) {
15400        if (isCompact) {
15401            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15402        }
15403        if (isCheckinRequest || isCompact) {
15404            // short checkin version
15405            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15406        } else {
15407            pw.println("Applications Memory Usage (in Kilobytes):");
15408            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15409        }
15410    }
15411
15412    private static final int KSM_SHARED = 0;
15413    private static final int KSM_SHARING = 1;
15414    private static final int KSM_UNSHARED = 2;
15415    private static final int KSM_VOLATILE = 3;
15416
15417    private final long[] getKsmInfo() {
15418        long[] longOut = new long[4];
15419        final int[] SINGLE_LONG_FORMAT = new int[] {
15420            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15421        };
15422        long[] longTmp = new long[1];
15423        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15424                SINGLE_LONG_FORMAT, null, longTmp, null);
15425        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15426        longTmp[0] = 0;
15427        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15428                SINGLE_LONG_FORMAT, null, longTmp, null);
15429        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15430        longTmp[0] = 0;
15431        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15432                SINGLE_LONG_FORMAT, null, longTmp, null);
15433        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15434        longTmp[0] = 0;
15435        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15436                SINGLE_LONG_FORMAT, null, longTmp, null);
15437        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15438        return longOut;
15439    }
15440
15441    private static String stringifySize(long size, int order) {
15442        Locale locale = Locale.US;
15443        switch (order) {
15444            case 1:
15445                return String.format(locale, "%,13d", size);
15446            case 1024:
15447                return String.format(locale, "%,9dK", size / 1024);
15448            case 1024 * 1024:
15449                return String.format(locale, "%,5dM", size / 1024 / 1024);
15450            case 1024 * 1024 * 1024:
15451                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15452            default:
15453                throw new IllegalArgumentException("Invalid size order");
15454        }
15455    }
15456
15457    private static String stringifyKBSize(long size) {
15458        return stringifySize(size * 1024, 1024);
15459    }
15460
15461    // Update this version number in case you change the 'compact' format
15462    private static final int MEMINFO_COMPACT_VERSION = 1;
15463
15464    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15465            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15466        boolean dumpDetails = false;
15467        boolean dumpFullDetails = false;
15468        boolean dumpDalvik = false;
15469        boolean dumpSummaryOnly = false;
15470        boolean dumpUnreachable = false;
15471        boolean oomOnly = false;
15472        boolean isCompact = false;
15473        boolean localOnly = false;
15474        boolean packages = false;
15475        boolean isCheckinRequest = false;
15476        boolean dumpSwapPss = false;
15477
15478        int opti = 0;
15479        while (opti < args.length) {
15480            String opt = args[opti];
15481            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15482                break;
15483            }
15484            opti++;
15485            if ("-a".equals(opt)) {
15486                dumpDetails = true;
15487                dumpFullDetails = true;
15488                dumpDalvik = true;
15489                dumpSwapPss = true;
15490            } else if ("-d".equals(opt)) {
15491                dumpDalvik = true;
15492            } else if ("-c".equals(opt)) {
15493                isCompact = true;
15494            } else if ("-s".equals(opt)) {
15495                dumpDetails = true;
15496                dumpSummaryOnly = true;
15497            } else if ("-S".equals(opt)) {
15498                dumpSwapPss = true;
15499            } else if ("--unreachable".equals(opt)) {
15500                dumpUnreachable = true;
15501            } else if ("--oom".equals(opt)) {
15502                oomOnly = true;
15503            } else if ("--local".equals(opt)) {
15504                localOnly = true;
15505            } else if ("--package".equals(opt)) {
15506                packages = true;
15507            } else if ("--checkin".equals(opt)) {
15508                isCheckinRequest = true;
15509
15510            } else if ("-h".equals(opt)) {
15511                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15512                pw.println("  -a: include all available information for each process.");
15513                pw.println("  -d: include dalvik details.");
15514                pw.println("  -c: dump in a compact machine-parseable representation.");
15515                pw.println("  -s: dump only summary of application memory usage.");
15516                pw.println("  -S: dump also SwapPss.");
15517                pw.println("  --oom: only show processes organized by oom adj.");
15518                pw.println("  --local: only collect details locally, don't call process.");
15519                pw.println("  --package: interpret process arg as package, dumping all");
15520                pw.println("             processes that have loaded that package.");
15521                pw.println("  --checkin: dump data for a checkin");
15522                pw.println("If [process] is specified it can be the name or ");
15523                pw.println("pid of a specific process to dump.");
15524                return;
15525            } else {
15526                pw.println("Unknown argument: " + opt + "; use -h for help");
15527            }
15528        }
15529
15530        long uptime = SystemClock.uptimeMillis();
15531        long realtime = SystemClock.elapsedRealtime();
15532        final long[] tmpLong = new long[1];
15533
15534        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15535        if (procs == null) {
15536            // No Java processes.  Maybe they want to print a native process.
15537            if (args != null && args.length > opti
15538                    && args[opti].charAt(0) != '-') {
15539                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15540                        = new ArrayList<ProcessCpuTracker.Stats>();
15541                updateCpuStatsNow();
15542                int findPid = -1;
15543                try {
15544                    findPid = Integer.parseInt(args[opti]);
15545                } catch (NumberFormatException e) {
15546                }
15547                synchronized (mProcessCpuTracker) {
15548                    final int N = mProcessCpuTracker.countStats();
15549                    for (int i=0; i<N; i++) {
15550                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15551                        if (st.pid == findPid || (st.baseName != null
15552                                && st.baseName.equals(args[opti]))) {
15553                            nativeProcs.add(st);
15554                        }
15555                    }
15556                }
15557                if (nativeProcs.size() > 0) {
15558                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15559                            isCompact);
15560                    Debug.MemoryInfo mi = null;
15561                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15562                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15563                        final int pid = r.pid;
15564                        if (!isCheckinRequest && dumpDetails) {
15565                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15566                        }
15567                        if (mi == null) {
15568                            mi = new Debug.MemoryInfo();
15569                        }
15570                        if (dumpDetails || (!brief && !oomOnly)) {
15571                            Debug.getMemoryInfo(pid, mi);
15572                        } else {
15573                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15574                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15575                        }
15576                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15577                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15578                        if (isCheckinRequest) {
15579                            pw.println();
15580                        }
15581                    }
15582                    return;
15583                }
15584            }
15585            pw.println("No process found for: " + args[opti]);
15586            return;
15587        }
15588
15589        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15590            dumpDetails = true;
15591        }
15592
15593        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15594
15595        String[] innerArgs = new String[args.length-opti];
15596        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15597
15598        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15599        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15600        long nativePss = 0;
15601        long nativeSwapPss = 0;
15602        long dalvikPss = 0;
15603        long dalvikSwapPss = 0;
15604        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15605                EmptyArray.LONG;
15606        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15607                EmptyArray.LONG;
15608        long otherPss = 0;
15609        long otherSwapPss = 0;
15610        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15611        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15612
15613        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15614        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15615        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15616                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15617
15618        long totalPss = 0;
15619        long totalSwapPss = 0;
15620        long cachedPss = 0;
15621        long cachedSwapPss = 0;
15622        boolean hasSwapPss = false;
15623
15624        Debug.MemoryInfo mi = null;
15625        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15626            final ProcessRecord r = procs.get(i);
15627            final IApplicationThread thread;
15628            final int pid;
15629            final int oomAdj;
15630            final boolean hasActivities;
15631            synchronized (this) {
15632                thread = r.thread;
15633                pid = r.pid;
15634                oomAdj = r.getSetAdjWithServices();
15635                hasActivities = r.activities.size() > 0;
15636            }
15637            if (thread != null) {
15638                if (!isCheckinRequest && dumpDetails) {
15639                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15640                }
15641                if (mi == null) {
15642                    mi = new Debug.MemoryInfo();
15643                }
15644                if (dumpDetails || (!brief && !oomOnly)) {
15645                    Debug.getMemoryInfo(pid, mi);
15646                    hasSwapPss = mi.hasSwappedOutPss;
15647                } else {
15648                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15649                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15650                }
15651                if (dumpDetails) {
15652                    if (localOnly) {
15653                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15654                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15655                        if (isCheckinRequest) {
15656                            pw.println();
15657                        }
15658                    } else {
15659                        try {
15660                            pw.flush();
15661                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15662                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15663                        } catch (RemoteException e) {
15664                            if (!isCheckinRequest) {
15665                                pw.println("Got RemoteException!");
15666                                pw.flush();
15667                            }
15668                        }
15669                    }
15670                }
15671
15672                final long myTotalPss = mi.getTotalPss();
15673                final long myTotalUss = mi.getTotalUss();
15674                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15675
15676                synchronized (this) {
15677                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15678                        // Record this for posterity if the process has been stable.
15679                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15680                    }
15681                }
15682
15683                if (!isCheckinRequest && mi != null) {
15684                    totalPss += myTotalPss;
15685                    totalSwapPss += myTotalSwapPss;
15686                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15687                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15688                            myTotalSwapPss, pid, hasActivities);
15689                    procMems.add(pssItem);
15690                    procMemsMap.put(pid, pssItem);
15691
15692                    nativePss += mi.nativePss;
15693                    nativeSwapPss += mi.nativeSwappedOutPss;
15694                    dalvikPss += mi.dalvikPss;
15695                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15696                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15697                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15698                        dalvikSubitemSwapPss[j] +=
15699                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15700                    }
15701                    otherPss += mi.otherPss;
15702                    otherSwapPss += mi.otherSwappedOutPss;
15703                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15704                        long mem = mi.getOtherPss(j);
15705                        miscPss[j] += mem;
15706                        otherPss -= mem;
15707                        mem = mi.getOtherSwappedOutPss(j);
15708                        miscSwapPss[j] += mem;
15709                        otherSwapPss -= mem;
15710                    }
15711
15712                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15713                        cachedPss += myTotalPss;
15714                        cachedSwapPss += myTotalSwapPss;
15715                    }
15716
15717                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15718                        if (oomIndex == (oomPss.length - 1)
15719                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15720                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15721                            oomPss[oomIndex] += myTotalPss;
15722                            oomSwapPss[oomIndex] += myTotalSwapPss;
15723                            if (oomProcs[oomIndex] == null) {
15724                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15725                            }
15726                            oomProcs[oomIndex].add(pssItem);
15727                            break;
15728                        }
15729                    }
15730                }
15731            }
15732        }
15733
15734        long nativeProcTotalPss = 0;
15735
15736        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15737            // If we are showing aggregations, also look for native processes to
15738            // include so that our aggregations are more accurate.
15739            updateCpuStatsNow();
15740            mi = null;
15741            synchronized (mProcessCpuTracker) {
15742                final int N = mProcessCpuTracker.countStats();
15743                for (int i=0; i<N; i++) {
15744                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15745                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15746                        if (mi == null) {
15747                            mi = new Debug.MemoryInfo();
15748                        }
15749                        if (!brief && !oomOnly) {
15750                            Debug.getMemoryInfo(st.pid, mi);
15751                        } else {
15752                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15753                            mi.nativePrivateDirty = (int)tmpLong[0];
15754                        }
15755
15756                        final long myTotalPss = mi.getTotalPss();
15757                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15758                        totalPss += myTotalPss;
15759                        nativeProcTotalPss += myTotalPss;
15760
15761                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15762                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15763                        procMems.add(pssItem);
15764
15765                        nativePss += mi.nativePss;
15766                        nativeSwapPss += mi.nativeSwappedOutPss;
15767                        dalvikPss += mi.dalvikPss;
15768                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15769                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15770                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15771                            dalvikSubitemSwapPss[j] +=
15772                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15773                        }
15774                        otherPss += mi.otherPss;
15775                        otherSwapPss += mi.otherSwappedOutPss;
15776                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15777                            long mem = mi.getOtherPss(j);
15778                            miscPss[j] += mem;
15779                            otherPss -= mem;
15780                            mem = mi.getOtherSwappedOutPss(j);
15781                            miscSwapPss[j] += mem;
15782                            otherSwapPss -= mem;
15783                        }
15784                        oomPss[0] += myTotalPss;
15785                        oomSwapPss[0] += myTotalSwapPss;
15786                        if (oomProcs[0] == null) {
15787                            oomProcs[0] = new ArrayList<MemItem>();
15788                        }
15789                        oomProcs[0].add(pssItem);
15790                    }
15791                }
15792            }
15793
15794            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15795
15796            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15797            final MemItem dalvikItem =
15798                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15799            if (dalvikSubitemPss.length > 0) {
15800                dalvikItem.subitems = new ArrayList<MemItem>();
15801                for (int j=0; j<dalvikSubitemPss.length; j++) {
15802                    final String name = Debug.MemoryInfo.getOtherLabel(
15803                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15804                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15805                                    dalvikSubitemSwapPss[j], j));
15806                }
15807            }
15808            catMems.add(dalvikItem);
15809            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15810            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15811                String label = Debug.MemoryInfo.getOtherLabel(j);
15812                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15813            }
15814
15815            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15816            for (int j=0; j<oomPss.length; j++) {
15817                if (oomPss[j] != 0) {
15818                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15819                            : DUMP_MEM_OOM_LABEL[j];
15820                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15821                            DUMP_MEM_OOM_ADJ[j]);
15822                    item.subitems = oomProcs[j];
15823                    oomMems.add(item);
15824                }
15825            }
15826
15827            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15828            if (!brief && !oomOnly && !isCompact) {
15829                pw.println();
15830                pw.println("Total PSS by process:");
15831                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15832                pw.println();
15833            }
15834            if (!isCompact) {
15835                pw.println("Total PSS by OOM adjustment:");
15836            }
15837            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15838            if (!brief && !oomOnly) {
15839                PrintWriter out = categoryPw != null ? categoryPw : pw;
15840                if (!isCompact) {
15841                    out.println();
15842                    out.println("Total PSS by category:");
15843                }
15844                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15845            }
15846            if (!isCompact) {
15847                pw.println();
15848            }
15849            MemInfoReader memInfo = new MemInfoReader();
15850            memInfo.readMemInfo();
15851            if (nativeProcTotalPss > 0) {
15852                synchronized (this) {
15853                    final long cachedKb = memInfo.getCachedSizeKb();
15854                    final long freeKb = memInfo.getFreeSizeKb();
15855                    final long zramKb = memInfo.getZramTotalSizeKb();
15856                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15857                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15858                            kernelKb*1024, nativeProcTotalPss*1024);
15859                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15860                            nativeProcTotalPss);
15861                }
15862            }
15863            if (!brief) {
15864                if (!isCompact) {
15865                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15866                    pw.print(" (status ");
15867                    switch (mLastMemoryLevel) {
15868                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15869                            pw.println("normal)");
15870                            break;
15871                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15872                            pw.println("moderate)");
15873                            break;
15874                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15875                            pw.println("low)");
15876                            break;
15877                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15878                            pw.println("critical)");
15879                            break;
15880                        default:
15881                            pw.print(mLastMemoryLevel);
15882                            pw.println(")");
15883                            break;
15884                    }
15885                    pw.print(" Free RAM: ");
15886                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15887                            + memInfo.getFreeSizeKb()));
15888                    pw.print(" (");
15889                    pw.print(stringifyKBSize(cachedPss));
15890                    pw.print(" cached pss + ");
15891                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15892                    pw.print(" cached kernel + ");
15893                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15894                    pw.println(" free)");
15895                } else {
15896                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15897                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15898                            + memInfo.getFreeSizeKb()); pw.print(",");
15899                    pw.println(totalPss - cachedPss);
15900                }
15901            }
15902            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15903                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15904                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15905            if (!isCompact) {
15906                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15907                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15908                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15909                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15910                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15911            } else {
15912                pw.print("lostram,"); pw.println(lostRAM);
15913            }
15914            if (!brief) {
15915                if (memInfo.getZramTotalSizeKb() != 0) {
15916                    if (!isCompact) {
15917                        pw.print("     ZRAM: ");
15918                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15919                                pw.print(" physical used for ");
15920                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15921                                        - memInfo.getSwapFreeSizeKb()));
15922                                pw.print(" in swap (");
15923                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15924                                pw.println(" total swap)");
15925                    } else {
15926                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15927                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15928                                pw.println(memInfo.getSwapFreeSizeKb());
15929                    }
15930                }
15931                final long[] ksm = getKsmInfo();
15932                if (!isCompact) {
15933                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15934                            || ksm[KSM_VOLATILE] != 0) {
15935                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15936                                pw.print(" saved from shared ");
15937                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15938                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15939                                pw.print(" unshared; ");
15940                                pw.print(stringifyKBSize(
15941                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15942                    }
15943                    pw.print("   Tuning: ");
15944                    pw.print(ActivityManager.staticGetMemoryClass());
15945                    pw.print(" (large ");
15946                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15947                    pw.print("), oom ");
15948                    pw.print(stringifySize(
15949                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15950                    pw.print(", restore limit ");
15951                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15952                    if (ActivityManager.isLowRamDeviceStatic()) {
15953                        pw.print(" (low-ram)");
15954                    }
15955                    if (ActivityManager.isHighEndGfx()) {
15956                        pw.print(" (high-end-gfx)");
15957                    }
15958                    pw.println();
15959                } else {
15960                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15961                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15962                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15963                    pw.print("tuning,");
15964                    pw.print(ActivityManager.staticGetMemoryClass());
15965                    pw.print(',');
15966                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15967                    pw.print(',');
15968                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15969                    if (ActivityManager.isLowRamDeviceStatic()) {
15970                        pw.print(",low-ram");
15971                    }
15972                    if (ActivityManager.isHighEndGfx()) {
15973                        pw.print(",high-end-gfx");
15974                    }
15975                    pw.println();
15976                }
15977            }
15978        }
15979    }
15980
15981    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15982            long memtrack, String name) {
15983        sb.append("  ");
15984        sb.append(ProcessList.makeOomAdjString(oomAdj));
15985        sb.append(' ');
15986        sb.append(ProcessList.makeProcStateString(procState));
15987        sb.append(' ');
15988        ProcessList.appendRamKb(sb, pss);
15989        sb.append(": ");
15990        sb.append(name);
15991        if (memtrack > 0) {
15992            sb.append(" (");
15993            sb.append(stringifyKBSize(memtrack));
15994            sb.append(" memtrack)");
15995        }
15996    }
15997
15998    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15999        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16000        sb.append(" (pid ");
16001        sb.append(mi.pid);
16002        sb.append(") ");
16003        sb.append(mi.adjType);
16004        sb.append('\n');
16005        if (mi.adjReason != null) {
16006            sb.append("                      ");
16007            sb.append(mi.adjReason);
16008            sb.append('\n');
16009        }
16010    }
16011
16012    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16013        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16014        for (int i=0, N=memInfos.size(); i<N; i++) {
16015            ProcessMemInfo mi = memInfos.get(i);
16016            infoMap.put(mi.pid, mi);
16017        }
16018        updateCpuStatsNow();
16019        long[] memtrackTmp = new long[1];
16020        synchronized (mProcessCpuTracker) {
16021            final int N = mProcessCpuTracker.countStats();
16022            for (int i=0; i<N; i++) {
16023                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16024                if (st.vsize > 0) {
16025                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16026                    if (pss > 0) {
16027                        if (infoMap.indexOfKey(st.pid) < 0) {
16028                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16029                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16030                            mi.pss = pss;
16031                            mi.memtrack = memtrackTmp[0];
16032                            memInfos.add(mi);
16033                        }
16034                    }
16035                }
16036            }
16037        }
16038
16039        long totalPss = 0;
16040        long totalMemtrack = 0;
16041        for (int i=0, N=memInfos.size(); i<N; i++) {
16042            ProcessMemInfo mi = memInfos.get(i);
16043            if (mi.pss == 0) {
16044                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16045                mi.memtrack = memtrackTmp[0];
16046            }
16047            totalPss += mi.pss;
16048            totalMemtrack += mi.memtrack;
16049        }
16050        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16051            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16052                if (lhs.oomAdj != rhs.oomAdj) {
16053                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16054                }
16055                if (lhs.pss != rhs.pss) {
16056                    return lhs.pss < rhs.pss ? 1 : -1;
16057                }
16058                return 0;
16059            }
16060        });
16061
16062        StringBuilder tag = new StringBuilder(128);
16063        StringBuilder stack = new StringBuilder(128);
16064        tag.append("Low on memory -- ");
16065        appendMemBucket(tag, totalPss, "total", false);
16066        appendMemBucket(stack, totalPss, "total", true);
16067
16068        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16069        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16070        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16071
16072        boolean firstLine = true;
16073        int lastOomAdj = Integer.MIN_VALUE;
16074        long extraNativeRam = 0;
16075        long extraNativeMemtrack = 0;
16076        long cachedPss = 0;
16077        for (int i=0, N=memInfos.size(); i<N; i++) {
16078            ProcessMemInfo mi = memInfos.get(i);
16079
16080            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16081                cachedPss += mi.pss;
16082            }
16083
16084            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16085                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16086                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16087                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16088                if (lastOomAdj != mi.oomAdj) {
16089                    lastOomAdj = mi.oomAdj;
16090                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16091                        tag.append(" / ");
16092                    }
16093                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16094                        if (firstLine) {
16095                            stack.append(":");
16096                            firstLine = false;
16097                        }
16098                        stack.append("\n\t at ");
16099                    } else {
16100                        stack.append("$");
16101                    }
16102                } else {
16103                    tag.append(" ");
16104                    stack.append("$");
16105                }
16106                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16107                    appendMemBucket(tag, mi.pss, mi.name, false);
16108                }
16109                appendMemBucket(stack, mi.pss, mi.name, true);
16110                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16111                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16112                    stack.append("(");
16113                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16114                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16115                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16116                            stack.append(":");
16117                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16118                        }
16119                    }
16120                    stack.append(")");
16121                }
16122            }
16123
16124            appendMemInfo(fullNativeBuilder, mi);
16125            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16126                // The short form only has native processes that are >= 512K.
16127                if (mi.pss >= 512) {
16128                    appendMemInfo(shortNativeBuilder, mi);
16129                } else {
16130                    extraNativeRam += mi.pss;
16131                    extraNativeMemtrack += mi.memtrack;
16132                }
16133            } else {
16134                // Short form has all other details, but if we have collected RAM
16135                // from smaller native processes let's dump a summary of that.
16136                if (extraNativeRam > 0) {
16137                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16138                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16139                    shortNativeBuilder.append('\n');
16140                    extraNativeRam = 0;
16141                }
16142                appendMemInfo(fullJavaBuilder, mi);
16143            }
16144        }
16145
16146        fullJavaBuilder.append("           ");
16147        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16148        fullJavaBuilder.append(": TOTAL");
16149        if (totalMemtrack > 0) {
16150            fullJavaBuilder.append(" (");
16151            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16152            fullJavaBuilder.append(" memtrack)");
16153        } else {
16154        }
16155        fullJavaBuilder.append("\n");
16156
16157        MemInfoReader memInfo = new MemInfoReader();
16158        memInfo.readMemInfo();
16159        final long[] infos = memInfo.getRawInfo();
16160
16161        StringBuilder memInfoBuilder = new StringBuilder(1024);
16162        Debug.getMemInfo(infos);
16163        memInfoBuilder.append("  MemInfo: ");
16164        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16165        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16166        memInfoBuilder.append(stringifyKBSize(
16167                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16168        memInfoBuilder.append(stringifyKBSize(
16169                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16170        memInfoBuilder.append(stringifyKBSize(
16171                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16172        memInfoBuilder.append("           ");
16173        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16174        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16175        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16176        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16177        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16178            memInfoBuilder.append("  ZRAM: ");
16179            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16180            memInfoBuilder.append(" RAM, ");
16181            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16182            memInfoBuilder.append(" swap total, ");
16183            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16184            memInfoBuilder.append(" swap free\n");
16185        }
16186        final long[] ksm = getKsmInfo();
16187        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16188                || ksm[KSM_VOLATILE] != 0) {
16189            memInfoBuilder.append("  KSM: ");
16190            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16191            memInfoBuilder.append(" saved from shared ");
16192            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16193            memInfoBuilder.append("\n       ");
16194            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16195            memInfoBuilder.append(" unshared; ");
16196            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16197            memInfoBuilder.append(" volatile\n");
16198        }
16199        memInfoBuilder.append("  Free RAM: ");
16200        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16201                + memInfo.getFreeSizeKb()));
16202        memInfoBuilder.append("\n");
16203        memInfoBuilder.append("  Used RAM: ");
16204        memInfoBuilder.append(stringifyKBSize(
16205                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16206        memInfoBuilder.append("\n");
16207        memInfoBuilder.append("  Lost RAM: ");
16208        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16209                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16210                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16211        memInfoBuilder.append("\n");
16212        Slog.i(TAG, "Low on memory:");
16213        Slog.i(TAG, shortNativeBuilder.toString());
16214        Slog.i(TAG, fullJavaBuilder.toString());
16215        Slog.i(TAG, memInfoBuilder.toString());
16216
16217        StringBuilder dropBuilder = new StringBuilder(1024);
16218        /*
16219        StringWriter oomSw = new StringWriter();
16220        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16221        StringWriter catSw = new StringWriter();
16222        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16223        String[] emptyArgs = new String[] { };
16224        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16225        oomPw.flush();
16226        String oomString = oomSw.toString();
16227        */
16228        dropBuilder.append("Low on memory:");
16229        dropBuilder.append(stack);
16230        dropBuilder.append('\n');
16231        dropBuilder.append(fullNativeBuilder);
16232        dropBuilder.append(fullJavaBuilder);
16233        dropBuilder.append('\n');
16234        dropBuilder.append(memInfoBuilder);
16235        dropBuilder.append('\n');
16236        /*
16237        dropBuilder.append(oomString);
16238        dropBuilder.append('\n');
16239        */
16240        StringWriter catSw = new StringWriter();
16241        synchronized (ActivityManagerService.this) {
16242            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16243            String[] emptyArgs = new String[] { };
16244            catPw.println();
16245            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16246            catPw.println();
16247            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16248                    false, null).dumpLocked();
16249            catPw.println();
16250            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16251            catPw.flush();
16252        }
16253        dropBuilder.append(catSw.toString());
16254        addErrorToDropBox("lowmem", null, "system_server", null,
16255                null, tag.toString(), dropBuilder.toString(), null, null);
16256        //Slog.i(TAG, "Sent to dropbox:");
16257        //Slog.i(TAG, dropBuilder.toString());
16258        synchronized (ActivityManagerService.this) {
16259            long now = SystemClock.uptimeMillis();
16260            if (mLastMemUsageReportTime < now) {
16261                mLastMemUsageReportTime = now;
16262            }
16263        }
16264    }
16265
16266    /**
16267     * Searches array of arguments for the specified string
16268     * @param args array of argument strings
16269     * @param value value to search for
16270     * @return true if the value is contained in the array
16271     */
16272    private static boolean scanArgs(String[] args, String value) {
16273        if (args != null) {
16274            for (String arg : args) {
16275                if (value.equals(arg)) {
16276                    return true;
16277                }
16278            }
16279        }
16280        return false;
16281    }
16282
16283    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16284            ContentProviderRecord cpr, boolean always) {
16285        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16286
16287        if (!inLaunching || always) {
16288            synchronized (cpr) {
16289                cpr.launchingApp = null;
16290                cpr.notifyAll();
16291            }
16292            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16293            String names[] = cpr.info.authority.split(";");
16294            for (int j = 0; j < names.length; j++) {
16295                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16296            }
16297        }
16298
16299        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16300            ContentProviderConnection conn = cpr.connections.get(i);
16301            if (conn.waiting) {
16302                // If this connection is waiting for the provider, then we don't
16303                // need to mess with its process unless we are always removing
16304                // or for some reason the provider is not currently launching.
16305                if (inLaunching && !always) {
16306                    continue;
16307                }
16308            }
16309            ProcessRecord capp = conn.client;
16310            conn.dead = true;
16311            if (conn.stableCount > 0) {
16312                if (!capp.persistent && capp.thread != null
16313                        && capp.pid != 0
16314                        && capp.pid != MY_PID) {
16315                    capp.kill("depends on provider "
16316                            + cpr.name.flattenToShortString()
16317                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16318                }
16319            } else if (capp.thread != null && conn.provider.provider != null) {
16320                try {
16321                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16322                } catch (RemoteException e) {
16323                }
16324                // In the protocol here, we don't expect the client to correctly
16325                // clean up this connection, we'll just remove it.
16326                cpr.connections.remove(i);
16327                if (conn.client.conProviders.remove(conn)) {
16328                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16329                }
16330            }
16331        }
16332
16333        if (inLaunching && always) {
16334            mLaunchingProviders.remove(cpr);
16335        }
16336        return inLaunching;
16337    }
16338
16339    /**
16340     * Main code for cleaning up a process when it has gone away.  This is
16341     * called both as a result of the process dying, or directly when stopping
16342     * a process when running in single process mode.
16343     *
16344     * @return Returns true if the given process has been restarted, so the
16345     * app that was passed in must remain on the process lists.
16346     */
16347    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16348            boolean restarting, boolean allowRestart, int index) {
16349        if (index >= 0) {
16350            removeLruProcessLocked(app);
16351            ProcessList.remove(app.pid);
16352        }
16353
16354        mProcessesToGc.remove(app);
16355        mPendingPssProcesses.remove(app);
16356
16357        // Dismiss any open dialogs.
16358        if (app.crashDialog != null && !app.forceCrashReport) {
16359            app.crashDialog.dismiss();
16360            app.crashDialog = null;
16361        }
16362        if (app.anrDialog != null) {
16363            app.anrDialog.dismiss();
16364            app.anrDialog = null;
16365        }
16366        if (app.waitDialog != null) {
16367            app.waitDialog.dismiss();
16368            app.waitDialog = null;
16369        }
16370
16371        app.crashing = false;
16372        app.notResponding = false;
16373
16374        app.resetPackageList(mProcessStats);
16375        app.unlinkDeathRecipient();
16376        app.makeInactive(mProcessStats);
16377        app.waitingToKill = null;
16378        app.forcingToForeground = null;
16379        updateProcessForegroundLocked(app, false, false);
16380        app.foregroundActivities = false;
16381        app.hasShownUi = false;
16382        app.treatLikeActivity = false;
16383        app.hasAboveClient = false;
16384        app.hasClientActivities = false;
16385
16386        mServices.killServicesLocked(app, allowRestart);
16387
16388        boolean restart = false;
16389
16390        // Remove published content providers.
16391        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16392            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16393            final boolean always = app.bad || !allowRestart;
16394            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16395            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16396                // We left the provider in the launching list, need to
16397                // restart it.
16398                restart = true;
16399            }
16400
16401            cpr.provider = null;
16402            cpr.proc = null;
16403        }
16404        app.pubProviders.clear();
16405
16406        // Take care of any launching providers waiting for this process.
16407        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16408            restart = true;
16409        }
16410
16411        // Unregister from connected content providers.
16412        if (!app.conProviders.isEmpty()) {
16413            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16414                ContentProviderConnection conn = app.conProviders.get(i);
16415                conn.provider.connections.remove(conn);
16416                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16417                        conn.provider.name);
16418            }
16419            app.conProviders.clear();
16420        }
16421
16422        // At this point there may be remaining entries in mLaunchingProviders
16423        // where we were the only one waiting, so they are no longer of use.
16424        // Look for these and clean up if found.
16425        // XXX Commented out for now.  Trying to figure out a way to reproduce
16426        // the actual situation to identify what is actually going on.
16427        if (false) {
16428            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16429                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16430                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16431                    synchronized (cpr) {
16432                        cpr.launchingApp = null;
16433                        cpr.notifyAll();
16434                    }
16435                }
16436            }
16437        }
16438
16439        skipCurrentReceiverLocked(app);
16440
16441        // Unregister any receivers.
16442        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16443            removeReceiverLocked(app.receivers.valueAt(i));
16444        }
16445        app.receivers.clear();
16446
16447        // If the app is undergoing backup, tell the backup manager about it
16448        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16449            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16450                    + mBackupTarget.appInfo + " died during backup");
16451            try {
16452                IBackupManager bm = IBackupManager.Stub.asInterface(
16453                        ServiceManager.getService(Context.BACKUP_SERVICE));
16454                bm.agentDisconnected(app.info.packageName);
16455            } catch (RemoteException e) {
16456                // can't happen; backup manager is local
16457            }
16458        }
16459
16460        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16461            ProcessChangeItem item = mPendingProcessChanges.get(i);
16462            if (item.pid == app.pid) {
16463                mPendingProcessChanges.remove(i);
16464                mAvailProcessChanges.add(item);
16465            }
16466        }
16467        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16468                null).sendToTarget();
16469
16470        // If the caller is restarting this app, then leave it in its
16471        // current lists and let the caller take care of it.
16472        if (restarting) {
16473            return false;
16474        }
16475
16476        if (!app.persistent || app.isolated) {
16477            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16478                    "Removing non-persistent process during cleanup: " + app);
16479            removeProcessNameLocked(app.processName, app.uid);
16480            if (mHeavyWeightProcess == app) {
16481                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16482                        mHeavyWeightProcess.userId, 0));
16483                mHeavyWeightProcess = null;
16484            }
16485        } else if (!app.removed) {
16486            // This app is persistent, so we need to keep its record around.
16487            // If it is not already on the pending app list, add it there
16488            // and start a new process for it.
16489            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16490                mPersistentStartingProcesses.add(app);
16491                restart = true;
16492            }
16493        }
16494        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16495                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16496        mProcessesOnHold.remove(app);
16497
16498        if (app == mHomeProcess) {
16499            mHomeProcess = null;
16500        }
16501        if (app == mPreviousProcess) {
16502            mPreviousProcess = null;
16503        }
16504
16505        if (restart && !app.isolated) {
16506            // We have components that still need to be running in the
16507            // process, so re-launch it.
16508            if (index < 0) {
16509                ProcessList.remove(app.pid);
16510            }
16511            addProcessNameLocked(app);
16512            startProcessLocked(app, "restart", app.processName);
16513            return true;
16514        } else if (app.pid > 0 && app.pid != MY_PID) {
16515            // Goodbye!
16516            boolean removed;
16517            synchronized (mPidsSelfLocked) {
16518                mPidsSelfLocked.remove(app.pid);
16519                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16520            }
16521            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16522            if (app.isolated) {
16523                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16524            }
16525            app.setPid(0);
16526        }
16527        return false;
16528    }
16529
16530    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16531        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16532            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16533            if (cpr.launchingApp == app) {
16534                return true;
16535            }
16536        }
16537        return false;
16538    }
16539
16540    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16541        // Look through the content providers we are waiting to have launched,
16542        // and if any run in this process then either schedule a restart of
16543        // the process or kill the client waiting for it if this process has
16544        // gone bad.
16545        boolean restart = false;
16546        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16547            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16548            if (cpr.launchingApp == app) {
16549                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16550                    restart = true;
16551                } else {
16552                    removeDyingProviderLocked(app, cpr, true);
16553                }
16554            }
16555        }
16556        return restart;
16557    }
16558
16559    // =========================================================
16560    // SERVICES
16561    // =========================================================
16562
16563    @Override
16564    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16565            int flags) {
16566        enforceNotIsolatedCaller("getServices");
16567        synchronized (this) {
16568            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16569        }
16570    }
16571
16572    @Override
16573    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16574        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16575        synchronized (this) {
16576            return mServices.getRunningServiceControlPanelLocked(name);
16577        }
16578    }
16579
16580    @Override
16581    public ComponentName startService(IApplicationThread caller, Intent service,
16582            String resolvedType, String callingPackage, int userId)
16583            throws TransactionTooLargeException {
16584        enforceNotIsolatedCaller("startService");
16585        // Refuse possible leaked file descriptors
16586        if (service != null && service.hasFileDescriptors() == true) {
16587            throw new IllegalArgumentException("File descriptors passed in Intent");
16588        }
16589
16590        if (callingPackage == null) {
16591            throw new IllegalArgumentException("callingPackage cannot be null");
16592        }
16593
16594        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16595                "startService: " + service + " type=" + resolvedType);
16596        synchronized(this) {
16597            final int callingPid = Binder.getCallingPid();
16598            final int callingUid = Binder.getCallingUid();
16599            final long origId = Binder.clearCallingIdentity();
16600            ComponentName res = mServices.startServiceLocked(caller, service,
16601                    resolvedType, callingPid, callingUid, callingPackage, userId);
16602            Binder.restoreCallingIdentity(origId);
16603            return res;
16604        }
16605    }
16606
16607    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16608            String callingPackage, int userId)
16609            throws TransactionTooLargeException {
16610        synchronized(this) {
16611            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16612                    "startServiceInPackage: " + service + " type=" + resolvedType);
16613            final long origId = Binder.clearCallingIdentity();
16614            ComponentName res = mServices.startServiceLocked(null, service,
16615                    resolvedType, -1, uid, callingPackage, userId);
16616            Binder.restoreCallingIdentity(origId);
16617            return res;
16618        }
16619    }
16620
16621    @Override
16622    public int stopService(IApplicationThread caller, Intent service,
16623            String resolvedType, int userId) {
16624        enforceNotIsolatedCaller("stopService");
16625        // Refuse possible leaked file descriptors
16626        if (service != null && service.hasFileDescriptors() == true) {
16627            throw new IllegalArgumentException("File descriptors passed in Intent");
16628        }
16629
16630        synchronized(this) {
16631            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16632        }
16633    }
16634
16635    @Override
16636    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16637        enforceNotIsolatedCaller("peekService");
16638        // Refuse possible leaked file descriptors
16639        if (service != null && service.hasFileDescriptors() == true) {
16640            throw new IllegalArgumentException("File descriptors passed in Intent");
16641        }
16642
16643        if (callingPackage == null) {
16644            throw new IllegalArgumentException("callingPackage cannot be null");
16645        }
16646
16647        synchronized(this) {
16648            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16649        }
16650    }
16651
16652    @Override
16653    public boolean stopServiceToken(ComponentName className, IBinder token,
16654            int startId) {
16655        synchronized(this) {
16656            return mServices.stopServiceTokenLocked(className, token, startId);
16657        }
16658    }
16659
16660    @Override
16661    public void setServiceForeground(ComponentName className, IBinder token,
16662            int id, Notification notification, int flags) {
16663        synchronized(this) {
16664            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16665        }
16666    }
16667
16668    @Override
16669    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16670            boolean requireFull, String name, String callerPackage) {
16671        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16672                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16673    }
16674
16675    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16676            String className, int flags) {
16677        boolean result = false;
16678        // For apps that don't have pre-defined UIDs, check for permission
16679        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16680            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16681                if (ActivityManager.checkUidPermission(
16682                        INTERACT_ACROSS_USERS,
16683                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16684                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16685                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16686                            + " requests FLAG_SINGLE_USER, but app does not hold "
16687                            + INTERACT_ACROSS_USERS;
16688                    Slog.w(TAG, msg);
16689                    throw new SecurityException(msg);
16690                }
16691                // Permission passed
16692                result = true;
16693            }
16694        } else if ("system".equals(componentProcessName)) {
16695            result = true;
16696        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16697            // Phone app and persistent apps are allowed to export singleuser providers.
16698            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16699                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16700        }
16701        if (DEBUG_MU) Slog.v(TAG_MU,
16702                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16703                + Integer.toHexString(flags) + ") = " + result);
16704        return result;
16705    }
16706
16707    /**
16708     * Checks to see if the caller is in the same app as the singleton
16709     * component, or the component is in a special app. It allows special apps
16710     * to export singleton components but prevents exporting singleton
16711     * components for regular apps.
16712     */
16713    boolean isValidSingletonCall(int callingUid, int componentUid) {
16714        int componentAppId = UserHandle.getAppId(componentUid);
16715        return UserHandle.isSameApp(callingUid, componentUid)
16716                || componentAppId == Process.SYSTEM_UID
16717                || componentAppId == Process.PHONE_UID
16718                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16719                        == PackageManager.PERMISSION_GRANTED;
16720    }
16721
16722    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16723            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16724            int userId) throws TransactionTooLargeException {
16725        enforceNotIsolatedCaller("bindService");
16726
16727        // Refuse possible leaked file descriptors
16728        if (service != null && service.hasFileDescriptors() == true) {
16729            throw new IllegalArgumentException("File descriptors passed in Intent");
16730        }
16731
16732        if (callingPackage == null) {
16733            throw new IllegalArgumentException("callingPackage cannot be null");
16734        }
16735
16736        synchronized(this) {
16737            return mServices.bindServiceLocked(caller, token, service,
16738                    resolvedType, connection, flags, callingPackage, userId);
16739        }
16740    }
16741
16742    public boolean unbindService(IServiceConnection connection) {
16743        synchronized (this) {
16744            return mServices.unbindServiceLocked(connection);
16745        }
16746    }
16747
16748    public void publishService(IBinder token, Intent intent, IBinder service) {
16749        // Refuse possible leaked file descriptors
16750        if (intent != null && intent.hasFileDescriptors() == true) {
16751            throw new IllegalArgumentException("File descriptors passed in Intent");
16752        }
16753
16754        synchronized(this) {
16755            if (!(token instanceof ServiceRecord)) {
16756                throw new IllegalArgumentException("Invalid service token");
16757            }
16758            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16759        }
16760    }
16761
16762    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16763        // Refuse possible leaked file descriptors
16764        if (intent != null && intent.hasFileDescriptors() == true) {
16765            throw new IllegalArgumentException("File descriptors passed in Intent");
16766        }
16767
16768        synchronized(this) {
16769            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16770        }
16771    }
16772
16773    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16774        synchronized(this) {
16775            if (!(token instanceof ServiceRecord)) {
16776                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16777                throw new IllegalArgumentException("Invalid service token");
16778            }
16779            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16780        }
16781    }
16782
16783    // =========================================================
16784    // BACKUP AND RESTORE
16785    // =========================================================
16786
16787    // Cause the target app to be launched if necessary and its backup agent
16788    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16789    // activity manager to announce its creation.
16790    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16791        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16792                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16793        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16794
16795        synchronized(this) {
16796            // !!! TODO: currently no check here that we're already bound
16797            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16798            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16799            synchronized (stats) {
16800                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16801            }
16802
16803            // Backup agent is now in use, its package can't be stopped.
16804            try {
16805                AppGlobals.getPackageManager().setPackageStoppedState(
16806                        app.packageName, false, UserHandle.getUserId(app.uid));
16807            } catch (RemoteException e) {
16808            } catch (IllegalArgumentException e) {
16809                Slog.w(TAG, "Failed trying to unstop package "
16810                        + app.packageName + ": " + e);
16811            }
16812
16813            BackupRecord r = new BackupRecord(ss, app, backupMode);
16814            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16815                    ? new ComponentName(app.packageName, app.backupAgentName)
16816                    : new ComponentName("android", "FullBackupAgent");
16817            // startProcessLocked() returns existing proc's record if it's already running
16818            ProcessRecord proc = startProcessLocked(app.processName, app,
16819                    false, 0, "backup", hostingName, false, false, false);
16820            if (proc == null) {
16821                Slog.e(TAG, "Unable to start backup agent process " + r);
16822                return false;
16823            }
16824
16825            r.app = proc;
16826            mBackupTarget = r;
16827            mBackupAppName = app.packageName;
16828
16829            // Try not to kill the process during backup
16830            updateOomAdjLocked(proc);
16831
16832            // If the process is already attached, schedule the creation of the backup agent now.
16833            // If it is not yet live, this will be done when it attaches to the framework.
16834            if (proc.thread != null) {
16835                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16836                try {
16837                    proc.thread.scheduleCreateBackupAgent(app,
16838                            compatibilityInfoForPackageLocked(app), backupMode);
16839                } catch (RemoteException e) {
16840                    // Will time out on the backup manager side
16841                }
16842            } else {
16843                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16844            }
16845            // Invariants: at this point, the target app process exists and the application
16846            // is either already running or in the process of coming up.  mBackupTarget and
16847            // mBackupAppName describe the app, so that when it binds back to the AM we
16848            // know that it's scheduled for a backup-agent operation.
16849        }
16850
16851        return true;
16852    }
16853
16854    @Override
16855    public void clearPendingBackup() {
16856        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16857        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16858
16859        synchronized (this) {
16860            mBackupTarget = null;
16861            mBackupAppName = null;
16862        }
16863    }
16864
16865    // A backup agent has just come up
16866    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16867        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16868                + " = " + agent);
16869
16870        synchronized(this) {
16871            if (!agentPackageName.equals(mBackupAppName)) {
16872                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16873                return;
16874            }
16875        }
16876
16877        long oldIdent = Binder.clearCallingIdentity();
16878        try {
16879            IBackupManager bm = IBackupManager.Stub.asInterface(
16880                    ServiceManager.getService(Context.BACKUP_SERVICE));
16881            bm.agentConnected(agentPackageName, agent);
16882        } catch (RemoteException e) {
16883            // can't happen; the backup manager service is local
16884        } catch (Exception e) {
16885            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16886            e.printStackTrace();
16887        } finally {
16888            Binder.restoreCallingIdentity(oldIdent);
16889        }
16890    }
16891
16892    // done with this agent
16893    public void unbindBackupAgent(ApplicationInfo appInfo) {
16894        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16895        if (appInfo == null) {
16896            Slog.w(TAG, "unbind backup agent for null app");
16897            return;
16898        }
16899
16900        synchronized(this) {
16901            try {
16902                if (mBackupAppName == null) {
16903                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16904                    return;
16905                }
16906
16907                if (!mBackupAppName.equals(appInfo.packageName)) {
16908                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16909                    return;
16910                }
16911
16912                // Not backing this app up any more; reset its OOM adjustment
16913                final ProcessRecord proc = mBackupTarget.app;
16914                updateOomAdjLocked(proc);
16915
16916                // If the app crashed during backup, 'thread' will be null here
16917                if (proc.thread != null) {
16918                    try {
16919                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16920                                compatibilityInfoForPackageLocked(appInfo));
16921                    } catch (Exception e) {
16922                        Slog.e(TAG, "Exception when unbinding backup agent:");
16923                        e.printStackTrace();
16924                    }
16925                }
16926            } finally {
16927                mBackupTarget = null;
16928                mBackupAppName = null;
16929            }
16930        }
16931    }
16932    // =========================================================
16933    // BROADCASTS
16934    // =========================================================
16935
16936    boolean isPendingBroadcastProcessLocked(int pid) {
16937        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16938                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16939    }
16940
16941    void skipPendingBroadcastLocked(int pid) {
16942            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16943            for (BroadcastQueue queue : mBroadcastQueues) {
16944                queue.skipPendingBroadcastLocked(pid);
16945            }
16946    }
16947
16948    // The app just attached; send any pending broadcasts that it should receive
16949    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16950        boolean didSomething = false;
16951        for (BroadcastQueue queue : mBroadcastQueues) {
16952            didSomething |= queue.sendPendingBroadcastsLocked(app);
16953        }
16954        return didSomething;
16955    }
16956
16957    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16958            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16959        enforceNotIsolatedCaller("registerReceiver");
16960        ArrayList<Intent> stickyIntents = null;
16961        ProcessRecord callerApp = null;
16962        int callingUid;
16963        int callingPid;
16964        synchronized(this) {
16965            if (caller != null) {
16966                callerApp = getRecordForAppLocked(caller);
16967                if (callerApp == null) {
16968                    throw new SecurityException(
16969                            "Unable to find app for caller " + caller
16970                            + " (pid=" + Binder.getCallingPid()
16971                            + ") when registering receiver " + receiver);
16972                }
16973                if (callerApp.info.uid != Process.SYSTEM_UID &&
16974                        !callerApp.pkgList.containsKey(callerPackage) &&
16975                        !"android".equals(callerPackage)) {
16976                    throw new SecurityException("Given caller package " + callerPackage
16977                            + " is not running in process " + callerApp);
16978                }
16979                callingUid = callerApp.info.uid;
16980                callingPid = callerApp.pid;
16981            } else {
16982                callerPackage = null;
16983                callingUid = Binder.getCallingUid();
16984                callingPid = Binder.getCallingPid();
16985            }
16986
16987            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16988                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16989
16990            Iterator<String> actions = filter.actionsIterator();
16991            if (actions == null) {
16992                ArrayList<String> noAction = new ArrayList<String>(1);
16993                noAction.add(null);
16994                actions = noAction.iterator();
16995            }
16996
16997            // Collect stickies of users
16998            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16999            while (actions.hasNext()) {
17000                String action = actions.next();
17001                for (int id : userIds) {
17002                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17003                    if (stickies != null) {
17004                        ArrayList<Intent> intents = stickies.get(action);
17005                        if (intents != null) {
17006                            if (stickyIntents == null) {
17007                                stickyIntents = new ArrayList<Intent>();
17008                            }
17009                            stickyIntents.addAll(intents);
17010                        }
17011                    }
17012                }
17013            }
17014        }
17015
17016        ArrayList<Intent> allSticky = null;
17017        if (stickyIntents != null) {
17018            final ContentResolver resolver = mContext.getContentResolver();
17019            // Look for any matching sticky broadcasts...
17020            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17021                Intent intent = stickyIntents.get(i);
17022                // If intent has scheme "content", it will need to acccess
17023                // provider that needs to lock mProviderMap in ActivityThread
17024                // and also it may need to wait application response, so we
17025                // cannot lock ActivityManagerService here.
17026                if (filter.match(resolver, intent, true, TAG) >= 0) {
17027                    if (allSticky == null) {
17028                        allSticky = new ArrayList<Intent>();
17029                    }
17030                    allSticky.add(intent);
17031                }
17032            }
17033        }
17034
17035        // The first sticky in the list is returned directly back to the client.
17036        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17037        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17038        if (receiver == null) {
17039            return sticky;
17040        }
17041
17042        synchronized (this) {
17043            if (callerApp != null && (callerApp.thread == null
17044                    || callerApp.thread.asBinder() != caller.asBinder())) {
17045                // Original caller already died
17046                return null;
17047            }
17048            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17049            if (rl == null) {
17050                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17051                        userId, receiver);
17052                if (rl.app != null) {
17053                    rl.app.receivers.add(rl);
17054                } else {
17055                    try {
17056                        receiver.asBinder().linkToDeath(rl, 0);
17057                    } catch (RemoteException e) {
17058                        return sticky;
17059                    }
17060                    rl.linkedToDeath = true;
17061                }
17062                mRegisteredReceivers.put(receiver.asBinder(), rl);
17063            } else if (rl.uid != callingUid) {
17064                throw new IllegalArgumentException(
17065                        "Receiver requested to register for uid " + callingUid
17066                        + " was previously registered for uid " + rl.uid);
17067            } else if (rl.pid != callingPid) {
17068                throw new IllegalArgumentException(
17069                        "Receiver requested to register for pid " + callingPid
17070                        + " was previously registered for pid " + rl.pid);
17071            } else if (rl.userId != userId) {
17072                throw new IllegalArgumentException(
17073                        "Receiver requested to register for user " + userId
17074                        + " was previously registered for user " + rl.userId);
17075            }
17076            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17077                    permission, callingUid, userId);
17078            rl.add(bf);
17079            if (!bf.debugCheck()) {
17080                Slog.w(TAG, "==> For Dynamic broadcast");
17081            }
17082            mReceiverResolver.addFilter(bf);
17083
17084            // Enqueue broadcasts for all existing stickies that match
17085            // this filter.
17086            if (allSticky != null) {
17087                ArrayList receivers = new ArrayList();
17088                receivers.add(bf);
17089
17090                final int stickyCount = allSticky.size();
17091                for (int i = 0; i < stickyCount; i++) {
17092                    Intent intent = allSticky.get(i);
17093                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17094                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17095                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17096                            null, 0, null, null, false, true, true, -1);
17097                    queue.enqueueParallelBroadcastLocked(r);
17098                    queue.scheduleBroadcastsLocked();
17099                }
17100            }
17101
17102            return sticky;
17103        }
17104    }
17105
17106    public void unregisterReceiver(IIntentReceiver receiver) {
17107        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17108
17109        final long origId = Binder.clearCallingIdentity();
17110        try {
17111            boolean doTrim = false;
17112
17113            synchronized(this) {
17114                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17115                if (rl != null) {
17116                    final BroadcastRecord r = rl.curBroadcast;
17117                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17118                        final boolean doNext = r.queue.finishReceiverLocked(
17119                                r, r.resultCode, r.resultData, r.resultExtras,
17120                                r.resultAbort, false);
17121                        if (doNext) {
17122                            doTrim = true;
17123                            r.queue.processNextBroadcast(false);
17124                        }
17125                    }
17126
17127                    if (rl.app != null) {
17128                        rl.app.receivers.remove(rl);
17129                    }
17130                    removeReceiverLocked(rl);
17131                    if (rl.linkedToDeath) {
17132                        rl.linkedToDeath = false;
17133                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17134                    }
17135                }
17136            }
17137
17138            // If we actually concluded any broadcasts, we might now be able
17139            // to trim the recipients' apps from our working set
17140            if (doTrim) {
17141                trimApplications();
17142                return;
17143            }
17144
17145        } finally {
17146            Binder.restoreCallingIdentity(origId);
17147        }
17148    }
17149
17150    void removeReceiverLocked(ReceiverList rl) {
17151        mRegisteredReceivers.remove(rl.receiver.asBinder());
17152        for (int i = rl.size() - 1; i >= 0; i--) {
17153            mReceiverResolver.removeFilter(rl.get(i));
17154        }
17155    }
17156
17157    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17158        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17159            ProcessRecord r = mLruProcesses.get(i);
17160            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17161                try {
17162                    r.thread.dispatchPackageBroadcast(cmd, packages);
17163                } catch (RemoteException ex) {
17164                }
17165            }
17166        }
17167    }
17168
17169    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17170            int callingUid, int[] users) {
17171        // TODO: come back and remove this assumption to triage all broadcasts
17172        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17173
17174        List<ResolveInfo> receivers = null;
17175        try {
17176            HashSet<ComponentName> singleUserReceivers = null;
17177            boolean scannedFirstReceivers = false;
17178            for (int user : users) {
17179                // Skip users that have Shell restrictions, with exception of always permitted
17180                // Shell broadcasts
17181                if (callingUid == Process.SHELL_UID
17182                        && mUserController.hasUserRestriction(
17183                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17184                        && !isPermittedShellBroadcast(intent)) {
17185                    continue;
17186                }
17187                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17188                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17189                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17190                    // If this is not the system user, we need to check for
17191                    // any receivers that should be filtered out.
17192                    for (int i=0; i<newReceivers.size(); i++) {
17193                        ResolveInfo ri = newReceivers.get(i);
17194                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17195                            newReceivers.remove(i);
17196                            i--;
17197                        }
17198                    }
17199                }
17200                if (newReceivers != null && newReceivers.size() == 0) {
17201                    newReceivers = null;
17202                }
17203                if (receivers == null) {
17204                    receivers = newReceivers;
17205                } else if (newReceivers != null) {
17206                    // We need to concatenate the additional receivers
17207                    // found with what we have do far.  This would be easy,
17208                    // but we also need to de-dup any receivers that are
17209                    // singleUser.
17210                    if (!scannedFirstReceivers) {
17211                        // Collect any single user receivers we had already retrieved.
17212                        scannedFirstReceivers = true;
17213                        for (int i=0; i<receivers.size(); i++) {
17214                            ResolveInfo ri = receivers.get(i);
17215                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17216                                ComponentName cn = new ComponentName(
17217                                        ri.activityInfo.packageName, ri.activityInfo.name);
17218                                if (singleUserReceivers == null) {
17219                                    singleUserReceivers = new HashSet<ComponentName>();
17220                                }
17221                                singleUserReceivers.add(cn);
17222                            }
17223                        }
17224                    }
17225                    // Add the new results to the existing results, tracking
17226                    // and de-dupping single user receivers.
17227                    for (int i=0; i<newReceivers.size(); i++) {
17228                        ResolveInfo ri = newReceivers.get(i);
17229                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17230                            ComponentName cn = new ComponentName(
17231                                    ri.activityInfo.packageName, ri.activityInfo.name);
17232                            if (singleUserReceivers == null) {
17233                                singleUserReceivers = new HashSet<ComponentName>();
17234                            }
17235                            if (!singleUserReceivers.contains(cn)) {
17236                                singleUserReceivers.add(cn);
17237                                receivers.add(ri);
17238                            }
17239                        } else {
17240                            receivers.add(ri);
17241                        }
17242                    }
17243                }
17244            }
17245        } catch (RemoteException ex) {
17246            // pm is in same process, this will never happen.
17247        }
17248        return receivers;
17249    }
17250
17251    private boolean isPermittedShellBroadcast(Intent intent) {
17252        // remote bugreport should always be allowed to be taken
17253        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17254    }
17255
17256    final int broadcastIntentLocked(ProcessRecord callerApp,
17257            String callerPackage, Intent intent, String resolvedType,
17258            IIntentReceiver resultTo, int resultCode, String resultData,
17259            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17260            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17261        intent = new Intent(intent);
17262
17263        // By default broadcasts do not go to stopped apps.
17264        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17265
17266        // If we have not finished booting, don't allow this to launch new processes.
17267        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17268            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17269        }
17270
17271        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17272                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17273                + " ordered=" + ordered + " userid=" + userId);
17274        if ((resultTo != null) && !ordered) {
17275            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17276        }
17277
17278        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17279                ALLOW_NON_FULL, "broadcast", callerPackage);
17280
17281        // Make sure that the user who is receiving this broadcast is running.
17282        // If not, we will just skip it. Make an exception for shutdown broadcasts
17283        // and upgrade steps.
17284
17285        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17286            if ((callingUid != Process.SYSTEM_UID
17287                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17288                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17289                Slog.w(TAG, "Skipping broadcast of " + intent
17290                        + ": user " + userId + " is stopped");
17291                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17292            }
17293        }
17294
17295        BroadcastOptions brOptions = null;
17296        if (bOptions != null) {
17297            brOptions = new BroadcastOptions(bOptions);
17298            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17299                // See if the caller is allowed to do this.  Note we are checking against
17300                // the actual real caller (not whoever provided the operation as say a
17301                // PendingIntent), because that who is actually supplied the arguments.
17302                if (checkComponentPermission(
17303                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17304                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17305                        != PackageManager.PERMISSION_GRANTED) {
17306                    String msg = "Permission Denial: " + intent.getAction()
17307                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17308                            + ", uid=" + callingUid + ")"
17309                            + " requires "
17310                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17311                    Slog.w(TAG, msg);
17312                    throw new SecurityException(msg);
17313                }
17314            }
17315        }
17316
17317        // Verify that protected broadcasts are only being sent by system code,
17318        // and that system code is only sending protected broadcasts.
17319        final String action = intent.getAction();
17320        final boolean isProtectedBroadcast;
17321        try {
17322            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17323        } catch (RemoteException e) {
17324            Slog.w(TAG, "Remote exception", e);
17325            return ActivityManager.BROADCAST_SUCCESS;
17326        }
17327
17328        final boolean isCallerSystem;
17329        switch (UserHandle.getAppId(callingUid)) {
17330            case Process.ROOT_UID:
17331            case Process.SYSTEM_UID:
17332            case Process.PHONE_UID:
17333            case Process.BLUETOOTH_UID:
17334            case Process.NFC_UID:
17335                isCallerSystem = true;
17336                break;
17337            default:
17338                isCallerSystem = (callerApp != null) && callerApp.persistent;
17339                break;
17340        }
17341
17342        if (isCallerSystem) {
17343            if (isProtectedBroadcast
17344                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17345                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17346                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17347                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17348                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17349                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17350                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17351                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17352                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)) {
17353                // Broadcast is either protected, or it's a public action that
17354                // we've relaxed, so it's fine for system internals to send.
17355            } else {
17356                // The vast majority of broadcasts sent from system internals
17357                // should be protected to avoid security holes, so yell loudly
17358                // to ensure we examine these cases.
17359                Log.wtf(TAG, "Sending non-protected broadcast " + action
17360                        + " from system", new Throwable());
17361            }
17362
17363        } else {
17364            if (isProtectedBroadcast) {
17365                String msg = "Permission Denial: not allowed to send broadcast "
17366                        + action + " from pid="
17367                        + callingPid + ", uid=" + callingUid;
17368                Slog.w(TAG, msg);
17369                throw new SecurityException(msg);
17370
17371            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17372                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17373                // Special case for compatibility: we don't want apps to send this,
17374                // but historically it has not been protected and apps may be using it
17375                // to poke their own app widget.  So, instead of making it protected,
17376                // just limit it to the caller.
17377                if (callerPackage == null) {
17378                    String msg = "Permission Denial: not allowed to send broadcast "
17379                            + action + " from unknown caller.";
17380                    Slog.w(TAG, msg);
17381                    throw new SecurityException(msg);
17382                } else if (intent.getComponent() != null) {
17383                    // They are good enough to send to an explicit component...  verify
17384                    // it is being sent to the calling app.
17385                    if (!intent.getComponent().getPackageName().equals(
17386                            callerPackage)) {
17387                        String msg = "Permission Denial: not allowed to send broadcast "
17388                                + action + " to "
17389                                + intent.getComponent().getPackageName() + " from "
17390                                + callerPackage;
17391                        Slog.w(TAG, msg);
17392                        throw new SecurityException(msg);
17393                    }
17394                } else {
17395                    // Limit broadcast to their own package.
17396                    intent.setPackage(callerPackage);
17397                }
17398            }
17399        }
17400
17401        if (action != null) {
17402            switch (action) {
17403                case Intent.ACTION_UID_REMOVED:
17404                case Intent.ACTION_PACKAGE_REMOVED:
17405                case Intent.ACTION_PACKAGE_CHANGED:
17406                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17407                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17408                case Intent.ACTION_PACKAGES_SUSPENDED:
17409                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17410                    // Handle special intents: if this broadcast is from the package
17411                    // manager about a package being removed, we need to remove all of
17412                    // its activities from the history stack.
17413                    if (checkComponentPermission(
17414                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17415                            callingPid, callingUid, -1, true)
17416                            != PackageManager.PERMISSION_GRANTED) {
17417                        String msg = "Permission Denial: " + intent.getAction()
17418                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17419                                + ", uid=" + callingUid + ")"
17420                                + " requires "
17421                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17422                        Slog.w(TAG, msg);
17423                        throw new SecurityException(msg);
17424                    }
17425                    switch (action) {
17426                        case Intent.ACTION_UID_REMOVED:
17427                            final Bundle intentExtras = intent.getExtras();
17428                            final int uid = intentExtras != null
17429                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17430                            if (uid >= 0) {
17431                                mBatteryStatsService.removeUid(uid);
17432                                mAppOpsService.uidRemoved(uid);
17433                            }
17434                            break;
17435                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17436                            // If resources are unavailable just force stop all those packages
17437                            // and flush the attribute cache as well.
17438                            String list[] =
17439                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17440                            if (list != null && list.length > 0) {
17441                                for (int i = 0; i < list.length; i++) {
17442                                    forceStopPackageLocked(list[i], -1, false, true, true,
17443                                            false, false, userId, "storage unmount");
17444                                }
17445                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17446                                sendPackageBroadcastLocked(
17447                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17448                                        userId);
17449                            }
17450                            break;
17451                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17452                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17453                            break;
17454                        case Intent.ACTION_PACKAGE_REMOVED:
17455                        case Intent.ACTION_PACKAGE_CHANGED:
17456                            Uri data = intent.getData();
17457                            String ssp;
17458                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17459                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17460                                final boolean replacing =
17461                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17462                                final boolean killProcess =
17463                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17464                                final boolean fullUninstall = removed && !replacing;
17465                                if (killProcess) {
17466                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17467                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17468                                            false, true, true, false, fullUninstall, userId,
17469                                            removed ? "pkg removed" : "pkg changed");
17470                                }
17471                                if (removed) {
17472                                    final int cmd = killProcess
17473                                            ? IApplicationThread.PACKAGE_REMOVED
17474                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17475                                    sendPackageBroadcastLocked(cmd,
17476                                            new String[] {ssp}, userId);
17477                                    if (fullUninstall) {
17478                                        mAppOpsService.packageRemoved(
17479                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17480
17481                                        // Remove all permissions granted from/to this package
17482                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17483
17484                                        removeTasksByPackageNameLocked(ssp, userId);
17485                                        mBatteryStatsService.notePackageUninstalled(ssp);
17486                                    }
17487                                } else {
17488                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17489                                            intent.getStringArrayExtra(
17490                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17491                                }
17492                            }
17493                            break;
17494                        case Intent.ACTION_PACKAGES_SUSPENDED:
17495                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17496                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17497                                    intent.getAction());
17498                            final String[] packageNames = intent.getStringArrayExtra(
17499                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17500                            final int userHandle = intent.getIntExtra(
17501                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17502
17503                            synchronized(ActivityManagerService.this) {
17504                                mRecentTasks.onPackagesSuspendedChanged(
17505                                        packageNames, suspended, userHandle);
17506                            }
17507                            break;
17508                    }
17509                    break;
17510                case Intent.ACTION_PACKAGE_REPLACED:
17511                {
17512                    final Uri data = intent.getData();
17513                    final String ssp;
17514                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17515                        final ApplicationInfo aInfo =
17516                                getPackageManagerInternalLocked().getApplicationInfo(
17517                                        ssp,
17518                                        userId);
17519                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17520                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17521                                new String[] {ssp}, userId);
17522                    }
17523                    break;
17524                }
17525                case Intent.ACTION_PACKAGE_ADDED:
17526                {
17527                    // Special case for adding a package: by default turn on compatibility mode.
17528                    Uri data = intent.getData();
17529                    String ssp;
17530                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17531                        final boolean replacing =
17532                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17533                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17534
17535                        try {
17536                            ApplicationInfo ai = AppGlobals.getPackageManager().
17537                                    getApplicationInfo(ssp, 0, 0);
17538                            mBatteryStatsService.notePackageInstalled(ssp,
17539                                    ai != null ? ai.versionCode : 0);
17540                        } catch (RemoteException e) {
17541                        }
17542                    }
17543                    break;
17544                }
17545                case Intent.ACTION_TIMEZONE_CHANGED:
17546                    // If this is the time zone changed action, queue up a message that will reset
17547                    // the timezone of all currently running processes. This message will get
17548                    // queued up before the broadcast happens.
17549                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17550                    break;
17551                case Intent.ACTION_TIME_CHANGED:
17552                    // If the user set the time, let all running processes know.
17553                    final int is24Hour =
17554                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17555                                    : 0;
17556                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17557                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17558                    synchronized (stats) {
17559                        stats.noteCurrentTimeChangedLocked();
17560                    }
17561                    break;
17562                case Intent.ACTION_CLEAR_DNS_CACHE:
17563                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17564                    break;
17565                case Proxy.PROXY_CHANGE_ACTION:
17566                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17567                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17568                    break;
17569                case android.hardware.Camera.ACTION_NEW_PICTURE:
17570                case android.hardware.Camera.ACTION_NEW_VIDEO:
17571                    // These broadcasts are no longer allowed by the system, since they can
17572                    // cause significant thrashing at a crictical point (using the camera).
17573                    // Apps should use JobScehduler to monitor for media provider changes.
17574                    Slog.w(TAG, action + " no longer allowed; dropping from "
17575                            + UserHandle.formatUid(callingUid));
17576                    // Lie; we don't want to crash the app.
17577                    return ActivityManager.BROADCAST_SUCCESS;
17578            }
17579        }
17580
17581        // Add to the sticky list if requested.
17582        if (sticky) {
17583            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17584                    callingPid, callingUid)
17585                    != PackageManager.PERMISSION_GRANTED) {
17586                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17587                        + callingPid + ", uid=" + callingUid
17588                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17589                Slog.w(TAG, msg);
17590                throw new SecurityException(msg);
17591            }
17592            if (requiredPermissions != null && requiredPermissions.length > 0) {
17593                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17594                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17595                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17596            }
17597            if (intent.getComponent() != null) {
17598                throw new SecurityException(
17599                        "Sticky broadcasts can't target a specific component");
17600            }
17601            // We use userId directly here, since the "all" target is maintained
17602            // as a separate set of sticky broadcasts.
17603            if (userId != UserHandle.USER_ALL) {
17604                // But first, if this is not a broadcast to all users, then
17605                // make sure it doesn't conflict with an existing broadcast to
17606                // all users.
17607                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17608                        UserHandle.USER_ALL);
17609                if (stickies != null) {
17610                    ArrayList<Intent> list = stickies.get(intent.getAction());
17611                    if (list != null) {
17612                        int N = list.size();
17613                        int i;
17614                        for (i=0; i<N; i++) {
17615                            if (intent.filterEquals(list.get(i))) {
17616                                throw new IllegalArgumentException(
17617                                        "Sticky broadcast " + intent + " for user "
17618                                        + userId + " conflicts with existing global broadcast");
17619                            }
17620                        }
17621                    }
17622                }
17623            }
17624            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17625            if (stickies == null) {
17626                stickies = new ArrayMap<>();
17627                mStickyBroadcasts.put(userId, stickies);
17628            }
17629            ArrayList<Intent> list = stickies.get(intent.getAction());
17630            if (list == null) {
17631                list = new ArrayList<>();
17632                stickies.put(intent.getAction(), list);
17633            }
17634            final int stickiesCount = list.size();
17635            int i;
17636            for (i = 0; i < stickiesCount; i++) {
17637                if (intent.filterEquals(list.get(i))) {
17638                    // This sticky already exists, replace it.
17639                    list.set(i, new Intent(intent));
17640                    break;
17641                }
17642            }
17643            if (i >= stickiesCount) {
17644                list.add(new Intent(intent));
17645            }
17646        }
17647
17648        int[] users;
17649        if (userId == UserHandle.USER_ALL) {
17650            // Caller wants broadcast to go to all started users.
17651            users = mUserController.getStartedUserArrayLocked();
17652        } else {
17653            // Caller wants broadcast to go to one specific user.
17654            users = new int[] {userId};
17655        }
17656
17657        // Figure out who all will receive this broadcast.
17658        List receivers = null;
17659        List<BroadcastFilter> registeredReceivers = null;
17660        // Need to resolve the intent to interested receivers...
17661        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17662                 == 0) {
17663            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17664        }
17665        if (intent.getComponent() == null) {
17666            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17667                // Query one target user at a time, excluding shell-restricted users
17668                for (int i = 0; i < users.length; i++) {
17669                    if (mUserController.hasUserRestriction(
17670                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17671                        continue;
17672                    }
17673                    List<BroadcastFilter> registeredReceiversForUser =
17674                            mReceiverResolver.queryIntent(intent,
17675                                    resolvedType, false, users[i]);
17676                    if (registeredReceivers == null) {
17677                        registeredReceivers = registeredReceiversForUser;
17678                    } else if (registeredReceiversForUser != null) {
17679                        registeredReceivers.addAll(registeredReceiversForUser);
17680                    }
17681                }
17682            } else {
17683                registeredReceivers = mReceiverResolver.queryIntent(intent,
17684                        resolvedType, false, userId);
17685            }
17686        }
17687
17688        final boolean replacePending =
17689                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17690
17691        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17692                + " replacePending=" + replacePending);
17693
17694        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17695        if (!ordered && NR > 0) {
17696            // If we are not serializing this broadcast, then send the
17697            // registered receivers separately so they don't wait for the
17698            // components to be launched.
17699            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17700            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17701                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17702                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17703                    resultExtras, ordered, sticky, false, userId);
17704            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17705            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17706            if (!replaced) {
17707                queue.enqueueParallelBroadcastLocked(r);
17708                queue.scheduleBroadcastsLocked();
17709            }
17710            registeredReceivers = null;
17711            NR = 0;
17712        }
17713
17714        // Merge into one list.
17715        int ir = 0;
17716        if (receivers != null) {
17717            // A special case for PACKAGE_ADDED: do not allow the package
17718            // being added to see this broadcast.  This prevents them from
17719            // using this as a back door to get run as soon as they are
17720            // installed.  Maybe in the future we want to have a special install
17721            // broadcast or such for apps, but we'd like to deliberately make
17722            // this decision.
17723            String skipPackages[] = null;
17724            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17725                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17726                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17727                Uri data = intent.getData();
17728                if (data != null) {
17729                    String pkgName = data.getSchemeSpecificPart();
17730                    if (pkgName != null) {
17731                        skipPackages = new String[] { pkgName };
17732                    }
17733                }
17734            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17735                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17736            }
17737            if (skipPackages != null && (skipPackages.length > 0)) {
17738                for (String skipPackage : skipPackages) {
17739                    if (skipPackage != null) {
17740                        int NT = receivers.size();
17741                        for (int it=0; it<NT; it++) {
17742                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17743                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17744                                receivers.remove(it);
17745                                it--;
17746                                NT--;
17747                            }
17748                        }
17749                    }
17750                }
17751            }
17752
17753            int NT = receivers != null ? receivers.size() : 0;
17754            int it = 0;
17755            ResolveInfo curt = null;
17756            BroadcastFilter curr = null;
17757            while (it < NT && ir < NR) {
17758                if (curt == null) {
17759                    curt = (ResolveInfo)receivers.get(it);
17760                }
17761                if (curr == null) {
17762                    curr = registeredReceivers.get(ir);
17763                }
17764                if (curr.getPriority() >= curt.priority) {
17765                    // Insert this broadcast record into the final list.
17766                    receivers.add(it, curr);
17767                    ir++;
17768                    curr = null;
17769                    it++;
17770                    NT++;
17771                } else {
17772                    // Skip to the next ResolveInfo in the final list.
17773                    it++;
17774                    curt = null;
17775                }
17776            }
17777        }
17778        while (ir < NR) {
17779            if (receivers == null) {
17780                receivers = new ArrayList();
17781            }
17782            receivers.add(registeredReceivers.get(ir));
17783            ir++;
17784        }
17785
17786        if ((receivers != null && receivers.size() > 0)
17787                || resultTo != null) {
17788            BroadcastQueue queue = broadcastQueueForIntent(intent);
17789            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17790                    callerPackage, callingPid, callingUid, resolvedType,
17791                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17792                    resultData, resultExtras, ordered, sticky, false, userId);
17793
17794            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17795                    + ": prev had " + queue.mOrderedBroadcasts.size());
17796            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17797                    "Enqueueing broadcast " + r.intent.getAction());
17798
17799            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17800            if (!replaced) {
17801                queue.enqueueOrderedBroadcastLocked(r);
17802                queue.scheduleBroadcastsLocked();
17803            }
17804        }
17805
17806        return ActivityManager.BROADCAST_SUCCESS;
17807    }
17808
17809    final Intent verifyBroadcastLocked(Intent intent) {
17810        // Refuse possible leaked file descriptors
17811        if (intent != null && intent.hasFileDescriptors() == true) {
17812            throw new IllegalArgumentException("File descriptors passed in Intent");
17813        }
17814
17815        int flags = intent.getFlags();
17816
17817        if (!mProcessesReady) {
17818            // if the caller really truly claims to know what they're doing, go
17819            // ahead and allow the broadcast without launching any receivers
17820            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17821                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17822            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17823                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17824                        + " before boot completion");
17825                throw new IllegalStateException("Cannot broadcast before boot completed");
17826            }
17827        }
17828
17829        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17830            throw new IllegalArgumentException(
17831                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17832        }
17833
17834        return intent;
17835    }
17836
17837    public final int broadcastIntent(IApplicationThread caller,
17838            Intent intent, String resolvedType, IIntentReceiver resultTo,
17839            int resultCode, String resultData, Bundle resultExtras,
17840            String[] requiredPermissions, int appOp, Bundle bOptions,
17841            boolean serialized, boolean sticky, int userId) {
17842        enforceNotIsolatedCaller("broadcastIntent");
17843        synchronized(this) {
17844            intent = verifyBroadcastLocked(intent);
17845
17846            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17847            final int callingPid = Binder.getCallingPid();
17848            final int callingUid = Binder.getCallingUid();
17849            final long origId = Binder.clearCallingIdentity();
17850            int res = broadcastIntentLocked(callerApp,
17851                    callerApp != null ? callerApp.info.packageName : null,
17852                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17853                    requiredPermissions, appOp, bOptions, serialized, sticky,
17854                    callingPid, callingUid, userId);
17855            Binder.restoreCallingIdentity(origId);
17856            return res;
17857        }
17858    }
17859
17860
17861    int broadcastIntentInPackage(String packageName, int uid,
17862            Intent intent, String resolvedType, IIntentReceiver resultTo,
17863            int resultCode, String resultData, Bundle resultExtras,
17864            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17865            int userId) {
17866        synchronized(this) {
17867            intent = verifyBroadcastLocked(intent);
17868
17869            final long origId = Binder.clearCallingIdentity();
17870            String[] requiredPermissions = requiredPermission == null ? null
17871                    : new String[] {requiredPermission};
17872            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17873                    resultTo, resultCode, resultData, resultExtras,
17874                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17875                    sticky, -1, uid, userId);
17876            Binder.restoreCallingIdentity(origId);
17877            return res;
17878        }
17879    }
17880
17881    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17882        // Refuse possible leaked file descriptors
17883        if (intent != null && intent.hasFileDescriptors() == true) {
17884            throw new IllegalArgumentException("File descriptors passed in Intent");
17885        }
17886
17887        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17888                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17889
17890        synchronized(this) {
17891            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17892                    != PackageManager.PERMISSION_GRANTED) {
17893                String msg = "Permission Denial: unbroadcastIntent() from pid="
17894                        + Binder.getCallingPid()
17895                        + ", uid=" + Binder.getCallingUid()
17896                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17897                Slog.w(TAG, msg);
17898                throw new SecurityException(msg);
17899            }
17900            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17901            if (stickies != null) {
17902                ArrayList<Intent> list = stickies.get(intent.getAction());
17903                if (list != null) {
17904                    int N = list.size();
17905                    int i;
17906                    for (i=0; i<N; i++) {
17907                        if (intent.filterEquals(list.get(i))) {
17908                            list.remove(i);
17909                            break;
17910                        }
17911                    }
17912                    if (list.size() <= 0) {
17913                        stickies.remove(intent.getAction());
17914                    }
17915                }
17916                if (stickies.size() <= 0) {
17917                    mStickyBroadcasts.remove(userId);
17918                }
17919            }
17920        }
17921    }
17922
17923    void backgroundServicesFinishedLocked(int userId) {
17924        for (BroadcastQueue queue : mBroadcastQueues) {
17925            queue.backgroundServicesFinishedLocked(userId);
17926        }
17927    }
17928
17929    public void finishReceiver(IBinder who, int resultCode, String resultData,
17930            Bundle resultExtras, boolean resultAbort, int flags) {
17931        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17932
17933        // Refuse possible leaked file descriptors
17934        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17935            throw new IllegalArgumentException("File descriptors passed in Bundle");
17936        }
17937
17938        final long origId = Binder.clearCallingIdentity();
17939        try {
17940            boolean doNext = false;
17941            BroadcastRecord r;
17942
17943            synchronized(this) {
17944                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17945                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17946                r = queue.getMatchingOrderedReceiver(who);
17947                if (r != null) {
17948                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17949                        resultData, resultExtras, resultAbort, true);
17950                }
17951            }
17952
17953            if (doNext) {
17954                r.queue.processNextBroadcast(false);
17955            }
17956            trimApplications();
17957        } finally {
17958            Binder.restoreCallingIdentity(origId);
17959        }
17960    }
17961
17962    // =========================================================
17963    // INSTRUMENTATION
17964    // =========================================================
17965
17966    public boolean startInstrumentation(ComponentName className,
17967            String profileFile, int flags, Bundle arguments,
17968            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17969            int userId, String abiOverride) {
17970        enforceNotIsolatedCaller("startInstrumentation");
17971        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17972                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17973        // Refuse possible leaked file descriptors
17974        if (arguments != null && arguments.hasFileDescriptors()) {
17975            throw new IllegalArgumentException("File descriptors passed in Bundle");
17976        }
17977
17978        synchronized(this) {
17979            InstrumentationInfo ii = null;
17980            ApplicationInfo ai = null;
17981            try {
17982                ii = mContext.getPackageManager().getInstrumentationInfo(
17983                    className, STOCK_PM_FLAGS);
17984                ai = AppGlobals.getPackageManager().getApplicationInfo(
17985                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17986            } catch (PackageManager.NameNotFoundException e) {
17987            } catch (RemoteException e) {
17988            }
17989            if (ii == null) {
17990                reportStartInstrumentationFailureLocked(watcher, className,
17991                        "Unable to find instrumentation info for: " + className);
17992                return false;
17993            }
17994            if (ai == null) {
17995                reportStartInstrumentationFailureLocked(watcher, className,
17996                        "Unable to find instrumentation target package: " + ii.targetPackage);
17997                return false;
17998            }
17999            if (!ai.hasCode()) {
18000                reportStartInstrumentationFailureLocked(watcher, className,
18001                        "Instrumentation target has no code: " + ii.targetPackage);
18002                return false;
18003            }
18004
18005            int match = mContext.getPackageManager().checkSignatures(
18006                    ii.targetPackage, ii.packageName);
18007            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18008                String msg = "Permission Denial: starting instrumentation "
18009                        + className + " from pid="
18010                        + Binder.getCallingPid()
18011                        + ", uid=" + Binder.getCallingPid()
18012                        + " not allowed because package " + ii.packageName
18013                        + " does not have a signature matching the target "
18014                        + ii.targetPackage;
18015                reportStartInstrumentationFailureLocked(watcher, className, msg);
18016                throw new SecurityException(msg);
18017            }
18018
18019            final long origId = Binder.clearCallingIdentity();
18020            // Instrumentation can kill and relaunch even persistent processes
18021            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18022                    "start instr");
18023            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18024            app.instrumentationClass = className;
18025            app.instrumentationInfo = ai;
18026            app.instrumentationProfileFile = profileFile;
18027            app.instrumentationArguments = arguments;
18028            app.instrumentationWatcher = watcher;
18029            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18030            app.instrumentationResultClass = className;
18031            Binder.restoreCallingIdentity(origId);
18032        }
18033
18034        return true;
18035    }
18036
18037    /**
18038     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18039     * error to the logs, but if somebody is watching, send the report there too.  This enables
18040     * the "am" command to report errors with more information.
18041     *
18042     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18043     * @param cn The component name of the instrumentation.
18044     * @param report The error report.
18045     */
18046    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18047            ComponentName cn, String report) {
18048        Slog.w(TAG, report);
18049        if (watcher != null) {
18050            Bundle results = new Bundle();
18051            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18052            results.putString("Error", report);
18053            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18054        }
18055    }
18056
18057    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18058        if (app.instrumentationWatcher != null) {
18059            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18060                    app.instrumentationClass, resultCode, results);
18061        }
18062
18063        // Can't call out of the system process with a lock held, so post a message.
18064        if (app.instrumentationUiAutomationConnection != null) {
18065            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18066                    app.instrumentationUiAutomationConnection).sendToTarget();
18067        }
18068
18069        app.instrumentationWatcher = null;
18070        app.instrumentationUiAutomationConnection = null;
18071        app.instrumentationClass = null;
18072        app.instrumentationInfo = null;
18073        app.instrumentationProfileFile = null;
18074        app.instrumentationArguments = null;
18075
18076        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18077                "finished inst");
18078    }
18079
18080    public void finishInstrumentation(IApplicationThread target,
18081            int resultCode, Bundle results) {
18082        int userId = UserHandle.getCallingUserId();
18083        // Refuse possible leaked file descriptors
18084        if (results != null && results.hasFileDescriptors()) {
18085            throw new IllegalArgumentException("File descriptors passed in Intent");
18086        }
18087
18088        synchronized(this) {
18089            ProcessRecord app = getRecordForAppLocked(target);
18090            if (app == null) {
18091                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18092                return;
18093            }
18094            final long origId = Binder.clearCallingIdentity();
18095            finishInstrumentationLocked(app, resultCode, results);
18096            Binder.restoreCallingIdentity(origId);
18097        }
18098    }
18099
18100    // =========================================================
18101    // CONFIGURATION
18102    // =========================================================
18103
18104    public ConfigurationInfo getDeviceConfigurationInfo() {
18105        ConfigurationInfo config = new ConfigurationInfo();
18106        synchronized (this) {
18107            config.reqTouchScreen = mConfiguration.touchscreen;
18108            config.reqKeyboardType = mConfiguration.keyboard;
18109            config.reqNavigation = mConfiguration.navigation;
18110            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18111                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18112                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18113            }
18114            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18115                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18116                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18117            }
18118            config.reqGlEsVersion = GL_ES_VERSION;
18119        }
18120        return config;
18121    }
18122
18123    ActivityStack getFocusedStack() {
18124        return mStackSupervisor.getFocusedStack();
18125    }
18126
18127    @Override
18128    public int getFocusedStackId() throws RemoteException {
18129        ActivityStack focusedStack = getFocusedStack();
18130        if (focusedStack != null) {
18131            return focusedStack.getStackId();
18132        }
18133        return -1;
18134    }
18135
18136    public Configuration getConfiguration() {
18137        Configuration ci;
18138        synchronized(this) {
18139            ci = new Configuration(mConfiguration);
18140            ci.userSetLocale = false;
18141        }
18142        return ci;
18143    }
18144
18145    @Override
18146    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18147        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18148        synchronized (this) {
18149            mSuppressResizeConfigChanges = suppress;
18150        }
18151    }
18152
18153    @Override
18154    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18155        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18156        if (fromStackId == HOME_STACK_ID) {
18157            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18158        }
18159        synchronized (this) {
18160            final long origId = Binder.clearCallingIdentity();
18161            try {
18162                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18163            } finally {
18164                Binder.restoreCallingIdentity(origId);
18165            }
18166        }
18167    }
18168
18169    @Override
18170    public void updatePersistentConfiguration(Configuration values) {
18171        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18172                "updateConfiguration()");
18173        enforceWriteSettingsPermission("updateConfiguration()");
18174        if (values == null) {
18175            throw new NullPointerException("Configuration must not be null");
18176        }
18177
18178        int userId = UserHandle.getCallingUserId();
18179
18180        synchronized(this) {
18181            final long origId = Binder.clearCallingIdentity();
18182            updateConfigurationLocked(values, null, false, true, userId);
18183            Binder.restoreCallingIdentity(origId);
18184        }
18185    }
18186
18187    private void updateFontScaleIfNeeded() {
18188        final int currentUserId;
18189        synchronized(this) {
18190            currentUserId = mUserController.getCurrentUserIdLocked();
18191        }
18192        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18193                FONT_SCALE, 1.0f, currentUserId);
18194        if (mConfiguration.fontScale != scaleFactor) {
18195            final Configuration configuration = mWindowManager.computeNewConfiguration();
18196            configuration.fontScale = scaleFactor;
18197            updatePersistentConfiguration(configuration);
18198        }
18199    }
18200
18201    private void enforceWriteSettingsPermission(String func) {
18202        int uid = Binder.getCallingUid();
18203        if (uid == Process.ROOT_UID) {
18204            return;
18205        }
18206
18207        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18208                Settings.getPackageNameForUid(mContext, uid), false)) {
18209            return;
18210        }
18211
18212        String msg = "Permission Denial: " + func + " from pid="
18213                + Binder.getCallingPid()
18214                + ", uid=" + uid
18215                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18216        Slog.w(TAG, msg);
18217        throw new SecurityException(msg);
18218    }
18219
18220    public void updateConfiguration(Configuration values) {
18221        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18222                "updateConfiguration()");
18223
18224        synchronized(this) {
18225            if (values == null && mWindowManager != null) {
18226                // sentinel: fetch the current configuration from the window manager
18227                values = mWindowManager.computeNewConfiguration();
18228            }
18229
18230            if (mWindowManager != null) {
18231                mProcessList.applyDisplaySize(mWindowManager);
18232            }
18233
18234            final long origId = Binder.clearCallingIdentity();
18235            if (values != null) {
18236                Settings.System.clearConfiguration(values);
18237            }
18238            updateConfigurationLocked(values, null, false);
18239            Binder.restoreCallingIdentity(origId);
18240        }
18241    }
18242
18243    void updateUserConfigurationLocked() {
18244        Configuration configuration = new Configuration(mConfiguration);
18245        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18246                mUserController.getCurrentUserIdLocked());
18247        updateConfigurationLocked(configuration, null, false);
18248    }
18249
18250    boolean updateConfigurationLocked(Configuration values,
18251            ActivityRecord starting, boolean initLocale) {
18252        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18253        return updateConfigurationLocked(values, starting, initLocale, false,
18254                UserHandle.USER_NULL);
18255    }
18256
18257    // To cache the list of supported system locales
18258    private String[] mSupportedSystemLocales = null;
18259
18260    /**
18261     * Do either or both things: (1) change the current configuration, and (2)
18262     * make sure the given activity is running with the (now) current
18263     * configuration.  Returns true if the activity has been left running, or
18264     * false if <var>starting</var> is being destroyed to match the new
18265     * configuration.
18266     *
18267     * @param userId is only used when persistent parameter is set to true to persist configuration
18268     *               for that particular user
18269     */
18270    private boolean updateConfigurationLocked(Configuration values,
18271            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18272        int changes = 0;
18273
18274        if (mWindowManager != null) {
18275            mWindowManager.deferSurfaceLayout();
18276        }
18277        if (values != null) {
18278            Configuration newConfig = new Configuration(mConfiguration);
18279            changes = newConfig.updateFrom(values);
18280            if (changes != 0) {
18281                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18282                        "Updating configuration to: " + values);
18283
18284                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18285
18286                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18287                    final Locale locale;
18288                    if (values.getLocales().size() == 1) {
18289                        // This is an optimization to avoid the JNI call when the result of
18290                        // getFirstMatch() does not depend on the supported locales.
18291                        locale = values.getLocales().get(0);
18292                    } else {
18293                        if (mSupportedSystemLocales == null) {
18294                            mSupportedSystemLocales =
18295                                    Resources.getSystem().getAssets().getLocales();
18296                        }
18297                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18298                    }
18299                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18300                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18301                            locale));
18302                }
18303
18304                mConfigurationSeq++;
18305                if (mConfigurationSeq <= 0) {
18306                    mConfigurationSeq = 1;
18307                }
18308                newConfig.seq = mConfigurationSeq;
18309                mConfiguration = newConfig;
18310                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18311                mUsageStatsService.reportConfigurationChange(newConfig,
18312                        mUserController.getCurrentUserIdLocked());
18313                //mUsageStatsService.noteStartConfig(newConfig);
18314
18315                final Configuration configCopy = new Configuration(mConfiguration);
18316
18317                // TODO: If our config changes, should we auto dismiss any currently
18318                // showing dialogs?
18319                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18320
18321                AttributeCache ac = AttributeCache.instance();
18322                if (ac != null) {
18323                    ac.updateConfiguration(configCopy);
18324                }
18325
18326                // Make sure all resources in our process are updated
18327                // right now, so that anyone who is going to retrieve
18328                // resource values after we return will be sure to get
18329                // the new ones.  This is especially important during
18330                // boot, where the first config change needs to guarantee
18331                // all resources have that config before following boot
18332                // code is executed.
18333                mSystemThread.applyConfigurationToResources(configCopy);
18334
18335                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18336                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18337                    msg.obj = new Configuration(configCopy);
18338                    msg.arg1 = userId;
18339                    mHandler.sendMessage(msg);
18340                }
18341
18342                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18343                if (isDensityChange) {
18344                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18345                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18346                }
18347
18348                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18349                    ProcessRecord app = mLruProcesses.get(i);
18350                    try {
18351                        if (app.thread != null) {
18352                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18353                                    + app.processName + " new config " + mConfiguration);
18354                            app.thread.scheduleConfigurationChanged(configCopy);
18355                        }
18356                    } catch (Exception e) {
18357                    }
18358                }
18359                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18360                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18361                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18362                        | Intent.FLAG_RECEIVER_FOREGROUND);
18363                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18364                        null, AppOpsManager.OP_NONE, null, false, false,
18365                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18366                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18367                    // Tell the shortcut manager that the system locale changed.  It needs to know
18368                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18369                    // we "push" from here, rather than having the service listen to the broadcast.
18370                    final ShortcutServiceInternal shortcutService =
18371                            LocalServices.getService(ShortcutServiceInternal.class);
18372                    if (shortcutService != null) {
18373                        shortcutService.onSystemLocaleChangedNoLock();
18374                    }
18375
18376                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18377                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18378                    if (!mProcessesReady) {
18379                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18380                    }
18381                    broadcastIntentLocked(null, null, intent,
18382                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18383                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18384                }
18385            }
18386            // Update the configuration with WM first and check if any of the stacks need to be
18387            // resized due to the configuration change. If so, resize the stacks now and do any
18388            // relaunches if necessary. This way we don't need to relaunch again below in
18389            // ensureActivityConfigurationLocked().
18390            if (mWindowManager != null) {
18391                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18392                if (resizedStacks != null) {
18393                    for (int stackId : resizedStacks) {
18394                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18395                        mStackSupervisor.resizeStackLocked(
18396                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18397                    }
18398                }
18399            }
18400        }
18401
18402        boolean kept = true;
18403        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18404        // mainStack is null during startup.
18405        if (mainStack != null) {
18406            if (changes != 0 && starting == null) {
18407                // If the configuration changed, and the caller is not already
18408                // in the process of starting an activity, then find the top
18409                // activity to check if its configuration needs to change.
18410                starting = mainStack.topRunningActivityLocked();
18411            }
18412
18413            if (starting != null) {
18414                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18415                // And we need to make sure at this point that all other activities
18416                // are made visible with the correct configuration.
18417                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18418                        !PRESERVE_WINDOWS);
18419            }
18420        }
18421        if (mWindowManager != null) {
18422            mWindowManager.continueSurfaceLayout();
18423        }
18424        return kept;
18425    }
18426
18427    /**
18428     * Decide based on the configuration whether we should shouw the ANR,
18429     * crash, etc dialogs.  The idea is that if there is no affordence to
18430     * press the on-screen buttons, or the user experience would be more
18431     * greatly impacted than the crash itself, we shouldn't show the dialog.
18432     *
18433     * A thought: SystemUI might also want to get told about this, the Power
18434     * dialog / global actions also might want different behaviors.
18435     */
18436    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18437        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18438                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18439                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18440        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
18441        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
18442                && (modeType != Configuration.UI_MODE_TYPE_WATCH || "eng".equals(Build.TYPE)));
18443        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
18444    }
18445
18446    @Override
18447    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18448        synchronized (this) {
18449            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18450            if (srec != null) {
18451                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18452            }
18453        }
18454        return false;
18455    }
18456
18457    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18458            Intent resultData) {
18459
18460        synchronized (this) {
18461            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18462            if (r != null) {
18463                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18464            }
18465            return false;
18466        }
18467    }
18468
18469    public int getLaunchedFromUid(IBinder activityToken) {
18470        ActivityRecord srec;
18471        synchronized (this) {
18472            srec = ActivityRecord.forTokenLocked(activityToken);
18473        }
18474        if (srec == null) {
18475            return -1;
18476        }
18477        return srec.launchedFromUid;
18478    }
18479
18480    public String getLaunchedFromPackage(IBinder activityToken) {
18481        ActivityRecord srec;
18482        synchronized (this) {
18483            srec = ActivityRecord.forTokenLocked(activityToken);
18484        }
18485        if (srec == null) {
18486            return null;
18487        }
18488        return srec.launchedFromPackage;
18489    }
18490
18491    // =========================================================
18492    // LIFETIME MANAGEMENT
18493    // =========================================================
18494
18495    // Returns which broadcast queue the app is the current [or imminent] receiver
18496    // on, or 'null' if the app is not an active broadcast recipient.
18497    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18498        BroadcastRecord r = app.curReceiver;
18499        if (r != null) {
18500            return r.queue;
18501        }
18502
18503        // It's not the current receiver, but it might be starting up to become one
18504        synchronized (this) {
18505            for (BroadcastQueue queue : mBroadcastQueues) {
18506                r = queue.mPendingBroadcast;
18507                if (r != null && r.curApp == app) {
18508                    // found it; report which queue it's in
18509                    return queue;
18510                }
18511            }
18512        }
18513
18514        return null;
18515    }
18516
18517    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18518            int targetUid, ComponentName targetComponent, String targetProcess) {
18519        if (!mTrackingAssociations) {
18520            return null;
18521        }
18522        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18523                = mAssociations.get(targetUid);
18524        if (components == null) {
18525            components = new ArrayMap<>();
18526            mAssociations.put(targetUid, components);
18527        }
18528        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18529        if (sourceUids == null) {
18530            sourceUids = new SparseArray<>();
18531            components.put(targetComponent, sourceUids);
18532        }
18533        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18534        if (sourceProcesses == null) {
18535            sourceProcesses = new ArrayMap<>();
18536            sourceUids.put(sourceUid, sourceProcesses);
18537        }
18538        Association ass = sourceProcesses.get(sourceProcess);
18539        if (ass == null) {
18540            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18541                    targetProcess);
18542            sourceProcesses.put(sourceProcess, ass);
18543        }
18544        ass.mCount++;
18545        ass.mNesting++;
18546        if (ass.mNesting == 1) {
18547            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18548            ass.mLastState = sourceState;
18549        }
18550        return ass;
18551    }
18552
18553    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18554            ComponentName targetComponent) {
18555        if (!mTrackingAssociations) {
18556            return;
18557        }
18558        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18559                = mAssociations.get(targetUid);
18560        if (components == null) {
18561            return;
18562        }
18563        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18564        if (sourceUids == null) {
18565            return;
18566        }
18567        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18568        if (sourceProcesses == null) {
18569            return;
18570        }
18571        Association ass = sourceProcesses.get(sourceProcess);
18572        if (ass == null || ass.mNesting <= 0) {
18573            return;
18574        }
18575        ass.mNesting--;
18576        if (ass.mNesting == 0) {
18577            long uptime = SystemClock.uptimeMillis();
18578            ass.mTime += uptime - ass.mStartTime;
18579            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18580                    += uptime - ass.mLastStateUptime;
18581            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18582        }
18583    }
18584
18585    private void noteUidProcessState(final int uid, final int state) {
18586        mBatteryStatsService.noteUidProcessState(uid, state);
18587        if (mTrackingAssociations) {
18588            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18589                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18590                        = mAssociations.valueAt(i1);
18591                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18592                    SparseArray<ArrayMap<String, Association>> sourceUids
18593                            = targetComponents.valueAt(i2);
18594                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18595                    if (sourceProcesses != null) {
18596                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18597                            Association ass = sourceProcesses.valueAt(i4);
18598                            if (ass.mNesting >= 1) {
18599                                // currently associated
18600                                long uptime = SystemClock.uptimeMillis();
18601                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18602                                        += uptime - ass.mLastStateUptime;
18603                                ass.mLastState = state;
18604                                ass.mLastStateUptime = uptime;
18605                            }
18606                        }
18607                    }
18608                }
18609            }
18610        }
18611    }
18612
18613    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18614            boolean doingAll, long now) {
18615        if (mAdjSeq == app.adjSeq) {
18616            // This adjustment has already been computed.
18617            return app.curRawAdj;
18618        }
18619
18620        if (app.thread == null) {
18621            app.adjSeq = mAdjSeq;
18622            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18623            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18624            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18625        }
18626
18627        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18628        app.adjSource = null;
18629        app.adjTarget = null;
18630        app.empty = false;
18631        app.cached = false;
18632
18633        final int activitiesSize = app.activities.size();
18634
18635        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18636            // The max adjustment doesn't allow this app to be anything
18637            // below foreground, so it is not worth doing work for it.
18638            app.adjType = "fixed";
18639            app.adjSeq = mAdjSeq;
18640            app.curRawAdj = app.maxAdj;
18641            app.foregroundActivities = false;
18642            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18643            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18644            // System processes can do UI, and when they do we want to have
18645            // them trim their memory after the user leaves the UI.  To
18646            // facilitate this, here we need to determine whether or not it
18647            // is currently showing UI.
18648            app.systemNoUi = true;
18649            if (app == TOP_APP) {
18650                app.systemNoUi = false;
18651                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18652                app.adjType = "pers-top-activity";
18653            } else if (activitiesSize > 0) {
18654                for (int j = 0; j < activitiesSize; j++) {
18655                    final ActivityRecord r = app.activities.get(j);
18656                    if (r.visible) {
18657                        app.systemNoUi = false;
18658                    }
18659                }
18660            }
18661            if (!app.systemNoUi) {
18662                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18663            }
18664            return (app.curAdj=app.maxAdj);
18665        }
18666
18667        app.systemNoUi = false;
18668
18669        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18670
18671        // Determine the importance of the process, starting with most
18672        // important to least, and assign an appropriate OOM adjustment.
18673        int adj;
18674        int schedGroup;
18675        int procState;
18676        boolean foregroundActivities = false;
18677        BroadcastQueue queue;
18678        if (app == TOP_APP) {
18679            // The last app on the list is the foreground app.
18680            adj = ProcessList.FOREGROUND_APP_ADJ;
18681            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18682            app.adjType = "top-activity";
18683            foregroundActivities = true;
18684            procState = PROCESS_STATE_CUR_TOP;
18685        } else if (app.instrumentationClass != null) {
18686            // Don't want to kill running instrumentation.
18687            adj = ProcessList.FOREGROUND_APP_ADJ;
18688            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18689            app.adjType = "instrumentation";
18690            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18691        } else if ((queue = isReceivingBroadcast(app)) != null) {
18692            // An app that is currently receiving a broadcast also
18693            // counts as being in the foreground for OOM killer purposes.
18694            // It's placed in a sched group based on the nature of the
18695            // broadcast as reflected by which queue it's active in.
18696            adj = ProcessList.FOREGROUND_APP_ADJ;
18697            schedGroup = (queue == mFgBroadcastQueue)
18698                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18699            app.adjType = "broadcast";
18700            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18701        } else if (app.executingServices.size() > 0) {
18702            // An app that is currently executing a service callback also
18703            // counts as being in the foreground.
18704            adj = ProcessList.FOREGROUND_APP_ADJ;
18705            schedGroup = app.execServicesFg ?
18706                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18707            app.adjType = "exec-service";
18708            procState = ActivityManager.PROCESS_STATE_SERVICE;
18709            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18710        } else {
18711            // As far as we know the process is empty.  We may change our mind later.
18712            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18713            // At this point we don't actually know the adjustment.  Use the cached adj
18714            // value that the caller wants us to.
18715            adj = cachedAdj;
18716            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18717            app.cached = true;
18718            app.empty = true;
18719            app.adjType = "cch-empty";
18720        }
18721
18722        // Examine all activities if not already foreground.
18723        if (!foregroundActivities && activitiesSize > 0) {
18724            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18725            for (int j = 0; j < activitiesSize; j++) {
18726                final ActivityRecord r = app.activities.get(j);
18727                if (r.app != app) {
18728                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18729                            + " instead of expected " + app);
18730                    if (r.app == null || (r.app.uid == app.uid)) {
18731                        // Only fix things up when they look sane
18732                        r.app = app;
18733                    } else {
18734                        continue;
18735                    }
18736                }
18737                if (r.visible) {
18738                    // App has a visible activity; only upgrade adjustment.
18739                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18740                        adj = ProcessList.VISIBLE_APP_ADJ;
18741                        app.adjType = "visible";
18742                    }
18743                    if (procState > PROCESS_STATE_CUR_TOP) {
18744                        procState = PROCESS_STATE_CUR_TOP;
18745                    }
18746                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18747                    app.cached = false;
18748                    app.empty = false;
18749                    foregroundActivities = true;
18750                    if (r.task != null && minLayer > 0) {
18751                        final int layer = r.task.mLayerRank;
18752                        if (layer >= 0 && minLayer > layer) {
18753                            minLayer = layer;
18754                        }
18755                    }
18756                    break;
18757                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18758                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18759                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18760                        app.adjType = "pausing";
18761                    }
18762                    if (procState > PROCESS_STATE_CUR_TOP) {
18763                        procState = PROCESS_STATE_CUR_TOP;
18764                    }
18765                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18766                    app.cached = false;
18767                    app.empty = false;
18768                    foregroundActivities = true;
18769                } else if (r.state == ActivityState.STOPPING) {
18770                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18771                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18772                        app.adjType = "stopping";
18773                    }
18774                    // For the process state, we will at this point consider the
18775                    // process to be cached.  It will be cached either as an activity
18776                    // or empty depending on whether the activity is finishing.  We do
18777                    // this so that we can treat the process as cached for purposes of
18778                    // memory trimming (determing current memory level, trim command to
18779                    // send to process) since there can be an arbitrary number of stopping
18780                    // processes and they should soon all go into the cached state.
18781                    if (!r.finishing) {
18782                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18783                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18784                        }
18785                    }
18786                    app.cached = false;
18787                    app.empty = false;
18788                    foregroundActivities = true;
18789                } else {
18790                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18791                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18792                        app.adjType = "cch-act";
18793                    }
18794                }
18795            }
18796            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18797                adj += minLayer;
18798            }
18799        }
18800
18801        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18802                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18803            if (app.foregroundServices) {
18804                // The user is aware of this app, so make it visible.
18805                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18806                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18807                app.cached = false;
18808                app.adjType = "fg-service";
18809                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18810            } else if (app.forcingToForeground != null) {
18811                // The user is aware of this app, so make it visible.
18812                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18813                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18814                app.cached = false;
18815                app.adjType = "force-fg";
18816                app.adjSource = app.forcingToForeground;
18817                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18818            }
18819        }
18820
18821        if (app == mHeavyWeightProcess) {
18822            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18823                // We don't want to kill the current heavy-weight process.
18824                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18825                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18826                app.cached = false;
18827                app.adjType = "heavy";
18828            }
18829            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18830                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18831            }
18832        }
18833
18834        if (app == mHomeProcess) {
18835            if (adj > ProcessList.HOME_APP_ADJ) {
18836                // This process is hosting what we currently consider to be the
18837                // home app, so we don't want to let it go into the background.
18838                adj = ProcessList.HOME_APP_ADJ;
18839                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18840                app.cached = false;
18841                app.adjType = "home";
18842            }
18843            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18844                procState = ActivityManager.PROCESS_STATE_HOME;
18845            }
18846        }
18847
18848        if (app == mPreviousProcess && app.activities.size() > 0) {
18849            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18850                // This was the previous process that showed UI to the user.
18851                // We want to try to keep it around more aggressively, to give
18852                // a good experience around switching between two apps.
18853                adj = ProcessList.PREVIOUS_APP_ADJ;
18854                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18855                app.cached = false;
18856                app.adjType = "previous";
18857            }
18858            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18859                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18860            }
18861        }
18862
18863        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18864                + " reason=" + app.adjType);
18865
18866        // By default, we use the computed adjustment.  It may be changed if
18867        // there are applications dependent on our services or providers, but
18868        // this gives us a baseline and makes sure we don't get into an
18869        // infinite recursion.
18870        app.adjSeq = mAdjSeq;
18871        app.curRawAdj = adj;
18872        app.hasStartedServices = false;
18873
18874        if (mBackupTarget != null && app == mBackupTarget.app) {
18875            // If possible we want to avoid killing apps while they're being backed up
18876            if (adj > ProcessList.BACKUP_APP_ADJ) {
18877                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18878                adj = ProcessList.BACKUP_APP_ADJ;
18879                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18880                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18881                }
18882                app.adjType = "backup";
18883                app.cached = false;
18884            }
18885            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18886                procState = ActivityManager.PROCESS_STATE_BACKUP;
18887            }
18888        }
18889
18890        boolean mayBeTop = false;
18891
18892        for (int is = app.services.size()-1;
18893                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18894                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18895                        || procState > ActivityManager.PROCESS_STATE_TOP);
18896                is--) {
18897            ServiceRecord s = app.services.valueAt(is);
18898            if (s.startRequested) {
18899                app.hasStartedServices = true;
18900                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18901                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18902                }
18903                if (app.hasShownUi && app != mHomeProcess) {
18904                    // If this process has shown some UI, let it immediately
18905                    // go to the LRU list because it may be pretty heavy with
18906                    // UI stuff.  We'll tag it with a label just to help
18907                    // debug and understand what is going on.
18908                    if (adj > ProcessList.SERVICE_ADJ) {
18909                        app.adjType = "cch-started-ui-services";
18910                    }
18911                } else {
18912                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18913                        // This service has seen some activity within
18914                        // recent memory, so we will keep its process ahead
18915                        // of the background processes.
18916                        if (adj > ProcessList.SERVICE_ADJ) {
18917                            adj = ProcessList.SERVICE_ADJ;
18918                            app.adjType = "started-services";
18919                            app.cached = false;
18920                        }
18921                    }
18922                    // If we have let the service slide into the background
18923                    // state, still have some text describing what it is doing
18924                    // even though the service no longer has an impact.
18925                    if (adj > ProcessList.SERVICE_ADJ) {
18926                        app.adjType = "cch-started-services";
18927                    }
18928                }
18929            }
18930            for (int conni = s.connections.size()-1;
18931                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18932                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18933                            || procState > ActivityManager.PROCESS_STATE_TOP);
18934                    conni--) {
18935                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18936                for (int i = 0;
18937                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18938                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18939                                || procState > ActivityManager.PROCESS_STATE_TOP);
18940                        i++) {
18941                    // XXX should compute this based on the max of
18942                    // all connected clients.
18943                    ConnectionRecord cr = clist.get(i);
18944                    if (cr.binding.client == app) {
18945                        // Binding to ourself is not interesting.
18946                        continue;
18947                    }
18948                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18949                        ProcessRecord client = cr.binding.client;
18950                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18951                                TOP_APP, doingAll, now);
18952                        int clientProcState = client.curProcState;
18953                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18954                            // If the other app is cached for any reason, for purposes here
18955                            // we are going to consider it empty.  The specific cached state
18956                            // doesn't propagate except under certain conditions.
18957                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18958                        }
18959                        String adjType = null;
18960                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18961                            // Not doing bind OOM management, so treat
18962                            // this guy more like a started service.
18963                            if (app.hasShownUi && app != mHomeProcess) {
18964                                // If this process has shown some UI, let it immediately
18965                                // go to the LRU list because it may be pretty heavy with
18966                                // UI stuff.  We'll tag it with a label just to help
18967                                // debug and understand what is going on.
18968                                if (adj > clientAdj) {
18969                                    adjType = "cch-bound-ui-services";
18970                                }
18971                                app.cached = false;
18972                                clientAdj = adj;
18973                                clientProcState = procState;
18974                            } else {
18975                                if (now >= (s.lastActivity
18976                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18977                                    // This service has not seen activity within
18978                                    // recent memory, so allow it to drop to the
18979                                    // LRU list if there is no other reason to keep
18980                                    // it around.  We'll also tag it with a label just
18981                                    // to help debug and undertand what is going on.
18982                                    if (adj > clientAdj) {
18983                                        adjType = "cch-bound-services";
18984                                    }
18985                                    clientAdj = adj;
18986                                }
18987                            }
18988                        }
18989                        if (adj > clientAdj) {
18990                            // If this process has recently shown UI, and
18991                            // the process that is binding to it is less
18992                            // important than being visible, then we don't
18993                            // care about the binding as much as we care
18994                            // about letting this process get into the LRU
18995                            // list to be killed and restarted if needed for
18996                            // memory.
18997                            if (app.hasShownUi && app != mHomeProcess
18998                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18999                                adjType = "cch-bound-ui-services";
19000                            } else {
19001                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19002                                        |Context.BIND_IMPORTANT)) != 0) {
19003                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19004                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19005                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19006                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19007                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19008                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19009                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19010                                    adj = clientAdj;
19011                                } else {
19012                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19013                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19014                                    }
19015                                }
19016                                if (!client.cached) {
19017                                    app.cached = false;
19018                                }
19019                                adjType = "service";
19020                            }
19021                        }
19022                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19023                            // This will treat important bound services identically to
19024                            // the top app, which may behave differently than generic
19025                            // foreground work.
19026                            if (client.curSchedGroup > schedGroup) {
19027                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19028                                    schedGroup = client.curSchedGroup;
19029                                } else {
19030                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19031                                }
19032                            }
19033                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19034                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19035                                    // Special handling of clients who are in the top state.
19036                                    // We *may* want to consider this process to be in the
19037                                    // top state as well, but only if there is not another
19038                                    // reason for it to be running.  Being on the top is a
19039                                    // special state, meaning you are specifically running
19040                                    // for the current top app.  If the process is already
19041                                    // running in the background for some other reason, it
19042                                    // is more important to continue considering it to be
19043                                    // in the background state.
19044                                    mayBeTop = true;
19045                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19046                                } else {
19047                                    // Special handling for above-top states (persistent
19048                                    // processes).  These should not bring the current process
19049                                    // into the top state, since they are not on top.  Instead
19050                                    // give them the best state after that.
19051                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19052                                        clientProcState =
19053                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19054                                    } else if (mWakefulness
19055                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19056                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19057                                                    != 0) {
19058                                        clientProcState =
19059                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19060                                    } else {
19061                                        clientProcState =
19062                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19063                                    }
19064                                }
19065                            }
19066                        } else {
19067                            if (clientProcState <
19068                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19069                                clientProcState =
19070                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19071                            }
19072                        }
19073                        if (procState > clientProcState) {
19074                            procState = clientProcState;
19075                        }
19076                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19077                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19078                            app.pendingUiClean = true;
19079                        }
19080                        if (adjType != null) {
19081                            app.adjType = adjType;
19082                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19083                                    .REASON_SERVICE_IN_USE;
19084                            app.adjSource = cr.binding.client;
19085                            app.adjSourceProcState = clientProcState;
19086                            app.adjTarget = s.name;
19087                        }
19088                    }
19089                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19090                        app.treatLikeActivity = true;
19091                    }
19092                    final ActivityRecord a = cr.activity;
19093                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19094                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19095                            (a.visible || a.state == ActivityState.RESUMED ||
19096                             a.state == ActivityState.PAUSING)) {
19097                            adj = ProcessList.FOREGROUND_APP_ADJ;
19098                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19099                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19100                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19101                                } else {
19102                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19103                                }
19104                            }
19105                            app.cached = false;
19106                            app.adjType = "service";
19107                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19108                                    .REASON_SERVICE_IN_USE;
19109                            app.adjSource = a;
19110                            app.adjSourceProcState = procState;
19111                            app.adjTarget = s.name;
19112                        }
19113                    }
19114                }
19115            }
19116        }
19117
19118        for (int provi = app.pubProviders.size()-1;
19119                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19120                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19121                        || procState > ActivityManager.PROCESS_STATE_TOP);
19122                provi--) {
19123            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19124            for (int i = cpr.connections.size()-1;
19125                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19126                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19127                            || procState > ActivityManager.PROCESS_STATE_TOP);
19128                    i--) {
19129                ContentProviderConnection conn = cpr.connections.get(i);
19130                ProcessRecord client = conn.client;
19131                if (client == app) {
19132                    // Being our own client is not interesting.
19133                    continue;
19134                }
19135                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19136                int clientProcState = client.curProcState;
19137                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19138                    // If the other app is cached for any reason, for purposes here
19139                    // we are going to consider it empty.
19140                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19141                }
19142                if (adj > clientAdj) {
19143                    if (app.hasShownUi && app != mHomeProcess
19144                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19145                        app.adjType = "cch-ui-provider";
19146                    } else {
19147                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19148                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19149                        app.adjType = "provider";
19150                    }
19151                    app.cached &= client.cached;
19152                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19153                            .REASON_PROVIDER_IN_USE;
19154                    app.adjSource = client;
19155                    app.adjSourceProcState = clientProcState;
19156                    app.adjTarget = cpr.name;
19157                }
19158                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19159                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19160                        // Special handling of clients who are in the top state.
19161                        // We *may* want to consider this process to be in the
19162                        // top state as well, but only if there is not another
19163                        // reason for it to be running.  Being on the top is a
19164                        // special state, meaning you are specifically running
19165                        // for the current top app.  If the process is already
19166                        // running in the background for some other reason, it
19167                        // is more important to continue considering it to be
19168                        // in the background state.
19169                        mayBeTop = true;
19170                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19171                    } else {
19172                        // Special handling for above-top states (persistent
19173                        // processes).  These should not bring the current process
19174                        // into the top state, since they are not on top.  Instead
19175                        // give them the best state after that.
19176                        clientProcState =
19177                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19178                    }
19179                }
19180                if (procState > clientProcState) {
19181                    procState = clientProcState;
19182                }
19183                if (client.curSchedGroup > schedGroup) {
19184                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19185                }
19186            }
19187            // If the provider has external (non-framework) process
19188            // dependencies, ensure that its adjustment is at least
19189            // FOREGROUND_APP_ADJ.
19190            if (cpr.hasExternalProcessHandles()) {
19191                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19192                    adj = ProcessList.FOREGROUND_APP_ADJ;
19193                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19194                    app.cached = false;
19195                    app.adjType = "provider";
19196                    app.adjTarget = cpr.name;
19197                }
19198                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19199                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19200                }
19201            }
19202        }
19203
19204        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19205            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19206                adj = ProcessList.PREVIOUS_APP_ADJ;
19207                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19208                app.cached = false;
19209                app.adjType = "provider";
19210            }
19211            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19212                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19213            }
19214        }
19215
19216        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19217            // A client of one of our services or providers is in the top state.  We
19218            // *may* want to be in the top state, but not if we are already running in
19219            // the background for some other reason.  For the decision here, we are going
19220            // to pick out a few specific states that we want to remain in when a client
19221            // is top (states that tend to be longer-term) and otherwise allow it to go
19222            // to the top state.
19223            switch (procState) {
19224                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19225                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19226                case ActivityManager.PROCESS_STATE_SERVICE:
19227                    // These all are longer-term states, so pull them up to the top
19228                    // of the background states, but not all the way to the top state.
19229                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19230                    break;
19231                default:
19232                    // Otherwise, top is a better choice, so take it.
19233                    procState = ActivityManager.PROCESS_STATE_TOP;
19234                    break;
19235            }
19236        }
19237
19238        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19239            if (app.hasClientActivities) {
19240                // This is a cached process, but with client activities.  Mark it so.
19241                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19242                app.adjType = "cch-client-act";
19243            } else if (app.treatLikeActivity) {
19244                // This is a cached process, but somebody wants us to treat it like it has
19245                // an activity, okay!
19246                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19247                app.adjType = "cch-as-act";
19248            }
19249        }
19250
19251        if (adj == ProcessList.SERVICE_ADJ) {
19252            if (doingAll) {
19253                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19254                mNewNumServiceProcs++;
19255                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19256                if (!app.serviceb) {
19257                    // This service isn't far enough down on the LRU list to
19258                    // normally be a B service, but if we are low on RAM and it
19259                    // is large we want to force it down since we would prefer to
19260                    // keep launcher over it.
19261                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19262                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19263                        app.serviceHighRam = true;
19264                        app.serviceb = true;
19265                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19266                    } else {
19267                        mNewNumAServiceProcs++;
19268                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19269                    }
19270                } else {
19271                    app.serviceHighRam = false;
19272                }
19273            }
19274            if (app.serviceb) {
19275                adj = ProcessList.SERVICE_B_ADJ;
19276            }
19277        }
19278
19279        app.curRawAdj = adj;
19280
19281        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19282        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19283        if (adj > app.maxAdj) {
19284            adj = app.maxAdj;
19285            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19286                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19287            }
19288        }
19289
19290        // Do final modification to adj.  Everything we do between here and applying
19291        // the final setAdj must be done in this function, because we will also use
19292        // it when computing the final cached adj later.  Note that we don't need to
19293        // worry about this for max adj above, since max adj will always be used to
19294        // keep it out of the cached vaues.
19295        app.curAdj = app.modifyRawOomAdj(adj);
19296        app.curSchedGroup = schedGroup;
19297        app.curProcState = procState;
19298        app.foregroundActivities = foregroundActivities;
19299
19300        return app.curRawAdj;
19301    }
19302
19303    /**
19304     * Record new PSS sample for a process.
19305     */
19306    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19307            long now) {
19308        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19309                swapPss * 1024);
19310        proc.lastPssTime = now;
19311        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19312        if (DEBUG_PSS) Slog.d(TAG_PSS,
19313                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19314                + " state=" + ProcessList.makeProcStateString(procState));
19315        if (proc.initialIdlePss == 0) {
19316            proc.initialIdlePss = pss;
19317        }
19318        proc.lastPss = pss;
19319        proc.lastSwapPss = swapPss;
19320        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19321            proc.lastCachedPss = pss;
19322            proc.lastCachedSwapPss = swapPss;
19323        }
19324
19325        final SparseArray<Pair<Long, String>> watchUids
19326                = mMemWatchProcesses.getMap().get(proc.processName);
19327        Long check = null;
19328        if (watchUids != null) {
19329            Pair<Long, String> val = watchUids.get(proc.uid);
19330            if (val == null) {
19331                val = watchUids.get(0);
19332            }
19333            if (val != null) {
19334                check = val.first;
19335            }
19336        }
19337        if (check != null) {
19338            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19339                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19340                if (!isDebuggable) {
19341                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19342                        isDebuggable = true;
19343                    }
19344                }
19345                if (isDebuggable) {
19346                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19347                    final ProcessRecord myProc = proc;
19348                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19349                    mMemWatchDumpProcName = proc.processName;
19350                    mMemWatchDumpFile = heapdumpFile.toString();
19351                    mMemWatchDumpPid = proc.pid;
19352                    mMemWatchDumpUid = proc.uid;
19353                    BackgroundThread.getHandler().post(new Runnable() {
19354                        @Override
19355                        public void run() {
19356                            revokeUriPermission(ActivityThread.currentActivityThread()
19357                                            .getApplicationThread(),
19358                                    DumpHeapActivity.JAVA_URI,
19359                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19360                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19361                                    UserHandle.myUserId());
19362                            ParcelFileDescriptor fd = null;
19363                            try {
19364                                heapdumpFile.delete();
19365                                fd = ParcelFileDescriptor.open(heapdumpFile,
19366                                        ParcelFileDescriptor.MODE_CREATE |
19367                                                ParcelFileDescriptor.MODE_TRUNCATE |
19368                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19369                                                ParcelFileDescriptor.MODE_APPEND);
19370                                IApplicationThread thread = myProc.thread;
19371                                if (thread != null) {
19372                                    try {
19373                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19374                                                "Requesting dump heap from "
19375                                                + myProc + " to " + heapdumpFile);
19376                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19377                                    } catch (RemoteException e) {
19378                                    }
19379                                }
19380                            } catch (FileNotFoundException e) {
19381                                e.printStackTrace();
19382                            } finally {
19383                                if (fd != null) {
19384                                    try {
19385                                        fd.close();
19386                                    } catch (IOException e) {
19387                                    }
19388                                }
19389                            }
19390                        }
19391                    });
19392                } else {
19393                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19394                            + ", but debugging not enabled");
19395                }
19396            }
19397        }
19398    }
19399
19400    /**
19401     * Schedule PSS collection of a process.
19402     */
19403    void requestPssLocked(ProcessRecord proc, int procState) {
19404        if (mPendingPssProcesses.contains(proc)) {
19405            return;
19406        }
19407        if (mPendingPssProcesses.size() == 0) {
19408            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19409        }
19410        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19411        proc.pssProcState = procState;
19412        mPendingPssProcesses.add(proc);
19413    }
19414
19415    /**
19416     * Schedule PSS collection of all processes.
19417     */
19418    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19419        if (!always) {
19420            if (now < (mLastFullPssTime +
19421                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19422                return;
19423            }
19424        }
19425        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19426        mLastFullPssTime = now;
19427        mFullPssPending = true;
19428        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19429        mPendingPssProcesses.clear();
19430        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19431            ProcessRecord app = mLruProcesses.get(i);
19432            if (app.thread == null
19433                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19434                continue;
19435            }
19436            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19437                app.pssProcState = app.setProcState;
19438                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19439                        mTestPssMode, isSleeping(), now);
19440                mPendingPssProcesses.add(app);
19441            }
19442        }
19443        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19444    }
19445
19446    public void setTestPssMode(boolean enabled) {
19447        synchronized (this) {
19448            mTestPssMode = enabled;
19449            if (enabled) {
19450                // Whenever we enable the mode, we want to take a snapshot all of current
19451                // process mem use.
19452                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19453            }
19454        }
19455    }
19456
19457    /**
19458     * Ask a given process to GC right now.
19459     */
19460    final void performAppGcLocked(ProcessRecord app) {
19461        try {
19462            app.lastRequestedGc = SystemClock.uptimeMillis();
19463            if (app.thread != null) {
19464                if (app.reportLowMemory) {
19465                    app.reportLowMemory = false;
19466                    app.thread.scheduleLowMemory();
19467                } else {
19468                    app.thread.processInBackground();
19469                }
19470            }
19471        } catch (Exception e) {
19472            // whatever.
19473        }
19474    }
19475
19476    /**
19477     * Returns true if things are idle enough to perform GCs.
19478     */
19479    private final boolean canGcNowLocked() {
19480        boolean processingBroadcasts = false;
19481        for (BroadcastQueue q : mBroadcastQueues) {
19482            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19483                processingBroadcasts = true;
19484            }
19485        }
19486        return !processingBroadcasts
19487                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19488    }
19489
19490    /**
19491     * Perform GCs on all processes that are waiting for it, but only
19492     * if things are idle.
19493     */
19494    final void performAppGcsLocked() {
19495        final int N = mProcessesToGc.size();
19496        if (N <= 0) {
19497            return;
19498        }
19499        if (canGcNowLocked()) {
19500            while (mProcessesToGc.size() > 0) {
19501                ProcessRecord proc = mProcessesToGc.remove(0);
19502                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19503                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19504                            <= SystemClock.uptimeMillis()) {
19505                        // To avoid spamming the system, we will GC processes one
19506                        // at a time, waiting a few seconds between each.
19507                        performAppGcLocked(proc);
19508                        scheduleAppGcsLocked();
19509                        return;
19510                    } else {
19511                        // It hasn't been long enough since we last GCed this
19512                        // process...  put it in the list to wait for its time.
19513                        addProcessToGcListLocked(proc);
19514                        break;
19515                    }
19516                }
19517            }
19518
19519            scheduleAppGcsLocked();
19520        }
19521    }
19522
19523    /**
19524     * If all looks good, perform GCs on all processes waiting for them.
19525     */
19526    final void performAppGcsIfAppropriateLocked() {
19527        if (canGcNowLocked()) {
19528            performAppGcsLocked();
19529            return;
19530        }
19531        // Still not idle, wait some more.
19532        scheduleAppGcsLocked();
19533    }
19534
19535    /**
19536     * Schedule the execution of all pending app GCs.
19537     */
19538    final void scheduleAppGcsLocked() {
19539        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19540
19541        if (mProcessesToGc.size() > 0) {
19542            // Schedule a GC for the time to the next process.
19543            ProcessRecord proc = mProcessesToGc.get(0);
19544            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19545
19546            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19547            long now = SystemClock.uptimeMillis();
19548            if (when < (now+GC_TIMEOUT)) {
19549                when = now + GC_TIMEOUT;
19550            }
19551            mHandler.sendMessageAtTime(msg, when);
19552        }
19553    }
19554
19555    /**
19556     * Add a process to the array of processes waiting to be GCed.  Keeps the
19557     * list in sorted order by the last GC time.  The process can't already be
19558     * on the list.
19559     */
19560    final void addProcessToGcListLocked(ProcessRecord proc) {
19561        boolean added = false;
19562        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19563            if (mProcessesToGc.get(i).lastRequestedGc <
19564                    proc.lastRequestedGc) {
19565                added = true;
19566                mProcessesToGc.add(i+1, proc);
19567                break;
19568            }
19569        }
19570        if (!added) {
19571            mProcessesToGc.add(0, proc);
19572        }
19573    }
19574
19575    /**
19576     * Set up to ask a process to GC itself.  This will either do it
19577     * immediately, or put it on the list of processes to gc the next
19578     * time things are idle.
19579     */
19580    final void scheduleAppGcLocked(ProcessRecord app) {
19581        long now = SystemClock.uptimeMillis();
19582        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19583            return;
19584        }
19585        if (!mProcessesToGc.contains(app)) {
19586            addProcessToGcListLocked(app);
19587            scheduleAppGcsLocked();
19588        }
19589    }
19590
19591    final void checkExcessivePowerUsageLocked(boolean doKills) {
19592        updateCpuStatsNow();
19593
19594        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19595        boolean doWakeKills = doKills;
19596        boolean doCpuKills = doKills;
19597        if (mLastPowerCheckRealtime == 0) {
19598            doWakeKills = false;
19599        }
19600        if (mLastPowerCheckUptime == 0) {
19601            doCpuKills = false;
19602        }
19603        if (stats.isScreenOn()) {
19604            doWakeKills = false;
19605        }
19606        final long curRealtime = SystemClock.elapsedRealtime();
19607        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19608        final long curUptime = SystemClock.uptimeMillis();
19609        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19610        mLastPowerCheckRealtime = curRealtime;
19611        mLastPowerCheckUptime = curUptime;
19612        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19613            doWakeKills = false;
19614        }
19615        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19616            doCpuKills = false;
19617        }
19618        int i = mLruProcesses.size();
19619        while (i > 0) {
19620            i--;
19621            ProcessRecord app = mLruProcesses.get(i);
19622            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19623                long wtime;
19624                synchronized (stats) {
19625                    wtime = stats.getProcessWakeTime(app.info.uid,
19626                            app.pid, curRealtime);
19627                }
19628                long wtimeUsed = wtime - app.lastWakeTime;
19629                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19630                if (DEBUG_POWER) {
19631                    StringBuilder sb = new StringBuilder(128);
19632                    sb.append("Wake for ");
19633                    app.toShortString(sb);
19634                    sb.append(": over ");
19635                    TimeUtils.formatDuration(realtimeSince, sb);
19636                    sb.append(" used ");
19637                    TimeUtils.formatDuration(wtimeUsed, sb);
19638                    sb.append(" (");
19639                    sb.append((wtimeUsed*100)/realtimeSince);
19640                    sb.append("%)");
19641                    Slog.i(TAG_POWER, sb.toString());
19642                    sb.setLength(0);
19643                    sb.append("CPU for ");
19644                    app.toShortString(sb);
19645                    sb.append(": over ");
19646                    TimeUtils.formatDuration(uptimeSince, sb);
19647                    sb.append(" used ");
19648                    TimeUtils.formatDuration(cputimeUsed, sb);
19649                    sb.append(" (");
19650                    sb.append((cputimeUsed*100)/uptimeSince);
19651                    sb.append("%)");
19652                    Slog.i(TAG_POWER, sb.toString());
19653                }
19654                // If a process has held a wake lock for more
19655                // than 50% of the time during this period,
19656                // that sounds bad.  Kill!
19657                if (doWakeKills && realtimeSince > 0
19658                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19659                    synchronized (stats) {
19660                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19661                                realtimeSince, wtimeUsed);
19662                    }
19663                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19664                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19665                } else if (doCpuKills && uptimeSince > 0
19666                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19667                    synchronized (stats) {
19668                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19669                                uptimeSince, cputimeUsed);
19670                    }
19671                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19672                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19673                } else {
19674                    app.lastWakeTime = wtime;
19675                    app.lastCpuTime = app.curCpuTime;
19676                }
19677            }
19678        }
19679    }
19680
19681    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19682            long nowElapsed) {
19683        boolean success = true;
19684
19685        if (app.curRawAdj != app.setRawAdj) {
19686            app.setRawAdj = app.curRawAdj;
19687        }
19688
19689        int changes = 0;
19690
19691        if (app.curAdj != app.setAdj) {
19692            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19693            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19694                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19695                    + app.adjType);
19696            app.setAdj = app.curAdj;
19697        }
19698
19699        if (app.setSchedGroup != app.curSchedGroup) {
19700            app.setSchedGroup = app.curSchedGroup;
19701            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19702                    "Setting sched group of " + app.processName
19703                    + " to " + app.curSchedGroup);
19704            if (app.waitingToKill != null && app.curReceiver == null
19705                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19706                app.kill(app.waitingToKill, true);
19707                success = false;
19708            } else {
19709                int processGroup;
19710                switch (app.curSchedGroup) {
19711                    case ProcessList.SCHED_GROUP_BACKGROUND:
19712                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19713                        break;
19714                    case ProcessList.SCHED_GROUP_TOP_APP:
19715                        processGroup = Process.THREAD_GROUP_TOP_APP;
19716                        break;
19717                    default:
19718                        processGroup = Process.THREAD_GROUP_DEFAULT;
19719                        break;
19720                }
19721                if (true) {
19722                    long oldId = Binder.clearCallingIdentity();
19723                    try {
19724                        Process.setProcessGroup(app.pid, processGroup);
19725                    } catch (Exception e) {
19726                        Slog.w(TAG, "Failed setting process group of " + app.pid
19727                                + " to " + app.curSchedGroup);
19728                        e.printStackTrace();
19729                    } finally {
19730                        Binder.restoreCallingIdentity(oldId);
19731                    }
19732                } else {
19733                    if (app.thread != null) {
19734                        try {
19735                            app.thread.setSchedulingGroup(processGroup);
19736                        } catch (RemoteException e) {
19737                        }
19738                    }
19739                }
19740            }
19741        }
19742        if (app.repForegroundActivities != app.foregroundActivities) {
19743            app.repForegroundActivities = app.foregroundActivities;
19744            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19745        }
19746        if (app.repProcState != app.curProcState) {
19747            app.repProcState = app.curProcState;
19748            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19749            if (app.thread != null) {
19750                try {
19751                    if (false) {
19752                        //RuntimeException h = new RuntimeException("here");
19753                        Slog.i(TAG, "Sending new process state " + app.repProcState
19754                                + " to " + app /*, h*/);
19755                    }
19756                    app.thread.setProcessState(app.repProcState);
19757                } catch (RemoteException e) {
19758                }
19759            }
19760        }
19761        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19762                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19763            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19764                // Experimental code to more aggressively collect pss while
19765                // running test...  the problem is that this tends to collect
19766                // the data right when a process is transitioning between process
19767                // states, which well tend to give noisy data.
19768                long start = SystemClock.uptimeMillis();
19769                long pss = Debug.getPss(app.pid, mTmpLong, null);
19770                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19771                mPendingPssProcesses.remove(app);
19772                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19773                        + " to " + app.curProcState + ": "
19774                        + (SystemClock.uptimeMillis()-start) + "ms");
19775            }
19776            app.lastStateTime = now;
19777            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19778                    mTestPssMode, isSleeping(), now);
19779            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19780                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19781                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19782                    + (app.nextPssTime-now) + ": " + app);
19783        } else {
19784            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19785                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19786                    mTestPssMode)))) {
19787                requestPssLocked(app, app.setProcState);
19788                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19789                        mTestPssMode, isSleeping(), now);
19790            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19791                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19792        }
19793        if (app.setProcState != app.curProcState) {
19794            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19795                    "Proc state change of " + app.processName
19796                            + " to " + app.curProcState);
19797            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19798            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19799            if (setImportant && !curImportant) {
19800                // This app is no longer something we consider important enough to allow to
19801                // use arbitrary amounts of battery power.  Note
19802                // its current wake lock time to later know to kill it if
19803                // it is not behaving well.
19804                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19805                synchronized (stats) {
19806                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19807                            app.pid, nowElapsed);
19808                }
19809                app.lastCpuTime = app.curCpuTime;
19810
19811            }
19812            // Inform UsageStats of important process state change
19813            // Must be called before updating setProcState
19814            maybeUpdateUsageStatsLocked(app, nowElapsed);
19815
19816            app.setProcState = app.curProcState;
19817            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19818                app.notCachedSinceIdle = false;
19819            }
19820            if (!doingAll) {
19821                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19822            } else {
19823                app.procStateChanged = true;
19824            }
19825        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19826                > USAGE_STATS_INTERACTION_INTERVAL) {
19827            // For apps that sit around for a long time in the interactive state, we need
19828            // to report this at least once a day so they don't go idle.
19829            maybeUpdateUsageStatsLocked(app, nowElapsed);
19830        }
19831
19832        if (changes != 0) {
19833            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19834                    "Changes in " + app + ": " + changes);
19835            int i = mPendingProcessChanges.size()-1;
19836            ProcessChangeItem item = null;
19837            while (i >= 0) {
19838                item = mPendingProcessChanges.get(i);
19839                if (item.pid == app.pid) {
19840                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19841                            "Re-using existing item: " + item);
19842                    break;
19843                }
19844                i--;
19845            }
19846            if (i < 0) {
19847                // No existing item in pending changes; need a new one.
19848                final int NA = mAvailProcessChanges.size();
19849                if (NA > 0) {
19850                    item = mAvailProcessChanges.remove(NA-1);
19851                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19852                            "Retrieving available item: " + item);
19853                } else {
19854                    item = new ProcessChangeItem();
19855                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19856                            "Allocating new item: " + item);
19857                }
19858                item.changes = 0;
19859                item.pid = app.pid;
19860                item.uid = app.info.uid;
19861                if (mPendingProcessChanges.size() == 0) {
19862                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19863                            "*** Enqueueing dispatch processes changed!");
19864                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19865                }
19866                mPendingProcessChanges.add(item);
19867            }
19868            item.changes |= changes;
19869            item.processState = app.repProcState;
19870            item.foregroundActivities = app.repForegroundActivities;
19871            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19872                    "Item " + Integer.toHexString(System.identityHashCode(item))
19873                    + " " + app.toShortString() + ": changes=" + item.changes
19874                    + " procState=" + item.processState
19875                    + " foreground=" + item.foregroundActivities
19876                    + " type=" + app.adjType + " source=" + app.adjSource
19877                    + " target=" + app.adjTarget);
19878        }
19879
19880        return success;
19881    }
19882
19883    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19884        final UidRecord.ChangeItem pendingChange;
19885        if (uidRec == null || uidRec.pendingChange == null) {
19886            if (mPendingUidChanges.size() == 0) {
19887                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19888                        "*** Enqueueing dispatch uid changed!");
19889                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19890            }
19891            final int NA = mAvailUidChanges.size();
19892            if (NA > 0) {
19893                pendingChange = mAvailUidChanges.remove(NA-1);
19894                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19895                        "Retrieving available item: " + pendingChange);
19896            } else {
19897                pendingChange = new UidRecord.ChangeItem();
19898                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19899                        "Allocating new item: " + pendingChange);
19900            }
19901            if (uidRec != null) {
19902                uidRec.pendingChange = pendingChange;
19903                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19904                    // If this uid is going away, and we haven't yet reported it is gone,
19905                    // then do so now.
19906                    change = UidRecord.CHANGE_GONE_IDLE;
19907                }
19908            } else if (uid < 0) {
19909                throw new IllegalArgumentException("No UidRecord or uid");
19910            }
19911            pendingChange.uidRecord = uidRec;
19912            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19913            mPendingUidChanges.add(pendingChange);
19914        } else {
19915            pendingChange = uidRec.pendingChange;
19916            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19917                change = UidRecord.CHANGE_GONE_IDLE;
19918            }
19919        }
19920        pendingChange.change = change;
19921        pendingChange.processState = uidRec != null
19922                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19923    }
19924
19925    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19926            String authority) {
19927        if (app == null) return;
19928        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19929            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19930            if (userState == null) return;
19931            final long now = SystemClock.elapsedRealtime();
19932            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19933            if (lastReported == null || lastReported < now - 60 * 1000L) {
19934                mUsageStatsService.reportContentProviderUsage(
19935                        authority, providerPkgName, app.userId);
19936                userState.mProviderLastReportedFg.put(authority, now);
19937            }
19938        }
19939    }
19940
19941    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19942        if (DEBUG_USAGE_STATS) {
19943            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19944                    + "] state changes: old = " + app.setProcState + ", new = "
19945                    + app.curProcState);
19946        }
19947        if (mUsageStatsService == null) {
19948            return;
19949        }
19950        boolean isInteraction;
19951        // To avoid some abuse patterns, we are going to be careful about what we consider
19952        // to be an app interaction.  Being the top activity doesn't count while the display
19953        // is sleeping, nor do short foreground services.
19954        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19955            isInteraction = true;
19956            app.fgInteractionTime = 0;
19957        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19958            if (app.fgInteractionTime == 0) {
19959                app.fgInteractionTime = nowElapsed;
19960                isInteraction = false;
19961            } else {
19962                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19963            }
19964        } else {
19965            isInteraction = app.curProcState
19966                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19967            app.fgInteractionTime = 0;
19968        }
19969        if (isInteraction && (!app.reportedInteraction
19970                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19971            app.interactionEventTime = nowElapsed;
19972            String[] packages = app.getPackageList();
19973            if (packages != null) {
19974                for (int i = 0; i < packages.length; i++) {
19975                    mUsageStatsService.reportEvent(packages[i], app.userId,
19976                            UsageEvents.Event.SYSTEM_INTERACTION);
19977                }
19978            }
19979        }
19980        app.reportedInteraction = isInteraction;
19981        if (!isInteraction) {
19982            app.interactionEventTime = 0;
19983        }
19984    }
19985
19986    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19987        if (proc.thread != null) {
19988            if (proc.baseProcessTracker != null) {
19989                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19990            }
19991        }
19992    }
19993
19994    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19995            ProcessRecord TOP_APP, boolean doingAll, long now) {
19996        if (app.thread == null) {
19997            return false;
19998        }
19999
20000        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20001
20002        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20003    }
20004
20005    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20006            boolean oomAdj) {
20007        if (isForeground != proc.foregroundServices) {
20008            proc.foregroundServices = isForeground;
20009            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20010                    proc.info.uid);
20011            if (isForeground) {
20012                if (curProcs == null) {
20013                    curProcs = new ArrayList<ProcessRecord>();
20014                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20015                }
20016                if (!curProcs.contains(proc)) {
20017                    curProcs.add(proc);
20018                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20019                            proc.info.packageName, proc.info.uid);
20020                }
20021            } else {
20022                if (curProcs != null) {
20023                    if (curProcs.remove(proc)) {
20024                        mBatteryStatsService.noteEvent(
20025                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20026                                proc.info.packageName, proc.info.uid);
20027                        if (curProcs.size() <= 0) {
20028                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20029                        }
20030                    }
20031                }
20032            }
20033            if (oomAdj) {
20034                updateOomAdjLocked();
20035            }
20036        }
20037    }
20038
20039    private final ActivityRecord resumedAppLocked() {
20040        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20041        String pkg;
20042        int uid;
20043        if (act != null) {
20044            pkg = act.packageName;
20045            uid = act.info.applicationInfo.uid;
20046        } else {
20047            pkg = null;
20048            uid = -1;
20049        }
20050        // Has the UID or resumed package name changed?
20051        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20052                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20053            if (mCurResumedPackage != null) {
20054                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20055                        mCurResumedPackage, mCurResumedUid);
20056            }
20057            mCurResumedPackage = pkg;
20058            mCurResumedUid = uid;
20059            if (mCurResumedPackage != null) {
20060                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20061                        mCurResumedPackage, mCurResumedUid);
20062            }
20063        }
20064        return act;
20065    }
20066
20067    final boolean updateOomAdjLocked(ProcessRecord app) {
20068        final ActivityRecord TOP_ACT = resumedAppLocked();
20069        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20070        final boolean wasCached = app.cached;
20071
20072        mAdjSeq++;
20073
20074        // This is the desired cached adjusment we want to tell it to use.
20075        // If our app is currently cached, we know it, and that is it.  Otherwise,
20076        // we don't know it yet, and it needs to now be cached we will then
20077        // need to do a complete oom adj.
20078        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20079                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20080        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20081                SystemClock.uptimeMillis());
20082        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20083            // Changed to/from cached state, so apps after it in the LRU
20084            // list may also be changed.
20085            updateOomAdjLocked();
20086        }
20087        return success;
20088    }
20089
20090    final void updateOomAdjLocked() {
20091        final ActivityRecord TOP_ACT = resumedAppLocked();
20092        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20093        final long now = SystemClock.uptimeMillis();
20094        final long nowElapsed = SystemClock.elapsedRealtime();
20095        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20096        final int N = mLruProcesses.size();
20097
20098        if (false) {
20099            RuntimeException e = new RuntimeException();
20100            e.fillInStackTrace();
20101            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20102        }
20103
20104        // Reset state in all uid records.
20105        for (int i=mActiveUids.size()-1; i>=0; i--) {
20106            final UidRecord uidRec = mActiveUids.valueAt(i);
20107            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20108                    "Starting update of " + uidRec);
20109            uidRec.reset();
20110        }
20111
20112        mStackSupervisor.rankTaskLayersIfNeeded();
20113
20114        mAdjSeq++;
20115        mNewNumServiceProcs = 0;
20116        mNewNumAServiceProcs = 0;
20117
20118        final int emptyProcessLimit;
20119        final int cachedProcessLimit;
20120        if (mProcessLimit <= 0) {
20121            emptyProcessLimit = cachedProcessLimit = 0;
20122        } else if (mProcessLimit == 1) {
20123            emptyProcessLimit = 1;
20124            cachedProcessLimit = 0;
20125        } else {
20126            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20127            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20128        }
20129
20130        // Let's determine how many processes we have running vs.
20131        // how many slots we have for background processes; we may want
20132        // to put multiple processes in a slot of there are enough of
20133        // them.
20134        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20135                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20136        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20137        if (numEmptyProcs > cachedProcessLimit) {
20138            // If there are more empty processes than our limit on cached
20139            // processes, then use the cached process limit for the factor.
20140            // This ensures that the really old empty processes get pushed
20141            // down to the bottom, so if we are running low on memory we will
20142            // have a better chance at keeping around more cached processes
20143            // instead of a gazillion empty processes.
20144            numEmptyProcs = cachedProcessLimit;
20145        }
20146        int emptyFactor = numEmptyProcs/numSlots;
20147        if (emptyFactor < 1) emptyFactor = 1;
20148        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20149        if (cachedFactor < 1) cachedFactor = 1;
20150        int stepCached = 0;
20151        int stepEmpty = 0;
20152        int numCached = 0;
20153        int numEmpty = 0;
20154        int numTrimming = 0;
20155
20156        mNumNonCachedProcs = 0;
20157        mNumCachedHiddenProcs = 0;
20158
20159        // First update the OOM adjustment for each of the
20160        // application processes based on their current state.
20161        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20162        int nextCachedAdj = curCachedAdj+1;
20163        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20164        int nextEmptyAdj = curEmptyAdj+2;
20165        for (int i=N-1; i>=0; i--) {
20166            ProcessRecord app = mLruProcesses.get(i);
20167            if (!app.killedByAm && app.thread != null) {
20168                app.procStateChanged = false;
20169                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20170
20171                // If we haven't yet assigned the final cached adj
20172                // to the process, do that now.
20173                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20174                    switch (app.curProcState) {
20175                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20176                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20177                            // This process is a cached process holding activities...
20178                            // assign it the next cached value for that type, and then
20179                            // step that cached level.
20180                            app.curRawAdj = curCachedAdj;
20181                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20182                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20183                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20184                                    + ")");
20185                            if (curCachedAdj != nextCachedAdj) {
20186                                stepCached++;
20187                                if (stepCached >= cachedFactor) {
20188                                    stepCached = 0;
20189                                    curCachedAdj = nextCachedAdj;
20190                                    nextCachedAdj += 2;
20191                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20192                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20193                                    }
20194                                }
20195                            }
20196                            break;
20197                        default:
20198                            // For everything else, assign next empty cached process
20199                            // level and bump that up.  Note that this means that
20200                            // long-running services that have dropped down to the
20201                            // cached level will be treated as empty (since their process
20202                            // state is still as a service), which is what we want.
20203                            app.curRawAdj = curEmptyAdj;
20204                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20205                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20206                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20207                                    + ")");
20208                            if (curEmptyAdj != nextEmptyAdj) {
20209                                stepEmpty++;
20210                                if (stepEmpty >= emptyFactor) {
20211                                    stepEmpty = 0;
20212                                    curEmptyAdj = nextEmptyAdj;
20213                                    nextEmptyAdj += 2;
20214                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20215                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20216                                    }
20217                                }
20218                            }
20219                            break;
20220                    }
20221                }
20222
20223                applyOomAdjLocked(app, true, now, nowElapsed);
20224
20225                // Count the number of process types.
20226                switch (app.curProcState) {
20227                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20228                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20229                        mNumCachedHiddenProcs++;
20230                        numCached++;
20231                        if (numCached > cachedProcessLimit) {
20232                            app.kill("cached #" + numCached, true);
20233                        }
20234                        break;
20235                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20236                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20237                                && app.lastActivityTime < oldTime) {
20238                            app.kill("empty for "
20239                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20240                                    / 1000) + "s", true);
20241                        } else {
20242                            numEmpty++;
20243                            if (numEmpty > emptyProcessLimit) {
20244                                app.kill("empty #" + numEmpty, true);
20245                            }
20246                        }
20247                        break;
20248                    default:
20249                        mNumNonCachedProcs++;
20250                        break;
20251                }
20252
20253                if (app.isolated && app.services.size() <= 0) {
20254                    // If this is an isolated process, and there are no
20255                    // services running in it, then the process is no longer
20256                    // needed.  We agressively kill these because we can by
20257                    // definition not re-use the same process again, and it is
20258                    // good to avoid having whatever code was running in them
20259                    // left sitting around after no longer needed.
20260                    app.kill("isolated not needed", true);
20261                } else {
20262                    // Keeping this process, update its uid.
20263                    final UidRecord uidRec = app.uidRecord;
20264                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20265                        uidRec.curProcState = app.curProcState;
20266                    }
20267                }
20268
20269                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20270                        && !app.killedByAm) {
20271                    numTrimming++;
20272                }
20273            }
20274        }
20275
20276        mNumServiceProcs = mNewNumServiceProcs;
20277
20278        // Now determine the memory trimming level of background processes.
20279        // Unfortunately we need to start at the back of the list to do this
20280        // properly.  We only do this if the number of background apps we
20281        // are managing to keep around is less than half the maximum we desire;
20282        // if we are keeping a good number around, we'll let them use whatever
20283        // memory they want.
20284        final int numCachedAndEmpty = numCached + numEmpty;
20285        int memFactor;
20286        if (numCached <= ProcessList.TRIM_CACHED_APPS
20287                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20288            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20289                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20290            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20291                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20292            } else {
20293                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20294            }
20295        } else {
20296            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20297        }
20298        // We always allow the memory level to go up (better).  We only allow it to go
20299        // down if we are in a state where that is allowed, *and* the total number of processes
20300        // has gone down since last time.
20301        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20302                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20303                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20304        if (memFactor > mLastMemoryLevel) {
20305            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20306                memFactor = mLastMemoryLevel;
20307                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20308            }
20309        }
20310        if (memFactor != mLastMemoryLevel) {
20311            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20312        }
20313        mLastMemoryLevel = memFactor;
20314        mLastNumProcesses = mLruProcesses.size();
20315        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20316        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20317        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20318            if (mLowRamStartTime == 0) {
20319                mLowRamStartTime = now;
20320            }
20321            int step = 0;
20322            int fgTrimLevel;
20323            switch (memFactor) {
20324                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20325                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20326                    break;
20327                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20328                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20329                    break;
20330                default:
20331                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20332                    break;
20333            }
20334            int factor = numTrimming/3;
20335            int minFactor = 2;
20336            if (mHomeProcess != null) minFactor++;
20337            if (mPreviousProcess != null) minFactor++;
20338            if (factor < minFactor) factor = minFactor;
20339            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20340            for (int i=N-1; i>=0; i--) {
20341                ProcessRecord app = mLruProcesses.get(i);
20342                if (allChanged || app.procStateChanged) {
20343                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20344                    app.procStateChanged = false;
20345                }
20346                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20347                        && !app.killedByAm) {
20348                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20349                        try {
20350                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20351                                    "Trimming memory of " + app.processName + " to " + curLevel);
20352                            app.thread.scheduleTrimMemory(curLevel);
20353                        } catch (RemoteException e) {
20354                        }
20355                        if (false) {
20356                            // For now we won't do this; our memory trimming seems
20357                            // to be good enough at this point that destroying
20358                            // activities causes more harm than good.
20359                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20360                                    && app != mHomeProcess && app != mPreviousProcess) {
20361                                // Need to do this on its own message because the stack may not
20362                                // be in a consistent state at this point.
20363                                // For these apps we will also finish their activities
20364                                // to help them free memory.
20365                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20366                            }
20367                        }
20368                    }
20369                    app.trimMemoryLevel = curLevel;
20370                    step++;
20371                    if (step >= factor) {
20372                        step = 0;
20373                        switch (curLevel) {
20374                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20375                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20376                                break;
20377                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20378                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20379                                break;
20380                        }
20381                    }
20382                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20383                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20384                            && app.thread != null) {
20385                        try {
20386                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20387                                    "Trimming memory of heavy-weight " + app.processName
20388                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20389                            app.thread.scheduleTrimMemory(
20390                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20391                        } catch (RemoteException e) {
20392                        }
20393                    }
20394                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20395                } else {
20396                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20397                            || app.systemNoUi) && app.pendingUiClean) {
20398                        // If this application is now in the background and it
20399                        // had done UI, then give it the special trim level to
20400                        // have it free UI resources.
20401                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20402                        if (app.trimMemoryLevel < level && app.thread != null) {
20403                            try {
20404                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20405                                        "Trimming memory of bg-ui " + app.processName
20406                                        + " to " + level);
20407                                app.thread.scheduleTrimMemory(level);
20408                            } catch (RemoteException e) {
20409                            }
20410                        }
20411                        app.pendingUiClean = false;
20412                    }
20413                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20414                        try {
20415                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20416                                    "Trimming memory of fg " + app.processName
20417                                    + " to " + fgTrimLevel);
20418                            app.thread.scheduleTrimMemory(fgTrimLevel);
20419                        } catch (RemoteException e) {
20420                        }
20421                    }
20422                    app.trimMemoryLevel = fgTrimLevel;
20423                }
20424            }
20425        } else {
20426            if (mLowRamStartTime != 0) {
20427                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20428                mLowRamStartTime = 0;
20429            }
20430            for (int i=N-1; i>=0; i--) {
20431                ProcessRecord app = mLruProcesses.get(i);
20432                if (allChanged || app.procStateChanged) {
20433                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20434                    app.procStateChanged = false;
20435                }
20436                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20437                        || app.systemNoUi) && app.pendingUiClean) {
20438                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20439                            && app.thread != null) {
20440                        try {
20441                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20442                                    "Trimming memory of ui hidden " + app.processName
20443                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20444                            app.thread.scheduleTrimMemory(
20445                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20446                        } catch (RemoteException e) {
20447                        }
20448                    }
20449                    app.pendingUiClean = false;
20450                }
20451                app.trimMemoryLevel = 0;
20452            }
20453        }
20454
20455        if (mAlwaysFinishActivities) {
20456            // Need to do this on its own message because the stack may not
20457            // be in a consistent state at this point.
20458            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20459        }
20460
20461        if (allChanged) {
20462            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20463        }
20464
20465        // Update from any uid changes.
20466        for (int i=mActiveUids.size()-1; i>=0; i--) {
20467            final UidRecord uidRec = mActiveUids.valueAt(i);
20468            int uidChange = UidRecord.CHANGE_PROCSTATE;
20469            if (uidRec.setProcState != uidRec.curProcState) {
20470                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20471                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20472                        + " to " + uidRec.curProcState);
20473                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20474                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20475                        uidRec.lastBackgroundTime = nowElapsed;
20476                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20477                            // Note: the background settle time is in elapsed realtime, while
20478                            // the handler time base is uptime.  All this means is that we may
20479                            // stop background uids later than we had intended, but that only
20480                            // happens because the device was sleeping so we are okay anyway.
20481                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20482                        }
20483                    }
20484                } else {
20485                    if (uidRec.idle) {
20486                        uidChange = UidRecord.CHANGE_ACTIVE;
20487                        uidRec.idle = false;
20488                    }
20489                    uidRec.lastBackgroundTime = 0;
20490                }
20491                uidRec.setProcState = uidRec.curProcState;
20492                enqueueUidChangeLocked(uidRec, -1, uidChange);
20493                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20494            }
20495        }
20496
20497        if (mProcessStats.shouldWriteNowLocked(now)) {
20498            mHandler.post(new Runnable() {
20499                @Override public void run() {
20500                    synchronized (ActivityManagerService.this) {
20501                        mProcessStats.writeStateAsyncLocked();
20502                    }
20503                }
20504            });
20505        }
20506
20507        if (DEBUG_OOM_ADJ) {
20508            final long duration = SystemClock.uptimeMillis() - now;
20509            if (false) {
20510                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20511                        new RuntimeException("here").fillInStackTrace());
20512            } else {
20513                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20514            }
20515        }
20516    }
20517
20518    final void idleUids() {
20519        synchronized (this) {
20520            final long nowElapsed = SystemClock.elapsedRealtime();
20521            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20522            long nextTime = 0;
20523            for (int i=mActiveUids.size()-1; i>=0; i--) {
20524                final UidRecord uidRec = mActiveUids.valueAt(i);
20525                final long bgTime = uidRec.lastBackgroundTime;
20526                if (bgTime > 0 && !uidRec.idle) {
20527                    if (bgTime <= maxBgTime) {
20528                        uidRec.idle = true;
20529                        doStopUidLocked(uidRec.uid, uidRec);
20530                    } else {
20531                        if (nextTime == 0 || nextTime > bgTime) {
20532                            nextTime = bgTime;
20533                        }
20534                    }
20535                }
20536            }
20537            if (nextTime > 0) {
20538                mHandler.removeMessages(IDLE_UIDS_MSG);
20539                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20540                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20541            }
20542        }
20543    }
20544
20545    final void runInBackgroundDisabled(int uid) {
20546        synchronized (this) {
20547            UidRecord uidRec = mActiveUids.get(uid);
20548            if (uidRec != null) {
20549                // This uid is actually running...  should it be considered background now?
20550                if (uidRec.idle) {
20551                    doStopUidLocked(uidRec.uid, uidRec);
20552                }
20553            } else {
20554                // This uid isn't actually running...  still send a report about it being "stopped".
20555                doStopUidLocked(uid, null);
20556            }
20557        }
20558    }
20559
20560    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20561        mServices.stopInBackgroundLocked(uid);
20562        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20563    }
20564
20565    final void trimApplications() {
20566        synchronized (this) {
20567            int i;
20568
20569            // First remove any unused application processes whose package
20570            // has been removed.
20571            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20572                final ProcessRecord app = mRemovedProcesses.get(i);
20573                if (app.activities.size() == 0
20574                        && app.curReceiver == null && app.services.size() == 0) {
20575                    Slog.i(
20576                        TAG, "Exiting empty application process "
20577                        + app.toShortString() + " ("
20578                        + (app.thread != null ? app.thread.asBinder() : null)
20579                        + ")\n");
20580                    if (app.pid > 0 && app.pid != MY_PID) {
20581                        app.kill("empty", false);
20582                    } else {
20583                        try {
20584                            app.thread.scheduleExit();
20585                        } catch (Exception e) {
20586                            // Ignore exceptions.
20587                        }
20588                    }
20589                    cleanUpApplicationRecordLocked(app, false, true, -1);
20590                    mRemovedProcesses.remove(i);
20591
20592                    if (app.persistent) {
20593                        addAppLocked(app.info, false, null /* ABI override */);
20594                    }
20595                }
20596            }
20597
20598            // Now update the oom adj for all processes.
20599            updateOomAdjLocked();
20600        }
20601    }
20602
20603    /** This method sends the specified signal to each of the persistent apps */
20604    public void signalPersistentProcesses(int sig) throws RemoteException {
20605        if (sig != Process.SIGNAL_USR1) {
20606            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20607        }
20608
20609        synchronized (this) {
20610            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20611                    != PackageManager.PERMISSION_GRANTED) {
20612                throw new SecurityException("Requires permission "
20613                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20614            }
20615
20616            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20617                ProcessRecord r = mLruProcesses.get(i);
20618                if (r.thread != null && r.persistent) {
20619                    Process.sendSignal(r.pid, sig);
20620                }
20621            }
20622        }
20623    }
20624
20625    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20626        if (proc == null || proc == mProfileProc) {
20627            proc = mProfileProc;
20628            profileType = mProfileType;
20629            clearProfilerLocked();
20630        }
20631        if (proc == null) {
20632            return;
20633        }
20634        try {
20635            proc.thread.profilerControl(false, null, profileType);
20636        } catch (RemoteException e) {
20637            throw new IllegalStateException("Process disappeared");
20638        }
20639    }
20640
20641    private void clearProfilerLocked() {
20642        if (mProfileFd != null) {
20643            try {
20644                mProfileFd.close();
20645            } catch (IOException e) {
20646            }
20647        }
20648        mProfileApp = null;
20649        mProfileProc = null;
20650        mProfileFile = null;
20651        mProfileType = 0;
20652        mAutoStopProfiler = false;
20653        mSamplingInterval = 0;
20654    }
20655
20656    public boolean profileControl(String process, int userId, boolean start,
20657            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20658
20659        try {
20660            synchronized (this) {
20661                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20662                // its own permission.
20663                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20664                        != PackageManager.PERMISSION_GRANTED) {
20665                    throw new SecurityException("Requires permission "
20666                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20667                }
20668
20669                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20670                    throw new IllegalArgumentException("null profile info or fd");
20671                }
20672
20673                ProcessRecord proc = null;
20674                if (process != null) {
20675                    proc = findProcessLocked(process, userId, "profileControl");
20676                }
20677
20678                if (start && (proc == null || proc.thread == null)) {
20679                    throw new IllegalArgumentException("Unknown process: " + process);
20680                }
20681
20682                if (start) {
20683                    stopProfilerLocked(null, 0);
20684                    setProfileApp(proc.info, proc.processName, profilerInfo);
20685                    mProfileProc = proc;
20686                    mProfileType = profileType;
20687                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20688                    try {
20689                        fd = fd.dup();
20690                    } catch (IOException e) {
20691                        fd = null;
20692                    }
20693                    profilerInfo.profileFd = fd;
20694                    proc.thread.profilerControl(start, profilerInfo, profileType);
20695                    fd = null;
20696                    mProfileFd = null;
20697                } else {
20698                    stopProfilerLocked(proc, profileType);
20699                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20700                        try {
20701                            profilerInfo.profileFd.close();
20702                        } catch (IOException e) {
20703                        }
20704                    }
20705                }
20706
20707                return true;
20708            }
20709        } catch (RemoteException e) {
20710            throw new IllegalStateException("Process disappeared");
20711        } finally {
20712            if (profilerInfo != null && profilerInfo.profileFd != null) {
20713                try {
20714                    profilerInfo.profileFd.close();
20715                } catch (IOException e) {
20716                }
20717            }
20718        }
20719    }
20720
20721    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20722        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20723                userId, true, ALLOW_FULL_ONLY, callName, null);
20724        ProcessRecord proc = null;
20725        try {
20726            int pid = Integer.parseInt(process);
20727            synchronized (mPidsSelfLocked) {
20728                proc = mPidsSelfLocked.get(pid);
20729            }
20730        } catch (NumberFormatException e) {
20731        }
20732
20733        if (proc == null) {
20734            ArrayMap<String, SparseArray<ProcessRecord>> all
20735                    = mProcessNames.getMap();
20736            SparseArray<ProcessRecord> procs = all.get(process);
20737            if (procs != null && procs.size() > 0) {
20738                proc = procs.valueAt(0);
20739                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20740                    for (int i=1; i<procs.size(); i++) {
20741                        ProcessRecord thisProc = procs.valueAt(i);
20742                        if (thisProc.userId == userId) {
20743                            proc = thisProc;
20744                            break;
20745                        }
20746                    }
20747                }
20748            }
20749        }
20750
20751        return proc;
20752    }
20753
20754    public boolean dumpHeap(String process, int userId, boolean managed,
20755            String path, ParcelFileDescriptor fd) throws RemoteException {
20756
20757        try {
20758            synchronized (this) {
20759                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20760                // its own permission (same as profileControl).
20761                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20762                        != PackageManager.PERMISSION_GRANTED) {
20763                    throw new SecurityException("Requires permission "
20764                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20765                }
20766
20767                if (fd == null) {
20768                    throw new IllegalArgumentException("null fd");
20769                }
20770
20771                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20772                if (proc == null || proc.thread == null) {
20773                    throw new IllegalArgumentException("Unknown process: " + process);
20774                }
20775
20776                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20777                if (!isDebuggable) {
20778                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20779                        throw new SecurityException("Process not debuggable: " + proc);
20780                    }
20781                }
20782
20783                proc.thread.dumpHeap(managed, path, fd);
20784                fd = null;
20785                return true;
20786            }
20787        } catch (RemoteException e) {
20788            throw new IllegalStateException("Process disappeared");
20789        } finally {
20790            if (fd != null) {
20791                try {
20792                    fd.close();
20793                } catch (IOException e) {
20794                }
20795            }
20796        }
20797    }
20798
20799    @Override
20800    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20801            String reportPackage) {
20802        if (processName != null) {
20803            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20804                    "setDumpHeapDebugLimit()");
20805        } else {
20806            synchronized (mPidsSelfLocked) {
20807                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20808                if (proc == null) {
20809                    throw new SecurityException("No process found for calling pid "
20810                            + Binder.getCallingPid());
20811                }
20812                if (!Build.IS_DEBUGGABLE
20813                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20814                    throw new SecurityException("Not running a debuggable build");
20815                }
20816                processName = proc.processName;
20817                uid = proc.uid;
20818                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20819                    throw new SecurityException("Package " + reportPackage + " is not running in "
20820                            + proc);
20821                }
20822            }
20823        }
20824        synchronized (this) {
20825            if (maxMemSize > 0) {
20826                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20827            } else {
20828                if (uid != 0) {
20829                    mMemWatchProcesses.remove(processName, uid);
20830                } else {
20831                    mMemWatchProcesses.getMap().remove(processName);
20832                }
20833            }
20834        }
20835    }
20836
20837    @Override
20838    public void dumpHeapFinished(String path) {
20839        synchronized (this) {
20840            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20841                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20842                        + " does not match last pid " + mMemWatchDumpPid);
20843                return;
20844            }
20845            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20846                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20847                        + " does not match last path " + mMemWatchDumpFile);
20848                return;
20849            }
20850            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20851            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20852        }
20853    }
20854
20855    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20856    public void monitor() {
20857        synchronized (this) { }
20858    }
20859
20860    void onCoreSettingsChange(Bundle settings) {
20861        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20862            ProcessRecord processRecord = mLruProcesses.get(i);
20863            try {
20864                if (processRecord.thread != null) {
20865                    processRecord.thread.setCoreSettings(settings);
20866                }
20867            } catch (RemoteException re) {
20868                /* ignore */
20869            }
20870        }
20871    }
20872
20873    // Multi-user methods
20874
20875    /**
20876     * Start user, if its not already running, but don't bring it to foreground.
20877     */
20878    @Override
20879    public boolean startUserInBackground(final int userId) {
20880        return mUserController.startUser(userId, /* foreground */ false);
20881    }
20882
20883    @Override
20884    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20885        return mUserController.unlockUser(userId, token, secret, listener);
20886    }
20887
20888    @Override
20889    public boolean switchUser(final int targetUserId) {
20890        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20891        UserInfo currentUserInfo;
20892        UserInfo targetUserInfo;
20893        synchronized (this) {
20894            int currentUserId = mUserController.getCurrentUserIdLocked();
20895            currentUserInfo = mUserController.getUserInfo(currentUserId);
20896            targetUserInfo = mUserController.getUserInfo(targetUserId);
20897            if (targetUserInfo == null) {
20898                Slog.w(TAG, "No user info for user #" + targetUserId);
20899                return false;
20900            }
20901            if (!targetUserInfo.supportsSwitchTo()) {
20902                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20903                return false;
20904            }
20905            if (targetUserInfo.isManagedProfile()) {
20906                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20907                return false;
20908            }
20909            mUserController.setTargetUserIdLocked(targetUserId);
20910        }
20911        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20912        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20913        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20914        return true;
20915    }
20916
20917    void scheduleStartProfilesLocked() {
20918        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20919            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20920                    DateUtils.SECOND_IN_MILLIS);
20921        }
20922    }
20923
20924    @Override
20925    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20926        return mUserController.stopUser(userId, force, callback);
20927    }
20928
20929    @Override
20930    public UserInfo getCurrentUser() {
20931        return mUserController.getCurrentUser();
20932    }
20933
20934    @Override
20935    public boolean isUserRunning(int userId, int flags) {
20936        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20937                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20938            String msg = "Permission Denial: isUserRunning() from pid="
20939                    + Binder.getCallingPid()
20940                    + ", uid=" + Binder.getCallingUid()
20941                    + " requires " + INTERACT_ACROSS_USERS;
20942            Slog.w(TAG, msg);
20943            throw new SecurityException(msg);
20944        }
20945        synchronized (this) {
20946            return mUserController.isUserRunningLocked(userId, flags);
20947        }
20948    }
20949
20950    @Override
20951    public int[] getRunningUserIds() {
20952        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20953                != PackageManager.PERMISSION_GRANTED) {
20954            String msg = "Permission Denial: isUserRunning() from pid="
20955                    + Binder.getCallingPid()
20956                    + ", uid=" + Binder.getCallingUid()
20957                    + " requires " + INTERACT_ACROSS_USERS;
20958            Slog.w(TAG, msg);
20959            throw new SecurityException(msg);
20960        }
20961        synchronized (this) {
20962            return mUserController.getStartedUserArrayLocked();
20963        }
20964    }
20965
20966    @Override
20967    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20968        mUserController.registerUserSwitchObserver(observer);
20969    }
20970
20971    @Override
20972    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20973        mUserController.unregisterUserSwitchObserver(observer);
20974    }
20975
20976    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20977        if (info == null) return null;
20978        ApplicationInfo newInfo = new ApplicationInfo(info);
20979        newInfo.initForUser(userId);
20980        return newInfo;
20981    }
20982
20983    public boolean isUserStopped(int userId) {
20984        synchronized (this) {
20985            return mUserController.getStartedUserStateLocked(userId) == null;
20986        }
20987    }
20988
20989    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20990        if (aInfo == null
20991                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20992            return aInfo;
20993        }
20994
20995        ActivityInfo info = new ActivityInfo(aInfo);
20996        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20997        return info;
20998    }
20999
21000    private boolean processSanityChecksLocked(ProcessRecord process) {
21001        if (process == null || process.thread == null) {
21002            return false;
21003        }
21004
21005        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21006        if (!isDebuggable) {
21007            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21008                return false;
21009            }
21010        }
21011
21012        return true;
21013    }
21014
21015    public boolean startBinderTracking() throws RemoteException {
21016        synchronized (this) {
21017            mBinderTransactionTrackingEnabled = true;
21018            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21019            // permission (same as profileControl).
21020            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21021                    != PackageManager.PERMISSION_GRANTED) {
21022                throw new SecurityException("Requires permission "
21023                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21024            }
21025
21026            for (int i = 0; i < mLruProcesses.size(); i++) {
21027                ProcessRecord process = mLruProcesses.get(i);
21028                if (!processSanityChecksLocked(process)) {
21029                    continue;
21030                }
21031                try {
21032                    process.thread.startBinderTracking();
21033                } catch (RemoteException e) {
21034                    Log.v(TAG, "Process disappared");
21035                }
21036            }
21037            return true;
21038        }
21039    }
21040
21041    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21042        try {
21043            synchronized (this) {
21044                mBinderTransactionTrackingEnabled = false;
21045                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21046                // permission (same as profileControl).
21047                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21048                        != PackageManager.PERMISSION_GRANTED) {
21049                    throw new SecurityException("Requires permission "
21050                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21051                }
21052
21053                if (fd == null) {
21054                    throw new IllegalArgumentException("null fd");
21055                }
21056
21057                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21058                pw.println("Binder transaction traces for all processes.\n");
21059                for (ProcessRecord process : mLruProcesses) {
21060                    if (!processSanityChecksLocked(process)) {
21061                        continue;
21062                    }
21063
21064                    pw.println("Traces for process: " + process.processName);
21065                    pw.flush();
21066                    try {
21067                        TransferPipe tp = new TransferPipe();
21068                        try {
21069                            process.thread.stopBinderTrackingAndDump(
21070                                    tp.getWriteFd().getFileDescriptor());
21071                            tp.go(fd.getFileDescriptor());
21072                        } finally {
21073                            tp.kill();
21074                        }
21075                    } catch (IOException e) {
21076                        pw.println("Failure while dumping IPC traces from " + process +
21077                                ".  Exception: " + e);
21078                        pw.flush();
21079                    } catch (RemoteException e) {
21080                        pw.println("Got a RemoteException while dumping IPC traces from " +
21081                                process + ".  Exception: " + e);
21082                        pw.flush();
21083                    }
21084                }
21085                fd = null;
21086                return true;
21087            }
21088        } finally {
21089            if (fd != null) {
21090                try {
21091                    fd.close();
21092                } catch (IOException e) {
21093                }
21094            }
21095        }
21096    }
21097
21098    private final class LocalService extends ActivityManagerInternal {
21099        @Override
21100        public void onWakefulnessChanged(int wakefulness) {
21101            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21102        }
21103
21104        @Override
21105        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21106                String processName, String abiOverride, int uid, Runnable crashHandler) {
21107            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21108                    processName, abiOverride, uid, crashHandler);
21109        }
21110
21111        @Override
21112        public SleepToken acquireSleepToken(String tag) {
21113            Preconditions.checkNotNull(tag);
21114
21115            synchronized (ActivityManagerService.this) {
21116                SleepTokenImpl token = new SleepTokenImpl(tag);
21117                mSleepTokens.add(token);
21118                updateSleepIfNeededLocked();
21119                applyVrModeIfNeededLocked(mFocusedActivity, false);
21120                return token;
21121            }
21122        }
21123
21124        @Override
21125        public ComponentName getHomeActivityForUser(int userId) {
21126            synchronized (ActivityManagerService.this) {
21127                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21128                return homeActivity == null ? null : homeActivity.realActivity;
21129            }
21130        }
21131
21132        @Override
21133        public void onUserRemoved(int userId) {
21134            synchronized (ActivityManagerService.this) {
21135                ActivityManagerService.this.onUserStoppedLocked(userId);
21136            }
21137        }
21138
21139        @Override
21140        public void onLocalVoiceInteractionStarted(IBinder activity,
21141                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21142            synchronized (ActivityManagerService.this) {
21143                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21144                        voiceSession, voiceInteractor);
21145            }
21146        }
21147
21148        @Override
21149        public void notifyStartingWindowDrawn() {
21150            synchronized (ActivityManagerService.this) {
21151                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21152            }
21153        }
21154
21155        @Override
21156        public void notifyAppTransitionStarting(int reason) {
21157            synchronized (ActivityManagerService.this) {
21158                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21159            }
21160        }
21161
21162        @Override
21163        public void notifyAppTransitionFinished() {
21164            synchronized (ActivityManagerService.this) {
21165                mStackSupervisor.notifyAppTransitionDone();
21166            }
21167        }
21168
21169        @Override
21170        public void notifyAppTransitionCancelled() {
21171            synchronized (ActivityManagerService.this) {
21172                mStackSupervisor.notifyAppTransitionDone();
21173            }
21174        }
21175
21176        @Override
21177        public List<IBinder> getTopVisibleActivities() {
21178            synchronized (ActivityManagerService.this) {
21179                return mStackSupervisor.getTopVisibleActivities();
21180            }
21181        }
21182
21183        @Override
21184        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21185            synchronized (ActivityManagerService.this) {
21186                mStackSupervisor.setDockedStackMinimized(minimized);
21187            }
21188        }
21189
21190        @Override
21191        public void killForegroundAppsForUser(int userHandle) {
21192            synchronized (ActivityManagerService.this) {
21193                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21194                final int NP = mProcessNames.getMap().size();
21195                for (int ip = 0; ip < NP; ip++) {
21196                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21197                    final int NA = apps.size();
21198                    for (int ia = 0; ia < NA; ia++) {
21199                        final ProcessRecord app = apps.valueAt(ia);
21200                        if (app.persistent) {
21201                            // We don't kill persistent processes.
21202                            continue;
21203                        }
21204                        if (app.removed) {
21205                            procs.add(app);
21206                        } else if (app.userId == userHandle && app.foregroundActivities) {
21207                            app.removed = true;
21208                            procs.add(app);
21209                        }
21210                    }
21211                }
21212
21213                final int N = procs.size();
21214                for (int i = 0; i < N; i++) {
21215                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21216                }
21217            }
21218        }
21219    }
21220
21221    private final class SleepTokenImpl extends SleepToken {
21222        private final String mTag;
21223        private final long mAcquireTime;
21224
21225        public SleepTokenImpl(String tag) {
21226            mTag = tag;
21227            mAcquireTime = SystemClock.uptimeMillis();
21228        }
21229
21230        @Override
21231        public void release() {
21232            synchronized (ActivityManagerService.this) {
21233                if (mSleepTokens.remove(this)) {
21234                    updateSleepIfNeededLocked();
21235                }
21236            }
21237        }
21238
21239        @Override
21240        public String toString() {
21241            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21242        }
21243    }
21244
21245    /**
21246     * An implementation of IAppTask, that allows an app to manage its own tasks via
21247     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21248     * only the process that calls getAppTasks() can call the AppTask methods.
21249     */
21250    class AppTaskImpl extends IAppTask.Stub {
21251        private int mTaskId;
21252        private int mCallingUid;
21253
21254        public AppTaskImpl(int taskId, int callingUid) {
21255            mTaskId = taskId;
21256            mCallingUid = callingUid;
21257        }
21258
21259        private void checkCaller() {
21260            if (mCallingUid != Binder.getCallingUid()) {
21261                throw new SecurityException("Caller " + mCallingUid
21262                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21263            }
21264        }
21265
21266        @Override
21267        public void finishAndRemoveTask() {
21268            checkCaller();
21269
21270            synchronized (ActivityManagerService.this) {
21271                long origId = Binder.clearCallingIdentity();
21272                try {
21273                    // We remove the task from recents to preserve backwards
21274                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21275                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21276                    }
21277                } finally {
21278                    Binder.restoreCallingIdentity(origId);
21279                }
21280            }
21281        }
21282
21283        @Override
21284        public ActivityManager.RecentTaskInfo getTaskInfo() {
21285            checkCaller();
21286
21287            synchronized (ActivityManagerService.this) {
21288                long origId = Binder.clearCallingIdentity();
21289                try {
21290                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21291                    if (tr == null) {
21292                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21293                    }
21294                    return createRecentTaskInfoFromTaskRecord(tr);
21295                } finally {
21296                    Binder.restoreCallingIdentity(origId);
21297                }
21298            }
21299        }
21300
21301        @Override
21302        public void moveToFront() {
21303            checkCaller();
21304            // Will bring task to front if it already has a root activity.
21305            final long origId = Binder.clearCallingIdentity();
21306            try {
21307                synchronized (this) {
21308                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21309                }
21310            } finally {
21311                Binder.restoreCallingIdentity(origId);
21312            }
21313        }
21314
21315        @Override
21316        public int startActivity(IBinder whoThread, String callingPackage,
21317                Intent intent, String resolvedType, Bundle bOptions) {
21318            checkCaller();
21319
21320            int callingUser = UserHandle.getCallingUserId();
21321            TaskRecord tr;
21322            IApplicationThread appThread;
21323            synchronized (ActivityManagerService.this) {
21324                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21325                if (tr == null) {
21326                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21327                }
21328                appThread = ApplicationThreadNative.asInterface(whoThread);
21329                if (appThread == null) {
21330                    throw new IllegalArgumentException("Bad app thread " + appThread);
21331                }
21332            }
21333            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21334                    resolvedType, null, null, null, null, 0, 0, null, null,
21335                    null, bOptions, false, callingUser, null, tr);
21336        }
21337
21338        @Override
21339        public void setExcludeFromRecents(boolean exclude) {
21340            checkCaller();
21341
21342            synchronized (ActivityManagerService.this) {
21343                long origId = Binder.clearCallingIdentity();
21344                try {
21345                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21346                    if (tr == null) {
21347                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21348                    }
21349                    Intent intent = tr.getBaseIntent();
21350                    if (exclude) {
21351                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21352                    } else {
21353                        intent.setFlags(intent.getFlags()
21354                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21355                    }
21356                } finally {
21357                    Binder.restoreCallingIdentity(origId);
21358                }
21359            }
21360        }
21361    }
21362
21363    /**
21364     * Kill processes for the user with id userId and that depend on the package named packageName
21365     */
21366    @Override
21367    public void killPackageDependents(String packageName, int userId) {
21368        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21369        if (packageName == null) {
21370            throw new NullPointerException(
21371                    "Cannot kill the dependents of a package without its name.");
21372        }
21373
21374        long callingId = Binder.clearCallingIdentity();
21375        IPackageManager pm = AppGlobals.getPackageManager();
21376        int pkgUid = -1;
21377        try {
21378            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21379        } catch (RemoteException e) {
21380        }
21381        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21382            throw new IllegalArgumentException(
21383                    "Cannot kill dependents of non-existing package " + packageName);
21384        }
21385        try {
21386            synchronized(this) {
21387                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21388                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21389                        "dep: " + packageName);
21390            }
21391        } finally {
21392            Binder.restoreCallingIdentity(callingId);
21393        }
21394    }
21395}
21396