ActivityManagerService.java revision 2675616719734ce069db47bd8b563f775351dd38
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            if (intent == null) {
7061                // Weird case: someone has given us their own custom IIntentSender, and now
7062                // they have someone else trying to send to it but of course this isn't
7063                // really a PendingIntent, so there is no base Intent, and the caller isn't
7064                // supplying an Intent... but we never want to dispatch a null Intent to
7065                // a receiver, so um...  let's make something up.
7066                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7067                intent = new Intent(Intent.ACTION_MAIN);
7068            }
7069            try {
7070                target.send(code, intent, resolvedType, null, requiredPermission, options);
7071            } catch (RemoteException e) {
7072            }
7073            // Platform code can rely on getting a result back when the send is done, but if
7074            // this intent sender is from outside of the system we can't rely on it doing that.
7075            // So instead we don't give it the result receiver, and instead just directly
7076            // report the finish immediately.
7077            if (finishedReceiver != null) {
7078                try {
7079                    finishedReceiver.performReceive(intent, 0,
7080                            null, null, false, false, UserHandle.getCallingUserId());
7081                } catch (RemoteException e) {
7082                }
7083            }
7084            return 0;
7085        }
7086    }
7087
7088    @Override
7089    public void cancelIntentSender(IIntentSender sender) {
7090        if (!(sender instanceof PendingIntentRecord)) {
7091            return;
7092        }
7093        synchronized(this) {
7094            PendingIntentRecord rec = (PendingIntentRecord)sender;
7095            try {
7096                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7097                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7098                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7099                    String msg = "Permission Denial: cancelIntentSender() from pid="
7100                        + Binder.getCallingPid()
7101                        + ", uid=" + Binder.getCallingUid()
7102                        + " is not allowed to cancel packges "
7103                        + rec.key.packageName;
7104                    Slog.w(TAG, msg);
7105                    throw new SecurityException(msg);
7106                }
7107            } catch (RemoteException e) {
7108                throw new SecurityException(e);
7109            }
7110            cancelIntentSenderLocked(rec, true);
7111        }
7112    }
7113
7114    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7115        rec.canceled = true;
7116        mIntentSenderRecords.remove(rec.key);
7117        if (cleanActivity && rec.key.activity != null) {
7118            rec.key.activity.pendingResults.remove(rec.ref);
7119        }
7120    }
7121
7122    @Override
7123    public String getPackageForIntentSender(IIntentSender pendingResult) {
7124        if (!(pendingResult instanceof PendingIntentRecord)) {
7125            return null;
7126        }
7127        try {
7128            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7129            return res.key.packageName;
7130        } catch (ClassCastException e) {
7131        }
7132        return null;
7133    }
7134
7135    @Override
7136    public int getUidForIntentSender(IIntentSender sender) {
7137        if (sender instanceof PendingIntentRecord) {
7138            try {
7139                PendingIntentRecord res = (PendingIntentRecord)sender;
7140                return res.uid;
7141            } catch (ClassCastException e) {
7142            }
7143        }
7144        return -1;
7145    }
7146
7147    @Override
7148    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7149        if (!(pendingResult instanceof PendingIntentRecord)) {
7150            return false;
7151        }
7152        try {
7153            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7154            if (res.key.allIntents == null) {
7155                return false;
7156            }
7157            for (int i=0; i<res.key.allIntents.length; i++) {
7158                Intent intent = res.key.allIntents[i];
7159                if (intent.getPackage() != null && intent.getComponent() != null) {
7160                    return false;
7161                }
7162            }
7163            return true;
7164        } catch (ClassCastException e) {
7165        }
7166        return false;
7167    }
7168
7169    @Override
7170    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7171        if (!(pendingResult instanceof PendingIntentRecord)) {
7172            return false;
7173        }
7174        try {
7175            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7176            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7177                return true;
7178            }
7179            return false;
7180        } catch (ClassCastException e) {
7181        }
7182        return false;
7183    }
7184
7185    @Override
7186    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7187        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7188                "getIntentForIntentSender()");
7189        if (!(pendingResult instanceof PendingIntentRecord)) {
7190            return null;
7191        }
7192        try {
7193            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7194            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7195        } catch (ClassCastException e) {
7196        }
7197        return null;
7198    }
7199
7200    @Override
7201    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7202        if (!(pendingResult instanceof PendingIntentRecord)) {
7203            return null;
7204        }
7205        try {
7206            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7207            synchronized (this) {
7208                return getTagForIntentSenderLocked(res, prefix);
7209            }
7210        } catch (ClassCastException e) {
7211        }
7212        return null;
7213    }
7214
7215    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7216        final Intent intent = res.key.requestIntent;
7217        if (intent != null) {
7218            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7219                    || res.lastTagPrefix.equals(prefix))) {
7220                return res.lastTag;
7221            }
7222            res.lastTagPrefix = prefix;
7223            final StringBuilder sb = new StringBuilder(128);
7224            if (prefix != null) {
7225                sb.append(prefix);
7226            }
7227            if (intent.getAction() != null) {
7228                sb.append(intent.getAction());
7229            } else if (intent.getComponent() != null) {
7230                intent.getComponent().appendShortString(sb);
7231            } else {
7232                sb.append("?");
7233            }
7234            return res.lastTag = sb.toString();
7235        }
7236        return null;
7237    }
7238
7239    @Override
7240    public void setProcessLimit(int max) {
7241        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7242                "setProcessLimit()");
7243        synchronized (this) {
7244            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7245            mProcessLimitOverride = max;
7246        }
7247        trimApplications();
7248    }
7249
7250    @Override
7251    public int getProcessLimit() {
7252        synchronized (this) {
7253            return mProcessLimitOverride;
7254        }
7255    }
7256
7257    void foregroundTokenDied(ForegroundToken token) {
7258        synchronized (ActivityManagerService.this) {
7259            synchronized (mPidsSelfLocked) {
7260                ForegroundToken cur
7261                    = mForegroundProcesses.get(token.pid);
7262                if (cur != token) {
7263                    return;
7264                }
7265                mForegroundProcesses.remove(token.pid);
7266                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7267                if (pr == null) {
7268                    return;
7269                }
7270                pr.forcingToForeground = null;
7271                updateProcessForegroundLocked(pr, false, false);
7272            }
7273            updateOomAdjLocked();
7274        }
7275    }
7276
7277    @Override
7278    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7279        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7280                "setProcessForeground()");
7281        synchronized(this) {
7282            boolean changed = false;
7283
7284            synchronized (mPidsSelfLocked) {
7285                ProcessRecord pr = mPidsSelfLocked.get(pid);
7286                if (pr == null && isForeground) {
7287                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7288                    return;
7289                }
7290                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7291                if (oldToken != null) {
7292                    oldToken.token.unlinkToDeath(oldToken, 0);
7293                    mForegroundProcesses.remove(pid);
7294                    if (pr != null) {
7295                        pr.forcingToForeground = null;
7296                    }
7297                    changed = true;
7298                }
7299                if (isForeground && token != null) {
7300                    ForegroundToken newToken = new ForegroundToken() {
7301                        @Override
7302                        public void binderDied() {
7303                            foregroundTokenDied(this);
7304                        }
7305                    };
7306                    newToken.pid = pid;
7307                    newToken.token = token;
7308                    try {
7309                        token.linkToDeath(newToken, 0);
7310                        mForegroundProcesses.put(pid, newToken);
7311                        pr.forcingToForeground = token;
7312                        changed = true;
7313                    } catch (RemoteException e) {
7314                        // If the process died while doing this, we will later
7315                        // do the cleanup with the process death link.
7316                    }
7317                }
7318            }
7319
7320            if (changed) {
7321                updateOomAdjLocked();
7322            }
7323        }
7324    }
7325
7326    @Override
7327    public boolean isAppForeground(int uid) throws RemoteException {
7328        synchronized (this) {
7329            UidRecord uidRec = mActiveUids.get(uid);
7330            if (uidRec == null || uidRec.idle) {
7331                return false;
7332            }
7333            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7334        }
7335    }
7336
7337    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7338    // be guarded by permission checking.
7339    int getUidState(int uid) {
7340        synchronized (this) {
7341            UidRecord uidRec = mActiveUids.get(uid);
7342            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7343        }
7344    }
7345
7346    @Override
7347    public boolean isInMultiWindowMode(IBinder token) {
7348        final long origId = Binder.clearCallingIdentity();
7349        try {
7350            synchronized(this) {
7351                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7352                if (r == null) {
7353                    return false;
7354                }
7355                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7356                return !r.task.mFullscreen;
7357            }
7358        } finally {
7359            Binder.restoreCallingIdentity(origId);
7360        }
7361    }
7362
7363    @Override
7364    public boolean isInPictureInPictureMode(IBinder token) {
7365        final long origId = Binder.clearCallingIdentity();
7366        try {
7367            synchronized(this) {
7368                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7369                if (stack == null) {
7370                    return false;
7371                }
7372                return stack.mStackId == PINNED_STACK_ID;
7373            }
7374        } finally {
7375            Binder.restoreCallingIdentity(origId);
7376        }
7377    }
7378
7379    @Override
7380    public void enterPictureInPictureMode(IBinder token) {
7381        final long origId = Binder.clearCallingIdentity();
7382        try {
7383            synchronized(this) {
7384                if (!mSupportsPictureInPicture) {
7385                    throw new IllegalStateException("enterPictureInPictureMode: "
7386                            + "Device doesn't support picture-in-picture mode.");
7387                }
7388
7389                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7390
7391                if (r == null) {
7392                    throw new IllegalStateException("enterPictureInPictureMode: "
7393                            + "Can't find activity for token=" + token);
7394                }
7395
7396                if (!r.supportsPictureInPicture()) {
7397                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7398                            + "Picture-In-Picture not supported for r=" + r);
7399                }
7400
7401                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7402                // current bounds.
7403                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7404                final Rect bounds = (pinnedStack != null)
7405                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7406
7407                mStackSupervisor.moveActivityToPinnedStackLocked(
7408                        r, "enterPictureInPictureMode", bounds);
7409            }
7410        } finally {
7411            Binder.restoreCallingIdentity(origId);
7412        }
7413    }
7414
7415    // =========================================================
7416    // PROCESS INFO
7417    // =========================================================
7418
7419    static class ProcessInfoService extends IProcessInfoService.Stub {
7420        final ActivityManagerService mActivityManagerService;
7421        ProcessInfoService(ActivityManagerService activityManagerService) {
7422            mActivityManagerService = activityManagerService;
7423        }
7424
7425        @Override
7426        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7427            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7428                    /*in*/ pids, /*out*/ states, null);
7429        }
7430
7431        @Override
7432        public void getProcessStatesAndOomScoresFromPids(
7433                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7434            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7435                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7436        }
7437    }
7438
7439    /**
7440     * For each PID in the given input array, write the current process state
7441     * for that process into the states array, or -1 to indicate that no
7442     * process with the given PID exists. If scores array is provided, write
7443     * the oom score for the process into the scores array, with INVALID_ADJ
7444     * indicating the PID doesn't exist.
7445     */
7446    public void getProcessStatesAndOomScoresForPIDs(
7447            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7448        if (scores != null) {
7449            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7450                    "getProcessStatesAndOomScoresForPIDs()");
7451        }
7452
7453        if (pids == null) {
7454            throw new NullPointerException("pids");
7455        } else if (states == null) {
7456            throw new NullPointerException("states");
7457        } else if (pids.length != states.length) {
7458            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7459        } else if (scores != null && pids.length != scores.length) {
7460            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7461        }
7462
7463        synchronized (mPidsSelfLocked) {
7464            for (int i = 0; i < pids.length; i++) {
7465                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7466                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7467                        pr.curProcState;
7468                if (scores != null) {
7469                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7470                }
7471            }
7472        }
7473    }
7474
7475    // =========================================================
7476    // PERMISSIONS
7477    // =========================================================
7478
7479    static class PermissionController extends IPermissionController.Stub {
7480        ActivityManagerService mActivityManagerService;
7481        PermissionController(ActivityManagerService activityManagerService) {
7482            mActivityManagerService = activityManagerService;
7483        }
7484
7485        @Override
7486        public boolean checkPermission(String permission, int pid, int uid) {
7487            return mActivityManagerService.checkPermission(permission, pid,
7488                    uid) == PackageManager.PERMISSION_GRANTED;
7489        }
7490
7491        @Override
7492        public String[] getPackagesForUid(int uid) {
7493            return mActivityManagerService.mContext.getPackageManager()
7494                    .getPackagesForUid(uid);
7495        }
7496
7497        @Override
7498        public boolean isRuntimePermission(String permission) {
7499            try {
7500                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7501                        .getPermissionInfo(permission, 0);
7502                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7503            } catch (NameNotFoundException nnfe) {
7504                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7505            }
7506            return false;
7507        }
7508    }
7509
7510    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7511        @Override
7512        public int checkComponentPermission(String permission, int pid, int uid,
7513                int owningUid, boolean exported) {
7514            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7515                    owningUid, exported);
7516        }
7517
7518        @Override
7519        public Object getAMSLock() {
7520            return ActivityManagerService.this;
7521        }
7522    }
7523
7524    /**
7525     * This can be called with or without the global lock held.
7526     */
7527    int checkComponentPermission(String permission, int pid, int uid,
7528            int owningUid, boolean exported) {
7529        if (pid == MY_PID) {
7530            return PackageManager.PERMISSION_GRANTED;
7531        }
7532        return ActivityManager.checkComponentPermission(permission, uid,
7533                owningUid, exported);
7534    }
7535
7536    /**
7537     * As the only public entry point for permissions checking, this method
7538     * can enforce the semantic that requesting a check on a null global
7539     * permission is automatically denied.  (Internally a null permission
7540     * string is used when calling {@link #checkComponentPermission} in cases
7541     * when only uid-based security is needed.)
7542     *
7543     * This can be called with or without the global lock held.
7544     */
7545    @Override
7546    public int checkPermission(String permission, int pid, int uid) {
7547        if (permission == null) {
7548            return PackageManager.PERMISSION_DENIED;
7549        }
7550        return checkComponentPermission(permission, pid, uid, -1, true);
7551    }
7552
7553    @Override
7554    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7555        if (permission == null) {
7556            return PackageManager.PERMISSION_DENIED;
7557        }
7558
7559        // We might be performing an operation on behalf of an indirect binder
7560        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7561        // client identity accordingly before proceeding.
7562        Identity tlsIdentity = sCallerIdentity.get();
7563        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7564            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7565                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7566            uid = tlsIdentity.uid;
7567            pid = tlsIdentity.pid;
7568        }
7569
7570        return checkComponentPermission(permission, pid, uid, -1, true);
7571    }
7572
7573    /**
7574     * Binder IPC calls go through the public entry point.
7575     * This can be called with or without the global lock held.
7576     */
7577    int checkCallingPermission(String permission) {
7578        return checkPermission(permission,
7579                Binder.getCallingPid(),
7580                UserHandle.getAppId(Binder.getCallingUid()));
7581    }
7582
7583    /**
7584     * This can be called with or without the global lock held.
7585     */
7586    void enforceCallingPermission(String permission, String func) {
7587        if (checkCallingPermission(permission)
7588                == PackageManager.PERMISSION_GRANTED) {
7589            return;
7590        }
7591
7592        String msg = "Permission Denial: " + func + " from pid="
7593                + Binder.getCallingPid()
7594                + ", uid=" + Binder.getCallingUid()
7595                + " requires " + permission;
7596        Slog.w(TAG, msg);
7597        throw new SecurityException(msg);
7598    }
7599
7600    /**
7601     * Determine if UID is holding permissions required to access {@link Uri} in
7602     * the given {@link ProviderInfo}. Final permission checking is always done
7603     * in {@link ContentProvider}.
7604     */
7605    private final boolean checkHoldingPermissionsLocked(
7606            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7607        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7608                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7609        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7610            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7611                    != PERMISSION_GRANTED) {
7612                return false;
7613            }
7614        }
7615        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7616    }
7617
7618    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7619            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7620        if (pi.applicationInfo.uid == uid) {
7621            return true;
7622        } else if (!pi.exported) {
7623            return false;
7624        }
7625
7626        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7627        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7628        try {
7629            // check if target holds top-level <provider> permissions
7630            if (!readMet && pi.readPermission != null && considerUidPermissions
7631                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7632                readMet = true;
7633            }
7634            if (!writeMet && pi.writePermission != null && considerUidPermissions
7635                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7636                writeMet = true;
7637            }
7638
7639            // track if unprotected read/write is allowed; any denied
7640            // <path-permission> below removes this ability
7641            boolean allowDefaultRead = pi.readPermission == null;
7642            boolean allowDefaultWrite = pi.writePermission == null;
7643
7644            // check if target holds any <path-permission> that match uri
7645            final PathPermission[] pps = pi.pathPermissions;
7646            if (pps != null) {
7647                final String path = grantUri.uri.getPath();
7648                int i = pps.length;
7649                while (i > 0 && (!readMet || !writeMet)) {
7650                    i--;
7651                    PathPermission pp = pps[i];
7652                    if (pp.match(path)) {
7653                        if (!readMet) {
7654                            final String pprperm = pp.getReadPermission();
7655                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7656                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7657                                    + ": match=" + pp.match(path)
7658                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7659                            if (pprperm != null) {
7660                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7661                                        == PERMISSION_GRANTED) {
7662                                    readMet = true;
7663                                } else {
7664                                    allowDefaultRead = false;
7665                                }
7666                            }
7667                        }
7668                        if (!writeMet) {
7669                            final String ppwperm = pp.getWritePermission();
7670                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7671                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7672                                    + ": match=" + pp.match(path)
7673                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7674                            if (ppwperm != null) {
7675                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7676                                        == PERMISSION_GRANTED) {
7677                                    writeMet = true;
7678                                } else {
7679                                    allowDefaultWrite = false;
7680                                }
7681                            }
7682                        }
7683                    }
7684                }
7685            }
7686
7687            // grant unprotected <provider> read/write, if not blocked by
7688            // <path-permission> above
7689            if (allowDefaultRead) readMet = true;
7690            if (allowDefaultWrite) writeMet = true;
7691
7692        } catch (RemoteException e) {
7693            return false;
7694        }
7695
7696        return readMet && writeMet;
7697    }
7698
7699    public int getAppStartMode(int uid, String packageName) {
7700        synchronized (this) {
7701            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7702        }
7703    }
7704
7705    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7706            boolean allowWhenForeground) {
7707        UidRecord uidRec = mActiveUids.get(uid);
7708        if (!mLenientBackgroundCheck) {
7709            if (!allowWhenForeground || uidRec == null
7710                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7711                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7712                        packageName) != AppOpsManager.MODE_ALLOWED) {
7713                    return ActivityManager.APP_START_MODE_DELAYED;
7714                }
7715            }
7716
7717        } else if (uidRec == null || uidRec.idle) {
7718            if (callingPid >= 0) {
7719                ProcessRecord proc;
7720                synchronized (mPidsSelfLocked) {
7721                    proc = mPidsSelfLocked.get(callingPid);
7722                }
7723                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7724                    // Whoever is instigating this is in the foreground, so we will allow it
7725                    // to go through.
7726                    return ActivityManager.APP_START_MODE_NORMAL;
7727                }
7728            }
7729            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7730                    != AppOpsManager.MODE_ALLOWED) {
7731                return ActivityManager.APP_START_MODE_DELAYED;
7732            }
7733        }
7734        return ActivityManager.APP_START_MODE_NORMAL;
7735    }
7736
7737    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7738        ProviderInfo pi = null;
7739        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7740        if (cpr != null) {
7741            pi = cpr.info;
7742        } else {
7743            try {
7744                pi = AppGlobals.getPackageManager().resolveContentProvider(
7745                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7746            } catch (RemoteException ex) {
7747            }
7748        }
7749        return pi;
7750    }
7751
7752    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7753        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7754        if (targetUris != null) {
7755            return targetUris.get(grantUri);
7756        }
7757        return null;
7758    }
7759
7760    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7761            String targetPkg, int targetUid, GrantUri grantUri) {
7762        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7763        if (targetUris == null) {
7764            targetUris = Maps.newArrayMap();
7765            mGrantedUriPermissions.put(targetUid, targetUris);
7766        }
7767
7768        UriPermission perm = targetUris.get(grantUri);
7769        if (perm == null) {
7770            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7771            targetUris.put(grantUri, perm);
7772        }
7773
7774        return perm;
7775    }
7776
7777    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7778            final int modeFlags) {
7779        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7780        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7781                : UriPermission.STRENGTH_OWNED;
7782
7783        // Root gets to do everything.
7784        if (uid == 0) {
7785            return true;
7786        }
7787
7788        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7789        if (perms == null) return false;
7790
7791        // First look for exact match
7792        final UriPermission exactPerm = perms.get(grantUri);
7793        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7794            return true;
7795        }
7796
7797        // No exact match, look for prefixes
7798        final int N = perms.size();
7799        for (int i = 0; i < N; i++) {
7800            final UriPermission perm = perms.valueAt(i);
7801            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7802                    && perm.getStrength(modeFlags) >= minStrength) {
7803                return true;
7804            }
7805        }
7806
7807        return false;
7808    }
7809
7810    /**
7811     * @param uri This uri must NOT contain an embedded userId.
7812     * @param userId The userId in which the uri is to be resolved.
7813     */
7814    @Override
7815    public int checkUriPermission(Uri uri, int pid, int uid,
7816            final int modeFlags, int userId, IBinder callerToken) {
7817        enforceNotIsolatedCaller("checkUriPermission");
7818
7819        // Another redirected-binder-call permissions check as in
7820        // {@link checkPermissionWithToken}.
7821        Identity tlsIdentity = sCallerIdentity.get();
7822        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7823            uid = tlsIdentity.uid;
7824            pid = tlsIdentity.pid;
7825        }
7826
7827        // Our own process gets to do everything.
7828        if (pid == MY_PID) {
7829            return PackageManager.PERMISSION_GRANTED;
7830        }
7831        synchronized (this) {
7832            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7833                    ? PackageManager.PERMISSION_GRANTED
7834                    : PackageManager.PERMISSION_DENIED;
7835        }
7836    }
7837
7838    /**
7839     * Check if the targetPkg can be granted permission to access uri by
7840     * the callingUid using the given modeFlags.  Throws a security exception
7841     * if callingUid is not allowed to do this.  Returns the uid of the target
7842     * if the URI permission grant should be performed; returns -1 if it is not
7843     * needed (for example targetPkg already has permission to access the URI).
7844     * If you already know the uid of the target, you can supply it in
7845     * lastTargetUid else set that to -1.
7846     */
7847    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7848            final int modeFlags, int lastTargetUid) {
7849        if (!Intent.isAccessUriMode(modeFlags)) {
7850            return -1;
7851        }
7852
7853        if (targetPkg != null) {
7854            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7855                    "Checking grant " + targetPkg + " permission to " + grantUri);
7856        }
7857
7858        final IPackageManager pm = AppGlobals.getPackageManager();
7859
7860        // If this is not a content: uri, we can't do anything with it.
7861        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7862            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7863                    "Can't grant URI permission for non-content URI: " + grantUri);
7864            return -1;
7865        }
7866
7867        final String authority = grantUri.uri.getAuthority();
7868        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7869        if (pi == null) {
7870            Slog.w(TAG, "No content provider found for permission check: " +
7871                    grantUri.uri.toSafeString());
7872            return -1;
7873        }
7874
7875        int targetUid = lastTargetUid;
7876        if (targetUid < 0 && targetPkg != null) {
7877            try {
7878                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7879                        UserHandle.getUserId(callingUid));
7880                if (targetUid < 0) {
7881                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7882                            "Can't grant URI permission no uid for: " + targetPkg);
7883                    return -1;
7884                }
7885            } catch (RemoteException ex) {
7886                return -1;
7887            }
7888        }
7889
7890        if (targetUid >= 0) {
7891            // First...  does the target actually need this permission?
7892            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7893                // No need to grant the target this permission.
7894                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7895                        "Target " + targetPkg + " already has full permission to " + grantUri);
7896                return -1;
7897            }
7898        } else {
7899            // First...  there is no target package, so can anyone access it?
7900            boolean allowed = pi.exported;
7901            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7902                if (pi.readPermission != null) {
7903                    allowed = false;
7904                }
7905            }
7906            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7907                if (pi.writePermission != null) {
7908                    allowed = false;
7909                }
7910            }
7911            if (allowed) {
7912                return -1;
7913            }
7914        }
7915
7916        /* There is a special cross user grant if:
7917         * - The target is on another user.
7918         * - Apps on the current user can access the uri without any uid permissions.
7919         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7920         * grant uri permissions.
7921         */
7922        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7923                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7924                modeFlags, false /*without considering the uid permissions*/);
7925
7926        // Second...  is the provider allowing granting of URI permissions?
7927        if (!specialCrossUserGrant) {
7928            if (!pi.grantUriPermissions) {
7929                throw new SecurityException("Provider " + pi.packageName
7930                        + "/" + pi.name
7931                        + " does not allow granting of Uri permissions (uri "
7932                        + grantUri + ")");
7933            }
7934            if (pi.uriPermissionPatterns != null) {
7935                final int N = pi.uriPermissionPatterns.length;
7936                boolean allowed = false;
7937                for (int i=0; i<N; i++) {
7938                    if (pi.uriPermissionPatterns[i] != null
7939                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7940                        allowed = true;
7941                        break;
7942                    }
7943                }
7944                if (!allowed) {
7945                    throw new SecurityException("Provider " + pi.packageName
7946                            + "/" + pi.name
7947                            + " does not allow granting of permission to path of Uri "
7948                            + grantUri);
7949                }
7950            }
7951        }
7952
7953        // Third...  does the caller itself have permission to access
7954        // this uri?
7955        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7956            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7957                // Require they hold a strong enough Uri permission
7958                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7959                    throw new SecurityException("Uid " + callingUid
7960                            + " does not have permission to uri " + grantUri);
7961                }
7962            }
7963        }
7964        return targetUid;
7965    }
7966
7967    /**
7968     * @param uri This uri must NOT contain an embedded userId.
7969     * @param userId The userId in which the uri is to be resolved.
7970     */
7971    @Override
7972    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7973            final int modeFlags, int userId) {
7974        enforceNotIsolatedCaller("checkGrantUriPermission");
7975        synchronized(this) {
7976            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7977                    new GrantUri(userId, uri, false), modeFlags, -1);
7978        }
7979    }
7980
7981    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7982            final int modeFlags, UriPermissionOwner owner) {
7983        if (!Intent.isAccessUriMode(modeFlags)) {
7984            return;
7985        }
7986
7987        // So here we are: the caller has the assumed permission
7988        // to the uri, and the target doesn't.  Let's now give this to
7989        // the target.
7990
7991        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7992                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7993
7994        final String authority = grantUri.uri.getAuthority();
7995        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7996        if (pi == null) {
7997            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7998            return;
7999        }
8000
8001        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8002            grantUri.prefix = true;
8003        }
8004        final UriPermission perm = findOrCreateUriPermissionLocked(
8005                pi.packageName, targetPkg, targetUid, grantUri);
8006        perm.grantModes(modeFlags, owner);
8007    }
8008
8009    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8010            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8011        if (targetPkg == null) {
8012            throw new NullPointerException("targetPkg");
8013        }
8014        int targetUid;
8015        final IPackageManager pm = AppGlobals.getPackageManager();
8016        try {
8017            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8018        } catch (RemoteException ex) {
8019            return;
8020        }
8021
8022        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8023                targetUid);
8024        if (targetUid < 0) {
8025            return;
8026        }
8027
8028        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8029                owner);
8030    }
8031
8032    static class NeededUriGrants extends ArrayList<GrantUri> {
8033        final String targetPkg;
8034        final int targetUid;
8035        final int flags;
8036
8037        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8038            this.targetPkg = targetPkg;
8039            this.targetUid = targetUid;
8040            this.flags = flags;
8041        }
8042    }
8043
8044    /**
8045     * Like checkGrantUriPermissionLocked, but takes an Intent.
8046     */
8047    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8048            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8049        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8050                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8051                + " clip=" + (intent != null ? intent.getClipData() : null)
8052                + " from " + intent + "; flags=0x"
8053                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8054
8055        if (targetPkg == null) {
8056            throw new NullPointerException("targetPkg");
8057        }
8058
8059        if (intent == null) {
8060            return null;
8061        }
8062        Uri data = intent.getData();
8063        ClipData clip = intent.getClipData();
8064        if (data == null && clip == null) {
8065            return null;
8066        }
8067        // Default userId for uris in the intent (if they don't specify it themselves)
8068        int contentUserHint = intent.getContentUserHint();
8069        if (contentUserHint == UserHandle.USER_CURRENT) {
8070            contentUserHint = UserHandle.getUserId(callingUid);
8071        }
8072        final IPackageManager pm = AppGlobals.getPackageManager();
8073        int targetUid;
8074        if (needed != null) {
8075            targetUid = needed.targetUid;
8076        } else {
8077            try {
8078                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8079                        targetUserId);
8080            } catch (RemoteException ex) {
8081                return null;
8082            }
8083            if (targetUid < 0) {
8084                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8085                        "Can't grant URI permission no uid for: " + targetPkg
8086                        + " on user " + targetUserId);
8087                return null;
8088            }
8089        }
8090        if (data != null) {
8091            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8092            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8093                    targetUid);
8094            if (targetUid > 0) {
8095                if (needed == null) {
8096                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8097                }
8098                needed.add(grantUri);
8099            }
8100        }
8101        if (clip != null) {
8102            for (int i=0; i<clip.getItemCount(); i++) {
8103                Uri uri = clip.getItemAt(i).getUri();
8104                if (uri != null) {
8105                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8106                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8107                            targetUid);
8108                    if (targetUid > 0) {
8109                        if (needed == null) {
8110                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8111                        }
8112                        needed.add(grantUri);
8113                    }
8114                } else {
8115                    Intent clipIntent = clip.getItemAt(i).getIntent();
8116                    if (clipIntent != null) {
8117                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8118                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8119                        if (newNeeded != null) {
8120                            needed = newNeeded;
8121                        }
8122                    }
8123                }
8124            }
8125        }
8126
8127        return needed;
8128    }
8129
8130    /**
8131     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8132     */
8133    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8134            UriPermissionOwner owner) {
8135        if (needed != null) {
8136            for (int i=0; i<needed.size(); i++) {
8137                GrantUri grantUri = needed.get(i);
8138                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8139                        grantUri, needed.flags, owner);
8140            }
8141        }
8142    }
8143
8144    void grantUriPermissionFromIntentLocked(int callingUid,
8145            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8146        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8147                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8148        if (needed == null) {
8149            return;
8150        }
8151
8152        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8153    }
8154
8155    /**
8156     * @param uri This uri must NOT contain an embedded userId.
8157     * @param userId The userId in which the uri is to be resolved.
8158     */
8159    @Override
8160    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8161            final int modeFlags, int userId) {
8162        enforceNotIsolatedCaller("grantUriPermission");
8163        GrantUri grantUri = new GrantUri(userId, uri, false);
8164        synchronized(this) {
8165            final ProcessRecord r = getRecordForAppLocked(caller);
8166            if (r == null) {
8167                throw new SecurityException("Unable to find app for caller "
8168                        + caller
8169                        + " when granting permission to uri " + grantUri);
8170            }
8171            if (targetPkg == null) {
8172                throw new IllegalArgumentException("null target");
8173            }
8174            if (grantUri == null) {
8175                throw new IllegalArgumentException("null uri");
8176            }
8177
8178            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8179                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8180                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8181                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8182
8183            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8184                    UserHandle.getUserId(r.uid));
8185        }
8186    }
8187
8188    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8189        if (perm.modeFlags == 0) {
8190            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8191                    perm.targetUid);
8192            if (perms != null) {
8193                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8194                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8195
8196                perms.remove(perm.uri);
8197                if (perms.isEmpty()) {
8198                    mGrantedUriPermissions.remove(perm.targetUid);
8199                }
8200            }
8201        }
8202    }
8203
8204    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8205        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8206                "Revoking all granted permissions to " + grantUri);
8207
8208        final IPackageManager pm = AppGlobals.getPackageManager();
8209        final String authority = grantUri.uri.getAuthority();
8210        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8211        if (pi == null) {
8212            Slog.w(TAG, "No content provider found for permission revoke: "
8213                    + grantUri.toSafeString());
8214            return;
8215        }
8216
8217        // Does the caller have this permission on the URI?
8218        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8219            // If they don't have direct access to the URI, then revoke any
8220            // ownerless URI permissions that have been granted to them.
8221            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8222            if (perms != null) {
8223                boolean persistChanged = false;
8224                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8225                    final UriPermission perm = it.next();
8226                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8227                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8228                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8229                                "Revoking non-owned " + perm.targetUid
8230                                + " permission to " + perm.uri);
8231                        persistChanged |= perm.revokeModes(
8232                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8233                        if (perm.modeFlags == 0) {
8234                            it.remove();
8235                        }
8236                    }
8237                }
8238                if (perms.isEmpty()) {
8239                    mGrantedUriPermissions.remove(callingUid);
8240                }
8241                if (persistChanged) {
8242                    schedulePersistUriGrants();
8243                }
8244            }
8245            return;
8246        }
8247
8248        boolean persistChanged = false;
8249
8250        // Go through all of the permissions and remove any that match.
8251        int N = mGrantedUriPermissions.size();
8252        for (int i = 0; i < N; i++) {
8253            final int targetUid = mGrantedUriPermissions.keyAt(i);
8254            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8255
8256            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8257                final UriPermission perm = it.next();
8258                if (perm.uri.sourceUserId == grantUri.sourceUserId
8259                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8260                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8261                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8262                    persistChanged |= perm.revokeModes(
8263                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8264                    if (perm.modeFlags == 0) {
8265                        it.remove();
8266                    }
8267                }
8268            }
8269
8270            if (perms.isEmpty()) {
8271                mGrantedUriPermissions.remove(targetUid);
8272                N--;
8273                i--;
8274            }
8275        }
8276
8277        if (persistChanged) {
8278            schedulePersistUriGrants();
8279        }
8280    }
8281
8282    /**
8283     * @param uri This uri must NOT contain an embedded userId.
8284     * @param userId The userId in which the uri is to be resolved.
8285     */
8286    @Override
8287    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8288            int userId) {
8289        enforceNotIsolatedCaller("revokeUriPermission");
8290        synchronized(this) {
8291            final ProcessRecord r = getRecordForAppLocked(caller);
8292            if (r == null) {
8293                throw new SecurityException("Unable to find app for caller "
8294                        + caller
8295                        + " when revoking permission to uri " + uri);
8296            }
8297            if (uri == null) {
8298                Slog.w(TAG, "revokeUriPermission: null uri");
8299                return;
8300            }
8301
8302            if (!Intent.isAccessUriMode(modeFlags)) {
8303                return;
8304            }
8305
8306            final String authority = uri.getAuthority();
8307            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8308            if (pi == null) {
8309                Slog.w(TAG, "No content provider found for permission revoke: "
8310                        + uri.toSafeString());
8311                return;
8312            }
8313
8314            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8315        }
8316    }
8317
8318    /**
8319     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8320     * given package.
8321     *
8322     * @param packageName Package name to match, or {@code null} to apply to all
8323     *            packages.
8324     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8325     *            to all users.
8326     * @param persistable If persistable grants should be removed.
8327     */
8328    private void removeUriPermissionsForPackageLocked(
8329            String packageName, int userHandle, boolean persistable) {
8330        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8331            throw new IllegalArgumentException("Must narrow by either package or user");
8332        }
8333
8334        boolean persistChanged = false;
8335
8336        int N = mGrantedUriPermissions.size();
8337        for (int i = 0; i < N; i++) {
8338            final int targetUid = mGrantedUriPermissions.keyAt(i);
8339            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8340
8341            // Only inspect grants matching user
8342            if (userHandle == UserHandle.USER_ALL
8343                    || userHandle == UserHandle.getUserId(targetUid)) {
8344                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8345                    final UriPermission perm = it.next();
8346
8347                    // Only inspect grants matching package
8348                    if (packageName == null || perm.sourcePkg.equals(packageName)
8349                            || perm.targetPkg.equals(packageName)) {
8350                        persistChanged |= perm.revokeModes(persistable
8351                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8352
8353                        // Only remove when no modes remain; any persisted grants
8354                        // will keep this alive.
8355                        if (perm.modeFlags == 0) {
8356                            it.remove();
8357                        }
8358                    }
8359                }
8360
8361                if (perms.isEmpty()) {
8362                    mGrantedUriPermissions.remove(targetUid);
8363                    N--;
8364                    i--;
8365                }
8366            }
8367        }
8368
8369        if (persistChanged) {
8370            schedulePersistUriGrants();
8371        }
8372    }
8373
8374    @Override
8375    public IBinder newUriPermissionOwner(String name) {
8376        enforceNotIsolatedCaller("newUriPermissionOwner");
8377        synchronized(this) {
8378            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8379            return owner.getExternalTokenLocked();
8380        }
8381    }
8382
8383    @Override
8384    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8385        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8386        synchronized(this) {
8387            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8388            if (r == null) {
8389                throw new IllegalArgumentException("Activity does not exist; token="
8390                        + activityToken);
8391            }
8392            return r.getUriPermissionsLocked().getExternalTokenLocked();
8393        }
8394    }
8395    /**
8396     * @param uri This uri must NOT contain an embedded userId.
8397     * @param sourceUserId The userId in which the uri is to be resolved.
8398     * @param targetUserId The userId of the app that receives the grant.
8399     */
8400    @Override
8401    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8402            final int modeFlags, int sourceUserId, int targetUserId) {
8403        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8404                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8405                "grantUriPermissionFromOwner", null);
8406        synchronized(this) {
8407            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8408            if (owner == null) {
8409                throw new IllegalArgumentException("Unknown owner: " + token);
8410            }
8411            if (fromUid != Binder.getCallingUid()) {
8412                if (Binder.getCallingUid() != Process.myUid()) {
8413                    // Only system code can grant URI permissions on behalf
8414                    // of other users.
8415                    throw new SecurityException("nice try");
8416                }
8417            }
8418            if (targetPkg == null) {
8419                throw new IllegalArgumentException("null target");
8420            }
8421            if (uri == null) {
8422                throw new IllegalArgumentException("null uri");
8423            }
8424
8425            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8426                    modeFlags, owner, targetUserId);
8427        }
8428    }
8429
8430    /**
8431     * @param uri This uri must NOT contain an embedded userId.
8432     * @param userId The userId in which the uri is to be resolved.
8433     */
8434    @Override
8435    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8436        synchronized(this) {
8437            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8438            if (owner == null) {
8439                throw new IllegalArgumentException("Unknown owner: " + token);
8440            }
8441
8442            if (uri == null) {
8443                owner.removeUriPermissionsLocked(mode);
8444            } else {
8445                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8446            }
8447        }
8448    }
8449
8450    private void schedulePersistUriGrants() {
8451        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8452            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8453                    10 * DateUtils.SECOND_IN_MILLIS);
8454        }
8455    }
8456
8457    private void writeGrantedUriPermissions() {
8458        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8459
8460        // Snapshot permissions so we can persist without lock
8461        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8462        synchronized (this) {
8463            final int size = mGrantedUriPermissions.size();
8464            for (int i = 0; i < size; i++) {
8465                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8466                for (UriPermission perm : perms.values()) {
8467                    if (perm.persistedModeFlags != 0) {
8468                        persist.add(perm.snapshot());
8469                    }
8470                }
8471            }
8472        }
8473
8474        FileOutputStream fos = null;
8475        try {
8476            fos = mGrantFile.startWrite();
8477
8478            XmlSerializer out = new FastXmlSerializer();
8479            out.setOutput(fos, StandardCharsets.UTF_8.name());
8480            out.startDocument(null, true);
8481            out.startTag(null, TAG_URI_GRANTS);
8482            for (UriPermission.Snapshot perm : persist) {
8483                out.startTag(null, TAG_URI_GRANT);
8484                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8485                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8486                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8487                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8488                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8489                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8490                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8491                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8492                out.endTag(null, TAG_URI_GRANT);
8493            }
8494            out.endTag(null, TAG_URI_GRANTS);
8495            out.endDocument();
8496
8497            mGrantFile.finishWrite(fos);
8498        } catch (IOException e) {
8499            if (fos != null) {
8500                mGrantFile.failWrite(fos);
8501            }
8502        }
8503    }
8504
8505    private void readGrantedUriPermissionsLocked() {
8506        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8507
8508        final long now = System.currentTimeMillis();
8509
8510        FileInputStream fis = null;
8511        try {
8512            fis = mGrantFile.openRead();
8513            final XmlPullParser in = Xml.newPullParser();
8514            in.setInput(fis, StandardCharsets.UTF_8.name());
8515
8516            int type;
8517            while ((type = in.next()) != END_DOCUMENT) {
8518                final String tag = in.getName();
8519                if (type == START_TAG) {
8520                    if (TAG_URI_GRANT.equals(tag)) {
8521                        final int sourceUserId;
8522                        final int targetUserId;
8523                        final int userHandle = readIntAttribute(in,
8524                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8525                        if (userHandle != UserHandle.USER_NULL) {
8526                            // For backwards compatibility.
8527                            sourceUserId = userHandle;
8528                            targetUserId = userHandle;
8529                        } else {
8530                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8531                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8532                        }
8533                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8534                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8535                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8536                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8537                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8538                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8539
8540                        // Sanity check that provider still belongs to source package
8541                        final ProviderInfo pi = getProviderInfoLocked(
8542                                uri.getAuthority(), sourceUserId);
8543                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8544                            int targetUid = -1;
8545                            try {
8546                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8547                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8548                            } catch (RemoteException e) {
8549                            }
8550                            if (targetUid != -1) {
8551                                final UriPermission perm = findOrCreateUriPermissionLocked(
8552                                        sourcePkg, targetPkg, targetUid,
8553                                        new GrantUri(sourceUserId, uri, prefix));
8554                                perm.initPersistedModes(modeFlags, createdTime);
8555                            }
8556                        } else {
8557                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8558                                    + " but instead found " + pi);
8559                        }
8560                    }
8561                }
8562            }
8563        } catch (FileNotFoundException e) {
8564            // Missing grants is okay
8565        } catch (IOException e) {
8566            Slog.wtf(TAG, "Failed reading Uri grants", e);
8567        } catch (XmlPullParserException e) {
8568            Slog.wtf(TAG, "Failed reading Uri grants", e);
8569        } finally {
8570            IoUtils.closeQuietly(fis);
8571        }
8572    }
8573
8574    /**
8575     * @param uri This uri must NOT contain an embedded userId.
8576     * @param userId The userId in which the uri is to be resolved.
8577     */
8578    @Override
8579    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8580        enforceNotIsolatedCaller("takePersistableUriPermission");
8581
8582        Preconditions.checkFlagsArgument(modeFlags,
8583                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8584
8585        synchronized (this) {
8586            final int callingUid = Binder.getCallingUid();
8587            boolean persistChanged = false;
8588            GrantUri grantUri = new GrantUri(userId, uri, false);
8589
8590            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8591                    new GrantUri(userId, uri, false));
8592            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8593                    new GrantUri(userId, uri, true));
8594
8595            final boolean exactValid = (exactPerm != null)
8596                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8597            final boolean prefixValid = (prefixPerm != null)
8598                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8599
8600            if (!(exactValid || prefixValid)) {
8601                throw new SecurityException("No persistable permission grants found for UID "
8602                        + callingUid + " and Uri " + grantUri.toSafeString());
8603            }
8604
8605            if (exactValid) {
8606                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8607            }
8608            if (prefixValid) {
8609                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8610            }
8611
8612            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8613
8614            if (persistChanged) {
8615                schedulePersistUriGrants();
8616            }
8617        }
8618    }
8619
8620    /**
8621     * @param uri This uri must NOT contain an embedded userId.
8622     * @param userId The userId in which the uri is to be resolved.
8623     */
8624    @Override
8625    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8626        enforceNotIsolatedCaller("releasePersistableUriPermission");
8627
8628        Preconditions.checkFlagsArgument(modeFlags,
8629                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8630
8631        synchronized (this) {
8632            final int callingUid = Binder.getCallingUid();
8633            boolean persistChanged = false;
8634
8635            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8636                    new GrantUri(userId, uri, false));
8637            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8638                    new GrantUri(userId, uri, true));
8639            if (exactPerm == null && prefixPerm == null) {
8640                throw new SecurityException("No permission grants found for UID " + callingUid
8641                        + " and Uri " + uri.toSafeString());
8642            }
8643
8644            if (exactPerm != null) {
8645                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8646                removeUriPermissionIfNeededLocked(exactPerm);
8647            }
8648            if (prefixPerm != null) {
8649                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8650                removeUriPermissionIfNeededLocked(prefixPerm);
8651            }
8652
8653            if (persistChanged) {
8654                schedulePersistUriGrants();
8655            }
8656        }
8657    }
8658
8659    /**
8660     * Prune any older {@link UriPermission} for the given UID until outstanding
8661     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8662     *
8663     * @return if any mutations occured that require persisting.
8664     */
8665    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8666        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8667        if (perms == null) return false;
8668        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8669
8670        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8671        for (UriPermission perm : perms.values()) {
8672            if (perm.persistedModeFlags != 0) {
8673                persisted.add(perm);
8674            }
8675        }
8676
8677        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8678        if (trimCount <= 0) return false;
8679
8680        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8681        for (int i = 0; i < trimCount; i++) {
8682            final UriPermission perm = persisted.get(i);
8683
8684            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8685                    "Trimming grant created at " + perm.persistedCreateTime);
8686
8687            perm.releasePersistableModes(~0);
8688            removeUriPermissionIfNeededLocked(perm);
8689        }
8690
8691        return true;
8692    }
8693
8694    @Override
8695    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8696            String packageName, boolean incoming) {
8697        enforceNotIsolatedCaller("getPersistedUriPermissions");
8698        Preconditions.checkNotNull(packageName, "packageName");
8699
8700        final int callingUid = Binder.getCallingUid();
8701        final IPackageManager pm = AppGlobals.getPackageManager();
8702        try {
8703            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8704                    UserHandle.getUserId(callingUid));
8705            if (packageUid != callingUid) {
8706                throw new SecurityException(
8707                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8708            }
8709        } catch (RemoteException e) {
8710            throw new SecurityException("Failed to verify package name ownership");
8711        }
8712
8713        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8714        synchronized (this) {
8715            if (incoming) {
8716                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8717                        callingUid);
8718                if (perms == null) {
8719                    Slog.w(TAG, "No permission grants found for " + packageName);
8720                } else {
8721                    for (UriPermission perm : perms.values()) {
8722                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8723                            result.add(perm.buildPersistedPublicApiObject());
8724                        }
8725                    }
8726                }
8727            } else {
8728                final int size = mGrantedUriPermissions.size();
8729                for (int i = 0; i < size; i++) {
8730                    final ArrayMap<GrantUri, UriPermission> perms =
8731                            mGrantedUriPermissions.valueAt(i);
8732                    for (UriPermission perm : perms.values()) {
8733                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8734                            result.add(perm.buildPersistedPublicApiObject());
8735                        }
8736                    }
8737                }
8738            }
8739        }
8740        return new ParceledListSlice<android.content.UriPermission>(result);
8741    }
8742
8743    @Override
8744    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8745            String packageName, int userId) {
8746        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8747                "getGrantedUriPermissions");
8748
8749        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8750        synchronized (this) {
8751            final int size = mGrantedUriPermissions.size();
8752            for (int i = 0; i < size; i++) {
8753                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8754                for (UriPermission perm : perms.values()) {
8755                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8756                            && perm.persistedModeFlags != 0) {
8757                        result.add(perm.buildPersistedPublicApiObject());
8758                    }
8759                }
8760            }
8761        }
8762        return new ParceledListSlice<android.content.UriPermission>(result);
8763    }
8764
8765    @Override
8766    public void clearGrantedUriPermissions(String packageName, int userId) {
8767        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8768                "clearGrantedUriPermissions");
8769        removeUriPermissionsForPackageLocked(packageName, userId, true);
8770    }
8771
8772    @Override
8773    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8774        synchronized (this) {
8775            ProcessRecord app =
8776                who != null ? getRecordForAppLocked(who) : null;
8777            if (app == null) return;
8778
8779            Message msg = Message.obtain();
8780            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8781            msg.obj = app;
8782            msg.arg1 = waiting ? 1 : 0;
8783            mUiHandler.sendMessage(msg);
8784        }
8785    }
8786
8787    @Override
8788    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8789        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8790        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8791        outInfo.availMem = Process.getFreeMemory();
8792        outInfo.totalMem = Process.getTotalMemory();
8793        outInfo.threshold = homeAppMem;
8794        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8795        outInfo.hiddenAppThreshold = cachedAppMem;
8796        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8797                ProcessList.SERVICE_ADJ);
8798        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8799                ProcessList.VISIBLE_APP_ADJ);
8800        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8801                ProcessList.FOREGROUND_APP_ADJ);
8802    }
8803
8804    // =========================================================
8805    // TASK MANAGEMENT
8806    // =========================================================
8807
8808    @Override
8809    public List<IAppTask> getAppTasks(String callingPackage) {
8810        int callingUid = Binder.getCallingUid();
8811        long ident = Binder.clearCallingIdentity();
8812
8813        synchronized(this) {
8814            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8815            try {
8816                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8817
8818                final int N = mRecentTasks.size();
8819                for (int i = 0; i < N; i++) {
8820                    TaskRecord tr = mRecentTasks.get(i);
8821                    // Skip tasks that do not match the caller.  We don't need to verify
8822                    // callingPackage, because we are also limiting to callingUid and know
8823                    // that will limit to the correct security sandbox.
8824                    if (tr.effectiveUid != callingUid) {
8825                        continue;
8826                    }
8827                    Intent intent = tr.getBaseIntent();
8828                    if (intent == null ||
8829                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8830                        continue;
8831                    }
8832                    ActivityManager.RecentTaskInfo taskInfo =
8833                            createRecentTaskInfoFromTaskRecord(tr);
8834                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8835                    list.add(taskImpl);
8836                }
8837            } finally {
8838                Binder.restoreCallingIdentity(ident);
8839            }
8840            return list;
8841        }
8842    }
8843
8844    @Override
8845    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8846        final int callingUid = Binder.getCallingUid();
8847        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8848
8849        synchronized(this) {
8850            if (DEBUG_ALL) Slog.v(
8851                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8852
8853            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8854                    callingUid);
8855
8856            // TODO: Improve with MRU list from all ActivityStacks.
8857            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8858        }
8859
8860        return list;
8861    }
8862
8863    /**
8864     * Creates a new RecentTaskInfo from a TaskRecord.
8865     */
8866    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8867        // Update the task description to reflect any changes in the task stack
8868        tr.updateTaskDescription();
8869
8870        // Compose the recent task info
8871        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8872        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8873        rti.persistentId = tr.taskId;
8874        rti.baseIntent = new Intent(tr.getBaseIntent());
8875        rti.origActivity = tr.origActivity;
8876        rti.realActivity = tr.realActivity;
8877        rti.description = tr.lastDescription;
8878        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8879        rti.userId = tr.userId;
8880        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8881        rti.firstActiveTime = tr.firstActiveTime;
8882        rti.lastActiveTime = tr.lastActiveTime;
8883        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8884        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8885        rti.numActivities = 0;
8886        if (tr.mBounds != null) {
8887            rti.bounds = new Rect(tr.mBounds);
8888        }
8889        rti.isDockable = tr.canGoInDockedStack();
8890        rti.resizeMode = tr.mResizeMode;
8891
8892        ActivityRecord base = null;
8893        ActivityRecord top = null;
8894        ActivityRecord tmp;
8895
8896        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8897            tmp = tr.mActivities.get(i);
8898            if (tmp.finishing) {
8899                continue;
8900            }
8901            base = tmp;
8902            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8903                top = base;
8904            }
8905            rti.numActivities++;
8906        }
8907
8908        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8909        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8910
8911        return rti;
8912    }
8913
8914    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8915        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8916                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8917        if (!allowed) {
8918            if (checkPermission(android.Manifest.permission.GET_TASKS,
8919                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8920                // Temporary compatibility: some existing apps on the system image may
8921                // still be requesting the old permission and not switched to the new
8922                // one; if so, we'll still allow them full access.  This means we need
8923                // to see if they are holding the old permission and are a system app.
8924                try {
8925                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8926                        allowed = true;
8927                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8928                                + " is using old GET_TASKS but privileged; allowing");
8929                    }
8930                } catch (RemoteException e) {
8931                }
8932            }
8933        }
8934        if (!allowed) {
8935            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8936                    + " does not hold REAL_GET_TASKS; limiting output");
8937        }
8938        return allowed;
8939    }
8940
8941    @Override
8942    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8943        final int callingUid = Binder.getCallingUid();
8944        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8945                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8946
8947        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8948        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8949        synchronized (this) {
8950            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8951                    callingUid);
8952            final boolean detailed = checkCallingPermission(
8953                    android.Manifest.permission.GET_DETAILED_TASKS)
8954                    == PackageManager.PERMISSION_GRANTED;
8955
8956            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8957                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8958                return Collections.emptyList();
8959            }
8960            mRecentTasks.loadUserRecentsLocked(userId);
8961
8962            final int recentsCount = mRecentTasks.size();
8963            ArrayList<ActivityManager.RecentTaskInfo> res =
8964                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8965
8966            final Set<Integer> includedUsers;
8967            if (includeProfiles) {
8968                includedUsers = mUserController.getProfileIds(userId);
8969            } else {
8970                includedUsers = new HashSet<>();
8971            }
8972            includedUsers.add(Integer.valueOf(userId));
8973
8974            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8975                TaskRecord tr = mRecentTasks.get(i);
8976                // Only add calling user or related users recent tasks
8977                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8978                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8979                    continue;
8980                }
8981
8982                if (tr.realActivitySuspended) {
8983                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8984                    continue;
8985                }
8986
8987                // Return the entry if desired by the caller.  We always return
8988                // the first entry, because callers always expect this to be the
8989                // foreground app.  We may filter others if the caller has
8990                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8991                // we should exclude the entry.
8992
8993                if (i == 0
8994                        || withExcluded
8995                        || (tr.intent == null)
8996                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8997                                == 0)) {
8998                    if (!allowed) {
8999                        // If the caller doesn't have the GET_TASKS permission, then only
9000                        // allow them to see a small subset of tasks -- their own and home.
9001                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9002                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9003                            continue;
9004                        }
9005                    }
9006                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9007                        if (tr.stack != null && tr.stack.isHomeStack()) {
9008                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9009                                    "Skipping, home stack task: " + tr);
9010                            continue;
9011                        }
9012                    }
9013                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9014                        final ActivityStack stack = tr.stack;
9015                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9016                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9017                                    "Skipping, top task in docked stack: " + tr);
9018                            continue;
9019                        }
9020                    }
9021                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9022                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9023                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9024                                    "Skipping, pinned stack task: " + tr);
9025                            continue;
9026                        }
9027                    }
9028                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9029                        // Don't include auto remove tasks that are finished or finishing.
9030                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9031                                "Skipping, auto-remove without activity: " + tr);
9032                        continue;
9033                    }
9034                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9035                            && !tr.isAvailable) {
9036                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9037                                "Skipping, unavail real act: " + tr);
9038                        continue;
9039                    }
9040
9041                    if (!tr.mUserSetupComplete) {
9042                        // Don't include task launched while user is not done setting-up.
9043                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9044                                "Skipping, user setup not complete: " + tr);
9045                        continue;
9046                    }
9047
9048                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9049                    if (!detailed) {
9050                        rti.baseIntent.replaceExtras((Bundle)null);
9051                    }
9052
9053                    res.add(rti);
9054                    maxNum--;
9055                }
9056            }
9057            return res;
9058        }
9059    }
9060
9061    @Override
9062    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9063        synchronized (this) {
9064            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9065                    "getTaskThumbnail()");
9066            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9067                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9068            if (tr != null) {
9069                return tr.getTaskThumbnailLocked();
9070            }
9071        }
9072        return null;
9073    }
9074
9075    @Override
9076    public int addAppTask(IBinder activityToken, Intent intent,
9077            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9078        final int callingUid = Binder.getCallingUid();
9079        final long callingIdent = Binder.clearCallingIdentity();
9080
9081        try {
9082            synchronized (this) {
9083                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9084                if (r == null) {
9085                    throw new IllegalArgumentException("Activity does not exist; token="
9086                            + activityToken);
9087                }
9088                ComponentName comp = intent.getComponent();
9089                if (comp == null) {
9090                    throw new IllegalArgumentException("Intent " + intent
9091                            + " must specify explicit component");
9092                }
9093                if (thumbnail.getWidth() != mThumbnailWidth
9094                        || thumbnail.getHeight() != mThumbnailHeight) {
9095                    throw new IllegalArgumentException("Bad thumbnail size: got "
9096                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9097                            + mThumbnailWidth + "x" + mThumbnailHeight);
9098                }
9099                if (intent.getSelector() != null) {
9100                    intent.setSelector(null);
9101                }
9102                if (intent.getSourceBounds() != null) {
9103                    intent.setSourceBounds(null);
9104                }
9105                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9106                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9107                        // The caller has added this as an auto-remove task...  that makes no
9108                        // sense, so turn off auto-remove.
9109                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9110                    }
9111                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9112                    // Must be a new task.
9113                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9114                }
9115                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9116                    mLastAddedTaskActivity = null;
9117                }
9118                ActivityInfo ainfo = mLastAddedTaskActivity;
9119                if (ainfo == null) {
9120                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9121                            comp, 0, UserHandle.getUserId(callingUid));
9122                    if (ainfo.applicationInfo.uid != callingUid) {
9123                        throw new SecurityException(
9124                                "Can't add task for another application: target uid="
9125                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9126                    }
9127                }
9128
9129                // Use the full screen as the context for the task thumbnail
9130                final Point displaySize = new Point();
9131                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9132                r.task.stack.getDisplaySize(displaySize);
9133                thumbnailInfo.taskWidth = displaySize.x;
9134                thumbnailInfo.taskHeight = displaySize.y;
9135                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9136
9137                TaskRecord task = new TaskRecord(this,
9138                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9139                        ainfo, intent, description, thumbnailInfo);
9140
9141                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9142                if (trimIdx >= 0) {
9143                    // If this would have caused a trim, then we'll abort because that
9144                    // means it would be added at the end of the list but then just removed.
9145                    return INVALID_TASK_ID;
9146                }
9147
9148                final int N = mRecentTasks.size();
9149                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9150                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9151                    tr.removedFromRecents();
9152                }
9153
9154                task.inRecents = true;
9155                mRecentTasks.add(task);
9156                r.task.stack.addTask(task, false, "addAppTask");
9157
9158                task.setLastThumbnailLocked(thumbnail);
9159                task.freeLastThumbnail();
9160
9161                return task.taskId;
9162            }
9163        } finally {
9164            Binder.restoreCallingIdentity(callingIdent);
9165        }
9166    }
9167
9168    @Override
9169    public Point getAppTaskThumbnailSize() {
9170        synchronized (this) {
9171            return new Point(mThumbnailWidth,  mThumbnailHeight);
9172        }
9173    }
9174
9175    @Override
9176    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9177        synchronized (this) {
9178            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9179            if (r != null) {
9180                r.setTaskDescription(td);
9181                r.task.updateTaskDescription();
9182            }
9183        }
9184    }
9185
9186    @Override
9187    public void setTaskResizeable(int taskId, int resizeableMode) {
9188        synchronized (this) {
9189            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9190                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9191            if (task == null) {
9192                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9193                return;
9194            }
9195            if (task.mResizeMode != resizeableMode) {
9196                task.mResizeMode = resizeableMode;
9197                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9198                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9199                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9200            }
9201        }
9202    }
9203
9204    @Override
9205    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9206        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9207        long ident = Binder.clearCallingIdentity();
9208        try {
9209            synchronized (this) {
9210                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9211                if (task == null) {
9212                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9213                    return;
9214                }
9215                int stackId = task.stack.mStackId;
9216                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9217                // in crop windows resize mode or if the task size is affected by the docked stack
9218                // changing size. No need to update configuration.
9219                if (bounds != null && task.inCropWindowsResizeMode()
9220                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9221                    mWindowManager.scrollTask(task.taskId, bounds);
9222                    return;
9223                }
9224
9225                // Place the task in the right stack if it isn't there already based on
9226                // the requested bounds.
9227                // The stack transition logic is:
9228                // - a null bounds on a freeform task moves that task to fullscreen
9229                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9230                //   that task to freeform
9231                // - otherwise the task is not moved
9232                if (!StackId.isTaskResizeAllowed(stackId)) {
9233                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9234                }
9235                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9236                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9237                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9238                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9239                }
9240                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9241                if (stackId != task.stack.mStackId) {
9242                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9243                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9244                    preserveWindow = false;
9245                }
9246
9247                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9248                        false /* deferResume */);
9249            }
9250        } finally {
9251            Binder.restoreCallingIdentity(ident);
9252        }
9253    }
9254
9255    @Override
9256    public Rect getTaskBounds(int taskId) {
9257        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9258        long ident = Binder.clearCallingIdentity();
9259        Rect rect = new Rect();
9260        try {
9261            synchronized (this) {
9262                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9263                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9264                if (task == null) {
9265                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9266                    return rect;
9267                }
9268                if (task.stack != null) {
9269                    // Return the bounds from window manager since it will be adjusted for various
9270                    // things like the presense of a docked stack for tasks that aren't resizeable.
9271                    mWindowManager.getTaskBounds(task.taskId, rect);
9272                } else {
9273                    // Task isn't in window manager yet since it isn't associated with a stack.
9274                    // Return the persist value from activity manager
9275                    if (task.mBounds != null) {
9276                        rect.set(task.mBounds);
9277                    } else if (task.mLastNonFullscreenBounds != null) {
9278                        rect.set(task.mLastNonFullscreenBounds);
9279                    }
9280                }
9281            }
9282        } finally {
9283            Binder.restoreCallingIdentity(ident);
9284        }
9285        return rect;
9286    }
9287
9288    @Override
9289    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9290        if (userId != UserHandle.getCallingUserId()) {
9291            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9292                    "getTaskDescriptionIcon");
9293        }
9294        final File passedIconFile = new File(filePath);
9295        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9296                passedIconFile.getName());
9297        if (!legitIconFile.getPath().equals(filePath)
9298                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9299            throw new IllegalArgumentException("Bad file path: " + filePath
9300                    + " passed for userId " + userId);
9301        }
9302        return mRecentTasks.getTaskDescriptionIcon(filePath);
9303    }
9304
9305    @Override
9306    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9307            throws RemoteException {
9308        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9309                opts.getCustomInPlaceResId() == 0) {
9310            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9311                    "with valid animation");
9312        }
9313        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9314        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9315                opts.getCustomInPlaceResId());
9316        mWindowManager.executeAppTransition();
9317    }
9318
9319    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9320            boolean removeFromRecents) {
9321        if (removeFromRecents) {
9322            mRecentTasks.remove(tr);
9323            tr.removedFromRecents();
9324        }
9325        ComponentName component = tr.getBaseIntent().getComponent();
9326        if (component == null) {
9327            Slog.w(TAG, "No component for base intent of task: " + tr);
9328            return;
9329        }
9330
9331        // Find any running services associated with this app and stop if needed.
9332        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9333
9334        if (!killProcess) {
9335            return;
9336        }
9337
9338        // Determine if the process(es) for this task should be killed.
9339        final String pkg = component.getPackageName();
9340        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9341        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9342        for (int i = 0; i < pmap.size(); i++) {
9343
9344            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9345            for (int j = 0; j < uids.size(); j++) {
9346                ProcessRecord proc = uids.valueAt(j);
9347                if (proc.userId != tr.userId) {
9348                    // Don't kill process for a different user.
9349                    continue;
9350                }
9351                if (proc == mHomeProcess) {
9352                    // Don't kill the home process along with tasks from the same package.
9353                    continue;
9354                }
9355                if (!proc.pkgList.containsKey(pkg)) {
9356                    // Don't kill process that is not associated with this task.
9357                    continue;
9358                }
9359
9360                for (int k = 0; k < proc.activities.size(); k++) {
9361                    TaskRecord otherTask = proc.activities.get(k).task;
9362                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9363                        // Don't kill process(es) that has an activity in a different task that is
9364                        // also in recents.
9365                        return;
9366                    }
9367                }
9368
9369                if (proc.foregroundServices) {
9370                    // Don't kill process(es) with foreground service.
9371                    return;
9372                }
9373
9374                // Add process to kill list.
9375                procsToKill.add(proc);
9376            }
9377        }
9378
9379        // Kill the running processes.
9380        for (int i = 0; i < procsToKill.size(); i++) {
9381            ProcessRecord pr = procsToKill.get(i);
9382            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9383                    && pr.curReceiver == null) {
9384                pr.kill("remove task", true);
9385            } else {
9386                // We delay killing processes that are not in the background or running a receiver.
9387                pr.waitingToKill = "remove task";
9388            }
9389        }
9390    }
9391
9392    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9393        // Remove all tasks with activities in the specified package from the list of recent tasks
9394        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9395            TaskRecord tr = mRecentTasks.get(i);
9396            if (tr.userId != userId) continue;
9397
9398            ComponentName cn = tr.intent.getComponent();
9399            if (cn != null && cn.getPackageName().equals(packageName)) {
9400                // If the package name matches, remove the task.
9401                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9402            }
9403        }
9404    }
9405
9406    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9407            int userId) {
9408
9409        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9410            TaskRecord tr = mRecentTasks.get(i);
9411            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9412                continue;
9413            }
9414
9415            ComponentName cn = tr.intent.getComponent();
9416            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9417                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9418            if (sameComponent) {
9419                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9420            }
9421        }
9422    }
9423
9424    /**
9425     * Removes the task with the specified task id.
9426     *
9427     * @param taskId Identifier of the task to be removed.
9428     * @param killProcess Kill any process associated with the task if possible.
9429     * @param removeFromRecents Whether to also remove the task from recents.
9430     * @return Returns true if the given task was found and removed.
9431     */
9432    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9433            boolean removeFromRecents) {
9434        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9435                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9436        if (tr != null) {
9437            tr.removeTaskActivitiesLocked();
9438            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9439            if (tr.isPersistable) {
9440                notifyTaskPersisterLocked(null, true);
9441            }
9442            return true;
9443        }
9444        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9445        return false;
9446    }
9447
9448    @Override
9449    public void removeStack(int stackId) {
9450        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9451        if (stackId == HOME_STACK_ID) {
9452            throw new IllegalArgumentException("Removing home stack is not allowed.");
9453        }
9454
9455        synchronized (this) {
9456            final long ident = Binder.clearCallingIdentity();
9457            try {
9458                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9459                if (stack == null) {
9460                    return;
9461                }
9462                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9463                for (int i = tasks.size() - 1; i >= 0; i--) {
9464                    removeTaskByIdLocked(
9465                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9466                }
9467            } finally {
9468                Binder.restoreCallingIdentity(ident);
9469            }
9470        }
9471    }
9472
9473    @Override
9474    public boolean removeTask(int taskId) {
9475        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9476        synchronized (this) {
9477            final long ident = Binder.clearCallingIdentity();
9478            try {
9479                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9480            } finally {
9481                Binder.restoreCallingIdentity(ident);
9482            }
9483        }
9484    }
9485
9486    /**
9487     * TODO: Add mController hook
9488     */
9489    @Override
9490    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9491        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9492
9493        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9494        synchronized(this) {
9495            moveTaskToFrontLocked(taskId, flags, bOptions);
9496        }
9497    }
9498
9499    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9500        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9501
9502        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9503                Binder.getCallingUid(), -1, -1, "Task to front")) {
9504            ActivityOptions.abort(options);
9505            return;
9506        }
9507        final long origId = Binder.clearCallingIdentity();
9508        try {
9509            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9510            if (task == null) {
9511                Slog.d(TAG, "Could not find task for id: "+ taskId);
9512                return;
9513            }
9514            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9515                mStackSupervisor.showLockTaskToast();
9516                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9517                return;
9518            }
9519            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9520            if (prev != null && prev.isRecentsActivity()) {
9521                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9522            }
9523            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9524                    false /* forceNonResizable */);
9525        } finally {
9526            Binder.restoreCallingIdentity(origId);
9527        }
9528        ActivityOptions.abort(options);
9529    }
9530
9531    /**
9532     * Moves an activity, and all of the other activities within the same task, to the bottom
9533     * of the history stack.  The activity's order within the task is unchanged.
9534     *
9535     * @param token A reference to the activity we wish to move
9536     * @param nonRoot If false then this only works if the activity is the root
9537     *                of a task; if true it will work for any activity in a task.
9538     * @return Returns true if the move completed, false if not.
9539     */
9540    @Override
9541    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9542        enforceNotIsolatedCaller("moveActivityTaskToBack");
9543        synchronized(this) {
9544            final long origId = Binder.clearCallingIdentity();
9545            try {
9546                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9547                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9548                if (task != null) {
9549                    if (mStackSupervisor.isLockedTask(task)) {
9550                        mStackSupervisor.showLockTaskToast();
9551                        return false;
9552                    }
9553                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9554                }
9555            } finally {
9556                Binder.restoreCallingIdentity(origId);
9557            }
9558        }
9559        return false;
9560    }
9561
9562    @Override
9563    public void moveTaskBackwards(int task) {
9564        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9565                "moveTaskBackwards()");
9566
9567        synchronized(this) {
9568            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9569                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9570                return;
9571            }
9572            final long origId = Binder.clearCallingIdentity();
9573            moveTaskBackwardsLocked(task);
9574            Binder.restoreCallingIdentity(origId);
9575        }
9576    }
9577
9578    private final void moveTaskBackwardsLocked(int task) {
9579        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9580    }
9581
9582    @Override
9583    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9584            IActivityContainerCallback callback) throws RemoteException {
9585        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9586        synchronized (this) {
9587            if (parentActivityToken == null) {
9588                throw new IllegalArgumentException("parent token must not be null");
9589            }
9590            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9591            if (r == null) {
9592                return null;
9593            }
9594            if (callback == null) {
9595                throw new IllegalArgumentException("callback must not be null");
9596            }
9597            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9598        }
9599    }
9600
9601    @Override
9602    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9603        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9604        synchronized (this) {
9605            mStackSupervisor.deleteActivityContainer(container);
9606        }
9607    }
9608
9609    @Override
9610    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9611        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9612        synchronized (this) {
9613            final int stackId = mStackSupervisor.getNextStackId();
9614            final ActivityStack stack =
9615                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9616            if (stack == null) {
9617                return null;
9618            }
9619            return stack.mActivityContainer;
9620        }
9621    }
9622
9623    @Override
9624    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9625        synchronized (this) {
9626            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9627            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9628                return stack.mActivityContainer.getDisplayId();
9629            }
9630            return Display.DEFAULT_DISPLAY;
9631        }
9632    }
9633
9634    @Override
9635    public int getActivityStackId(IBinder token) throws RemoteException {
9636        synchronized (this) {
9637            ActivityStack stack = ActivityRecord.getStackLocked(token);
9638            if (stack == null) {
9639                return INVALID_STACK_ID;
9640            }
9641            return stack.mStackId;
9642        }
9643    }
9644
9645    @Override
9646    public void exitFreeformMode(IBinder token) throws RemoteException {
9647        synchronized (this) {
9648            long ident = Binder.clearCallingIdentity();
9649            try {
9650                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9651                if (r == null) {
9652                    throw new IllegalArgumentException(
9653                            "exitFreeformMode: No activity record matching token=" + token);
9654                }
9655                final ActivityStack stack = r.getStackLocked(token);
9656                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9657                    throw new IllegalStateException(
9658                            "exitFreeformMode: You can only go fullscreen from freeform.");
9659                }
9660                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9661                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9662                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9663            } finally {
9664                Binder.restoreCallingIdentity(ident);
9665            }
9666        }
9667    }
9668
9669    @Override
9670    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9671        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9672        if (stackId == HOME_STACK_ID) {
9673            throw new IllegalArgumentException(
9674                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9675        }
9676        synchronized (this) {
9677            long ident = Binder.clearCallingIdentity();
9678            try {
9679                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9680                        + " to stackId=" + stackId + " toTop=" + toTop);
9681                if (stackId == DOCKED_STACK_ID) {
9682                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9683                            null /* initialBounds */);
9684                }
9685                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9686                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9687                if (result && stackId == DOCKED_STACK_ID) {
9688                    // If task moved to docked stack - show recents if needed.
9689                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9690                            "moveTaskToDockedStack");
9691                }
9692            } finally {
9693                Binder.restoreCallingIdentity(ident);
9694            }
9695        }
9696    }
9697
9698    @Override
9699    public void swapDockedAndFullscreenStack() throws RemoteException {
9700        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9701        synchronized (this) {
9702            long ident = Binder.clearCallingIdentity();
9703            try {
9704                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9705                        FULLSCREEN_WORKSPACE_STACK_ID);
9706                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9707                        : null;
9708                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9709                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9710                        : null;
9711                if (topTask == null || tasks == null || tasks.size() == 0) {
9712                    Slog.w(TAG,
9713                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9714                    return;
9715                }
9716
9717                // TODO: App transition
9718                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9719
9720                // Defer the resume so resume/pausing while moving stacks is dangerous.
9721                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9722                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9723                        ANIMATE, true /* deferResume */);
9724                final int size = tasks.size();
9725                for (int i = 0; i < size; i++) {
9726                    final int id = tasks.get(i).taskId;
9727                    if (id == topTask.taskId) {
9728                        continue;
9729                    }
9730                    mStackSupervisor.moveTaskToStackLocked(id,
9731                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9732                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9733                }
9734
9735                // Because we deferred the resume, to avoid conflicts with stack switches while
9736                // resuming, we need to do it after all the tasks are moved.
9737                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9738                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9739
9740                mWindowManager.executeAppTransition();
9741            } finally {
9742                Binder.restoreCallingIdentity(ident);
9743            }
9744        }
9745    }
9746
9747    /**
9748     * Moves the input task to the docked stack.
9749     *
9750     * @param taskId Id of task to move.
9751     * @param createMode The mode the docked stack should be created in if it doesn't exist
9752     *                   already. See
9753     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9754     *                   and
9755     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9756     * @param toTop If the task and stack should be moved to the top.
9757     * @param animate Whether we should play an animation for the moving the task
9758     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9759     *                      docked stack. Pass {@code null} to use default bounds.
9760     */
9761    @Override
9762    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9763            Rect initialBounds, boolean moveHomeStackFront) {
9764        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9765        synchronized (this) {
9766            long ident = Binder.clearCallingIdentity();
9767            try {
9768                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9769                        + " to createMode=" + createMode + " toTop=" + toTop);
9770                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9771                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9772                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9773                        animate, DEFER_RESUME);
9774                if (moved) {
9775                    if (moveHomeStackFront) {
9776                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9777                    }
9778                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9779                }
9780                return moved;
9781            } finally {
9782                Binder.restoreCallingIdentity(ident);
9783            }
9784        }
9785    }
9786
9787    /**
9788     * Moves the top activity in the input stackId to the pinned stack.
9789     *
9790     * @param stackId Id of stack to move the top activity to pinned stack.
9791     * @param bounds Bounds to use for pinned stack.
9792     *
9793     * @return True if the top activity of the input stack was successfully moved to the pinned
9794     *          stack.
9795     */
9796    @Override
9797    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9798        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9799        synchronized (this) {
9800            if (!mSupportsPictureInPicture) {
9801                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9802                        + "Device doesn't support picture-in-pciture mode");
9803            }
9804
9805            long ident = Binder.clearCallingIdentity();
9806            try {
9807                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9808            } finally {
9809                Binder.restoreCallingIdentity(ident);
9810            }
9811        }
9812    }
9813
9814    @Override
9815    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9816            boolean preserveWindows, boolean animate, int animationDuration) {
9817        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9818        long ident = Binder.clearCallingIdentity();
9819        try {
9820            synchronized (this) {
9821                if (animate) {
9822                    if (stackId == PINNED_STACK_ID) {
9823                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9824                    } else {
9825                        throw new IllegalArgumentException("Stack: " + stackId
9826                                + " doesn't support animated resize.");
9827                    }
9828                } else {
9829                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9830                            null /* tempTaskInsetBounds */, preserveWindows,
9831                            allowResizeInDockedMode, !DEFER_RESUME);
9832                }
9833            }
9834        } finally {
9835            Binder.restoreCallingIdentity(ident);
9836        }
9837    }
9838
9839    @Override
9840    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9841            Rect tempDockedTaskInsetBounds,
9842            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9843        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9844                "resizeDockedStack()");
9845        long ident = Binder.clearCallingIdentity();
9846        try {
9847            synchronized (this) {
9848                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9849                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9850                        PRESERVE_WINDOWS);
9851            }
9852        } finally {
9853            Binder.restoreCallingIdentity(ident);
9854        }
9855    }
9856
9857    @Override
9858    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9859        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9860                "resizePinnedStack()");
9861        final long ident = Binder.clearCallingIdentity();
9862        try {
9863            synchronized (this) {
9864                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9865            }
9866        } finally {
9867            Binder.restoreCallingIdentity(ident);
9868        }
9869    }
9870
9871    @Override
9872    public void positionTaskInStack(int taskId, int stackId, int position) {
9873        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9874        if (stackId == HOME_STACK_ID) {
9875            throw new IllegalArgumentException(
9876                    "positionTaskInStack: Attempt to change the position of task "
9877                    + taskId + " in/to home stack");
9878        }
9879        synchronized (this) {
9880            long ident = Binder.clearCallingIdentity();
9881            try {
9882                if (DEBUG_STACK) Slog.d(TAG_STACK,
9883                        "positionTaskInStack: positioning task=" + taskId
9884                        + " in stackId=" + stackId + " at position=" + position);
9885                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9886            } finally {
9887                Binder.restoreCallingIdentity(ident);
9888            }
9889        }
9890    }
9891
9892    @Override
9893    public List<StackInfo> getAllStackInfos() {
9894        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9895        long ident = Binder.clearCallingIdentity();
9896        try {
9897            synchronized (this) {
9898                return mStackSupervisor.getAllStackInfosLocked();
9899            }
9900        } finally {
9901            Binder.restoreCallingIdentity(ident);
9902        }
9903    }
9904
9905    @Override
9906    public StackInfo getStackInfo(int stackId) {
9907        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9908        long ident = Binder.clearCallingIdentity();
9909        try {
9910            synchronized (this) {
9911                return mStackSupervisor.getStackInfoLocked(stackId);
9912            }
9913        } finally {
9914            Binder.restoreCallingIdentity(ident);
9915        }
9916    }
9917
9918    @Override
9919    public boolean isInHomeStack(int taskId) {
9920        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9921        long ident = Binder.clearCallingIdentity();
9922        try {
9923            synchronized (this) {
9924                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9925                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9926                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9927            }
9928        } finally {
9929            Binder.restoreCallingIdentity(ident);
9930        }
9931    }
9932
9933    @Override
9934    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9935        synchronized(this) {
9936            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9937        }
9938    }
9939
9940    @Override
9941    public void updateDeviceOwner(String packageName) {
9942        final int callingUid = Binder.getCallingUid();
9943        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9944            throw new SecurityException("updateDeviceOwner called from non-system process");
9945        }
9946        synchronized (this) {
9947            mDeviceOwnerName = packageName;
9948        }
9949    }
9950
9951    @Override
9952    public void updateLockTaskPackages(int userId, String[] packages) {
9953        final int callingUid = Binder.getCallingUid();
9954        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9955            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9956                    "updateLockTaskPackages()");
9957        }
9958        synchronized (this) {
9959            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9960                    Arrays.toString(packages));
9961            mLockTaskPackages.put(userId, packages);
9962            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9963        }
9964    }
9965
9966
9967    void startLockTaskModeLocked(TaskRecord task) {
9968        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9969        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9970            return;
9971        }
9972
9973        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9974        // is initiated by system after the pinning request was shown and locked mode is initiated
9975        // by an authorized app directly
9976        final int callingUid = Binder.getCallingUid();
9977        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9978        long ident = Binder.clearCallingIdentity();
9979        try {
9980            if (!isSystemInitiated) {
9981                task.mLockTaskUid = callingUid;
9982                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9983                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9984                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9985                    StatusBarManagerInternal statusBarManager =
9986                            LocalServices.getService(StatusBarManagerInternal.class);
9987                    if (statusBarManager != null) {
9988                        statusBarManager.showScreenPinningRequest(task.taskId);
9989                    }
9990                    return;
9991                }
9992
9993                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9994                if (stack == null || task != stack.topTask()) {
9995                    throw new IllegalArgumentException("Invalid task, not in foreground");
9996                }
9997            }
9998            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9999                    "Locking fully");
10000            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10001                    ActivityManager.LOCK_TASK_MODE_PINNED :
10002                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10003                    "startLockTask", true);
10004        } finally {
10005            Binder.restoreCallingIdentity(ident);
10006        }
10007    }
10008
10009    @Override
10010    public void startLockTaskMode(int taskId) {
10011        synchronized (this) {
10012            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10013            if (task != null) {
10014                startLockTaskModeLocked(task);
10015            }
10016        }
10017    }
10018
10019    @Override
10020    public void startLockTaskMode(IBinder token) {
10021        synchronized (this) {
10022            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10023            if (r == null) {
10024                return;
10025            }
10026            final TaskRecord task = r.task;
10027            if (task != null) {
10028                startLockTaskModeLocked(task);
10029            }
10030        }
10031    }
10032
10033    @Override
10034    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10035        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10036        // This makes inner call to look as if it was initiated by system.
10037        long ident = Binder.clearCallingIdentity();
10038        try {
10039            synchronized (this) {
10040                startLockTaskMode(taskId);
10041            }
10042        } finally {
10043            Binder.restoreCallingIdentity(ident);
10044        }
10045    }
10046
10047    @Override
10048    public void stopLockTaskMode() {
10049        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10050        if (lockTask == null) {
10051            // Our work here is done.
10052            return;
10053        }
10054
10055        final int callingUid = Binder.getCallingUid();
10056        final int lockTaskUid = lockTask.mLockTaskUid;
10057        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10058        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10059            // Done.
10060            return;
10061        } else {
10062            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10063            // It is possible lockTaskMode was started by the system process because
10064            // android:lockTaskMode is set to a locking value in the application manifest
10065            // instead of the app calling startLockTaskMode. In this case
10066            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10067            // {@link TaskRecord.effectiveUid} instead. Also caller with
10068            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10069            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10070                    && callingUid != lockTaskUid
10071                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10072                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10073                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10074            }
10075        }
10076        long ident = Binder.clearCallingIdentity();
10077        try {
10078            Log.d(TAG, "stopLockTaskMode");
10079            // Stop lock task
10080            synchronized (this) {
10081                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10082                        "stopLockTask", true);
10083            }
10084        } finally {
10085            Binder.restoreCallingIdentity(ident);
10086        }
10087    }
10088
10089    /**
10090     * This API should be called by SystemUI only when user perform certain action to dismiss
10091     * lock task mode. We should only dismiss pinned lock task mode in this case.
10092     */
10093    @Override
10094    public void stopSystemLockTaskMode() throws RemoteException {
10095        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10096            stopLockTaskMode();
10097        } else {
10098            mStackSupervisor.showLockTaskToast();
10099        }
10100    }
10101
10102    @Override
10103    public boolean isInLockTaskMode() {
10104        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10105    }
10106
10107    @Override
10108    public int getLockTaskModeState() {
10109        synchronized (this) {
10110            return mStackSupervisor.getLockTaskModeState();
10111        }
10112    }
10113
10114    @Override
10115    public void showLockTaskEscapeMessage(IBinder token) {
10116        synchronized (this) {
10117            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10118            if (r == null) {
10119                return;
10120            }
10121            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10122        }
10123    }
10124
10125    // =========================================================
10126    // CONTENT PROVIDERS
10127    // =========================================================
10128
10129    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10130        List<ProviderInfo> providers = null;
10131        try {
10132            providers = AppGlobals.getPackageManager()
10133                    .queryContentProviders(app.processName, app.uid,
10134                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10135                                    | MATCH_DEBUG_TRIAGED_MISSING)
10136                    .getList();
10137        } catch (RemoteException ex) {
10138        }
10139        if (DEBUG_MU) Slog.v(TAG_MU,
10140                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10141        int userId = app.userId;
10142        if (providers != null) {
10143            int N = providers.size();
10144            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10145            for (int i=0; i<N; i++) {
10146                ProviderInfo cpi =
10147                    (ProviderInfo)providers.get(i);
10148                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10149                        cpi.name, cpi.flags);
10150                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10151                    // This is a singleton provider, but a user besides the
10152                    // default user is asking to initialize a process it runs
10153                    // in...  well, no, it doesn't actually run in this process,
10154                    // it runs in the process of the default user.  Get rid of it.
10155                    providers.remove(i);
10156                    N--;
10157                    i--;
10158                    continue;
10159                }
10160
10161                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10162                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10163                if (cpr == null) {
10164                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10165                    mProviderMap.putProviderByClass(comp, cpr);
10166                }
10167                if (DEBUG_MU) Slog.v(TAG_MU,
10168                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10169                app.pubProviders.put(cpi.name, cpr);
10170                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10171                    // Don't add this if it is a platform component that is marked
10172                    // to run in multiple processes, because this is actually
10173                    // part of the framework so doesn't make sense to track as a
10174                    // separate apk in the process.
10175                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10176                            mProcessStats);
10177                }
10178                notifyPackageUse(cpi.applicationInfo.packageName,
10179                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10180            }
10181        }
10182        return providers;
10183    }
10184
10185    /**
10186     * Check if {@link ProcessRecord} has a possible chance at accessing the
10187     * given {@link ProviderInfo}. Final permission checking is always done
10188     * in {@link ContentProvider}.
10189     */
10190    private final String checkContentProviderPermissionLocked(
10191            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10192        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10193        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10194        boolean checkedGrants = false;
10195        if (checkUser) {
10196            // Looking for cross-user grants before enforcing the typical cross-users permissions
10197            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10198            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10199                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10200                    return null;
10201                }
10202                checkedGrants = true;
10203            }
10204            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10205                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10206            if (userId != tmpTargetUserId) {
10207                // When we actually went to determine the final targer user ID, this ended
10208                // up different than our initial check for the authority.  This is because
10209                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10210                // SELF.  So we need to re-check the grants again.
10211                checkedGrants = false;
10212            }
10213        }
10214        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10215                cpi.applicationInfo.uid, cpi.exported)
10216                == PackageManager.PERMISSION_GRANTED) {
10217            return null;
10218        }
10219        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10220                cpi.applicationInfo.uid, cpi.exported)
10221                == PackageManager.PERMISSION_GRANTED) {
10222            return null;
10223        }
10224
10225        PathPermission[] pps = cpi.pathPermissions;
10226        if (pps != null) {
10227            int i = pps.length;
10228            while (i > 0) {
10229                i--;
10230                PathPermission pp = pps[i];
10231                String pprperm = pp.getReadPermission();
10232                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10233                        cpi.applicationInfo.uid, cpi.exported)
10234                        == PackageManager.PERMISSION_GRANTED) {
10235                    return null;
10236                }
10237                String ppwperm = pp.getWritePermission();
10238                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10239                        cpi.applicationInfo.uid, cpi.exported)
10240                        == PackageManager.PERMISSION_GRANTED) {
10241                    return null;
10242                }
10243            }
10244        }
10245        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10246            return null;
10247        }
10248
10249        String msg;
10250        if (!cpi.exported) {
10251            msg = "Permission Denial: opening provider " + cpi.name
10252                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10253                    + ", uid=" + callingUid + ") that is not exported from uid "
10254                    + cpi.applicationInfo.uid;
10255        } else {
10256            msg = "Permission Denial: opening provider " + cpi.name
10257                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10258                    + ", uid=" + callingUid + ") requires "
10259                    + cpi.readPermission + " or " + cpi.writePermission;
10260        }
10261        Slog.w(TAG, msg);
10262        return msg;
10263    }
10264
10265    /**
10266     * Returns if the ContentProvider has granted a uri to callingUid
10267     */
10268    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10269        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10270        if (perms != null) {
10271            for (int i=perms.size()-1; i>=0; i--) {
10272                GrantUri grantUri = perms.keyAt(i);
10273                if (grantUri.sourceUserId == userId || !checkUser) {
10274                    if (matchesProvider(grantUri.uri, cpi)) {
10275                        return true;
10276                    }
10277                }
10278            }
10279        }
10280        return false;
10281    }
10282
10283    /**
10284     * Returns true if the uri authority is one of the authorities specified in the provider.
10285     */
10286    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10287        String uriAuth = uri.getAuthority();
10288        String cpiAuth = cpi.authority;
10289        if (cpiAuth.indexOf(';') == -1) {
10290            return cpiAuth.equals(uriAuth);
10291        }
10292        String[] cpiAuths = cpiAuth.split(";");
10293        int length = cpiAuths.length;
10294        for (int i = 0; i < length; i++) {
10295            if (cpiAuths[i].equals(uriAuth)) return true;
10296        }
10297        return false;
10298    }
10299
10300    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10301            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10302        if (r != null) {
10303            for (int i=0; i<r.conProviders.size(); i++) {
10304                ContentProviderConnection conn = r.conProviders.get(i);
10305                if (conn.provider == cpr) {
10306                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10307                            "Adding provider requested by "
10308                            + r.processName + " from process "
10309                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10310                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10311                    if (stable) {
10312                        conn.stableCount++;
10313                        conn.numStableIncs++;
10314                    } else {
10315                        conn.unstableCount++;
10316                        conn.numUnstableIncs++;
10317                    }
10318                    return conn;
10319                }
10320            }
10321            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10322            if (stable) {
10323                conn.stableCount = 1;
10324                conn.numStableIncs = 1;
10325            } else {
10326                conn.unstableCount = 1;
10327                conn.numUnstableIncs = 1;
10328            }
10329            cpr.connections.add(conn);
10330            r.conProviders.add(conn);
10331            startAssociationLocked(r.uid, r.processName, r.curProcState,
10332                    cpr.uid, cpr.name, cpr.info.processName);
10333            return conn;
10334        }
10335        cpr.addExternalProcessHandleLocked(externalProcessToken);
10336        return null;
10337    }
10338
10339    boolean decProviderCountLocked(ContentProviderConnection conn,
10340            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10341        if (conn != null) {
10342            cpr = conn.provider;
10343            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10344                    "Removing provider requested by "
10345                    + conn.client.processName + " from process "
10346                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10347                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10348            if (stable) {
10349                conn.stableCount--;
10350            } else {
10351                conn.unstableCount--;
10352            }
10353            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10354                cpr.connections.remove(conn);
10355                conn.client.conProviders.remove(conn);
10356                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10357                    // The client is more important than last activity -- note the time this
10358                    // is happening, so we keep the old provider process around a bit as last
10359                    // activity to avoid thrashing it.
10360                    if (cpr.proc != null) {
10361                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10362                    }
10363                }
10364                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10365                return true;
10366            }
10367            return false;
10368        }
10369        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10370        return false;
10371    }
10372
10373    private void checkTime(long startTime, String where) {
10374        long now = SystemClock.uptimeMillis();
10375        if ((now-startTime) > 50) {
10376            // If we are taking more than 50ms, log about it.
10377            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10378        }
10379    }
10380
10381    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10382            String name, IBinder token, boolean stable, int userId) {
10383        ContentProviderRecord cpr;
10384        ContentProviderConnection conn = null;
10385        ProviderInfo cpi = null;
10386
10387        synchronized(this) {
10388            long startTime = SystemClock.uptimeMillis();
10389
10390            ProcessRecord r = null;
10391            if (caller != null) {
10392                r = getRecordForAppLocked(caller);
10393                if (r == null) {
10394                    throw new SecurityException(
10395                            "Unable to find app for caller " + caller
10396                          + " (pid=" + Binder.getCallingPid()
10397                          + ") when getting content provider " + name);
10398                }
10399            }
10400
10401            boolean checkCrossUser = true;
10402
10403            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10404
10405            // First check if this content provider has been published...
10406            cpr = mProviderMap.getProviderByName(name, userId);
10407            // If that didn't work, check if it exists for user 0 and then
10408            // verify that it's a singleton provider before using it.
10409            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10410                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10411                if (cpr != null) {
10412                    cpi = cpr.info;
10413                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10414                            cpi.name, cpi.flags)
10415                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10416                        userId = UserHandle.USER_SYSTEM;
10417                        checkCrossUser = false;
10418                    } else {
10419                        cpr = null;
10420                        cpi = null;
10421                    }
10422                }
10423            }
10424
10425            boolean providerRunning = cpr != null;
10426            if (providerRunning) {
10427                cpi = cpr.info;
10428                String msg;
10429                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10430                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10431                        != null) {
10432                    throw new SecurityException(msg);
10433                }
10434                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10435
10436                if (r != null && cpr.canRunHere(r)) {
10437                    // This provider has been published or is in the process
10438                    // of being published...  but it is also allowed to run
10439                    // in the caller's process, so don't make a connection
10440                    // and just let the caller instantiate its own instance.
10441                    ContentProviderHolder holder = cpr.newHolder(null);
10442                    // don't give caller the provider object, it needs
10443                    // to make its own.
10444                    holder.provider = null;
10445                    return holder;
10446                }
10447
10448                final long origId = Binder.clearCallingIdentity();
10449
10450                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10451
10452                // In this case the provider instance already exists, so we can
10453                // return it right away.
10454                conn = incProviderCountLocked(r, cpr, token, stable);
10455                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10456                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10457                        // If this is a perceptible app accessing the provider,
10458                        // make sure to count it as being accessed and thus
10459                        // back up on the LRU list.  This is good because
10460                        // content providers are often expensive to start.
10461                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10462                        updateLruProcessLocked(cpr.proc, false, null);
10463                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10464                    }
10465                }
10466
10467                if (cpr.proc != null) {
10468                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10469                    boolean success = updateOomAdjLocked(cpr.proc);
10470                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10471                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10472                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10473                    // NOTE: there is still a race here where a signal could be
10474                    // pending on the process even though we managed to update its
10475                    // adj level.  Not sure what to do about this, but at least
10476                    // the race is now smaller.
10477                    if (!success) {
10478                        // Uh oh...  it looks like the provider's process
10479                        // has been killed on us.  We need to wait for a new
10480                        // process to be started, and make sure its death
10481                        // doesn't kill our process.
10482                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10483                                + " is crashing; detaching " + r);
10484                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10485                        checkTime(startTime, "getContentProviderImpl: before appDied");
10486                        appDiedLocked(cpr.proc);
10487                        checkTime(startTime, "getContentProviderImpl: after appDied");
10488                        if (!lastRef) {
10489                            // This wasn't the last ref our process had on
10490                            // the provider...  we have now been killed, bail.
10491                            return null;
10492                        }
10493                        providerRunning = false;
10494                        conn = null;
10495                    }
10496                }
10497
10498                Binder.restoreCallingIdentity(origId);
10499            }
10500
10501            if (!providerRunning) {
10502                try {
10503                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10504                    cpi = AppGlobals.getPackageManager().
10505                        resolveContentProvider(name,
10506                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10507                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10508                } catch (RemoteException ex) {
10509                }
10510                if (cpi == null) {
10511                    return null;
10512                }
10513                // If the provider is a singleton AND
10514                // (it's a call within the same user || the provider is a
10515                // privileged app)
10516                // Then allow connecting to the singleton provider
10517                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10518                        cpi.name, cpi.flags)
10519                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10520                if (singleton) {
10521                    userId = UserHandle.USER_SYSTEM;
10522                }
10523                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10524                checkTime(startTime, "getContentProviderImpl: got app info for user");
10525
10526                String msg;
10527                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10528                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10529                        != null) {
10530                    throw new SecurityException(msg);
10531                }
10532                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10533
10534                if (!mProcessesReady
10535                        && !cpi.processName.equals("system")) {
10536                    // If this content provider does not run in the system
10537                    // process, and the system is not yet ready to run other
10538                    // processes, then fail fast instead of hanging.
10539                    throw new IllegalArgumentException(
10540                            "Attempt to launch content provider before system ready");
10541                }
10542
10543                // Make sure that the user who owns this provider is running.  If not,
10544                // we don't want to allow it to run.
10545                if (!mUserController.isUserRunningLocked(userId, 0)) {
10546                    Slog.w(TAG, "Unable to launch app "
10547                            + cpi.applicationInfo.packageName + "/"
10548                            + cpi.applicationInfo.uid + " for provider "
10549                            + name + ": user " + userId + " is stopped");
10550                    return null;
10551                }
10552
10553                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10554                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10555                cpr = mProviderMap.getProviderByClass(comp, userId);
10556                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10557                final boolean firstClass = cpr == null;
10558                if (firstClass) {
10559                    final long ident = Binder.clearCallingIdentity();
10560
10561                    // If permissions need a review before any of the app components can run,
10562                    // we return no provider and launch a review activity if the calling app
10563                    // is in the foreground.
10564                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10565                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10566                            return null;
10567                        }
10568                    }
10569
10570                    try {
10571                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10572                        ApplicationInfo ai =
10573                            AppGlobals.getPackageManager().
10574                                getApplicationInfo(
10575                                        cpi.applicationInfo.packageName,
10576                                        STOCK_PM_FLAGS, userId);
10577                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10578                        if (ai == null) {
10579                            Slog.w(TAG, "No package info for content provider "
10580                                    + cpi.name);
10581                            return null;
10582                        }
10583                        ai = getAppInfoForUser(ai, userId);
10584                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10585                    } catch (RemoteException ex) {
10586                        // pm is in same process, this will never happen.
10587                    } finally {
10588                        Binder.restoreCallingIdentity(ident);
10589                    }
10590                }
10591
10592                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10593
10594                if (r != null && cpr.canRunHere(r)) {
10595                    // If this is a multiprocess provider, then just return its
10596                    // info and allow the caller to instantiate it.  Only do
10597                    // this if the provider is the same user as the caller's
10598                    // process, or can run as root (so can be in any process).
10599                    return cpr.newHolder(null);
10600                }
10601
10602                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10603                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10604                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10605
10606                // This is single process, and our app is now connecting to it.
10607                // See if we are already in the process of launching this
10608                // provider.
10609                final int N = mLaunchingProviders.size();
10610                int i;
10611                for (i = 0; i < N; i++) {
10612                    if (mLaunchingProviders.get(i) == cpr) {
10613                        break;
10614                    }
10615                }
10616
10617                // If the provider is not already being launched, then get it
10618                // started.
10619                if (i >= N) {
10620                    final long origId = Binder.clearCallingIdentity();
10621
10622                    try {
10623                        // Content provider is now in use, its package can't be stopped.
10624                        try {
10625                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10626                            AppGlobals.getPackageManager().setPackageStoppedState(
10627                                    cpr.appInfo.packageName, false, userId);
10628                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10629                        } catch (RemoteException e) {
10630                        } catch (IllegalArgumentException e) {
10631                            Slog.w(TAG, "Failed trying to unstop package "
10632                                    + cpr.appInfo.packageName + ": " + e);
10633                        }
10634
10635                        // Use existing process if already started
10636                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10637                        ProcessRecord proc = getProcessRecordLocked(
10638                                cpi.processName, cpr.appInfo.uid, false);
10639                        if (proc != null && proc.thread != null) {
10640                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10641                                    "Installing in existing process " + proc);
10642                            if (!proc.pubProviders.containsKey(cpi.name)) {
10643                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10644                                proc.pubProviders.put(cpi.name, cpr);
10645                                try {
10646                                    proc.thread.scheduleInstallProvider(cpi);
10647                                } catch (RemoteException e) {
10648                                }
10649                            }
10650                        } else {
10651                            checkTime(startTime, "getContentProviderImpl: before start process");
10652                            proc = startProcessLocked(cpi.processName,
10653                                    cpr.appInfo, false, 0, "content provider",
10654                                    new ComponentName(cpi.applicationInfo.packageName,
10655                                            cpi.name), false, false, false);
10656                            checkTime(startTime, "getContentProviderImpl: after start process");
10657                            if (proc == null) {
10658                                Slog.w(TAG, "Unable to launch app "
10659                                        + cpi.applicationInfo.packageName + "/"
10660                                        + cpi.applicationInfo.uid + " for provider "
10661                                        + name + ": process is bad");
10662                                return null;
10663                            }
10664                        }
10665                        cpr.launchingApp = proc;
10666                        mLaunchingProviders.add(cpr);
10667                    } finally {
10668                        Binder.restoreCallingIdentity(origId);
10669                    }
10670                }
10671
10672                checkTime(startTime, "getContentProviderImpl: updating data structures");
10673
10674                // Make sure the provider is published (the same provider class
10675                // may be published under multiple names).
10676                if (firstClass) {
10677                    mProviderMap.putProviderByClass(comp, cpr);
10678                }
10679
10680                mProviderMap.putProviderByName(name, cpr);
10681                conn = incProviderCountLocked(r, cpr, token, stable);
10682                if (conn != null) {
10683                    conn.waiting = true;
10684                }
10685            }
10686            checkTime(startTime, "getContentProviderImpl: done!");
10687        }
10688
10689        // Wait for the provider to be published...
10690        synchronized (cpr) {
10691            while (cpr.provider == null) {
10692                if (cpr.launchingApp == null) {
10693                    Slog.w(TAG, "Unable to launch app "
10694                            + cpi.applicationInfo.packageName + "/"
10695                            + cpi.applicationInfo.uid + " for provider "
10696                            + name + ": launching app became null");
10697                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10698                            UserHandle.getUserId(cpi.applicationInfo.uid),
10699                            cpi.applicationInfo.packageName,
10700                            cpi.applicationInfo.uid, name);
10701                    return null;
10702                }
10703                try {
10704                    if (DEBUG_MU) Slog.v(TAG_MU,
10705                            "Waiting to start provider " + cpr
10706                            + " launchingApp=" + cpr.launchingApp);
10707                    if (conn != null) {
10708                        conn.waiting = true;
10709                    }
10710                    cpr.wait();
10711                } catch (InterruptedException ex) {
10712                } finally {
10713                    if (conn != null) {
10714                        conn.waiting = false;
10715                    }
10716                }
10717            }
10718        }
10719        return cpr != null ? cpr.newHolder(conn) : null;
10720    }
10721
10722    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10723            ProcessRecord r, final int userId) {
10724        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10725                cpi.packageName, userId)) {
10726
10727            final boolean callerForeground = r == null || r.setSchedGroup
10728                    != ProcessList.SCHED_GROUP_BACKGROUND;
10729
10730            // Show a permission review UI only for starting from a foreground app
10731            if (!callerForeground) {
10732                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10733                        + cpi.packageName + " requires a permissions review");
10734                return false;
10735            }
10736
10737            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10738            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10739                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10740            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10741
10742            if (DEBUG_PERMISSIONS_REVIEW) {
10743                Slog.i(TAG, "u" + userId + " Launching permission review "
10744                        + "for package " + cpi.packageName);
10745            }
10746
10747            final UserHandle userHandle = new UserHandle(userId);
10748            mHandler.post(new Runnable() {
10749                @Override
10750                public void run() {
10751                    mContext.startActivityAsUser(intent, userHandle);
10752                }
10753            });
10754
10755            return false;
10756        }
10757
10758        return true;
10759    }
10760
10761    PackageManagerInternal getPackageManagerInternalLocked() {
10762        if (mPackageManagerInt == null) {
10763            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10764        }
10765        return mPackageManagerInt;
10766    }
10767
10768    @Override
10769    public final ContentProviderHolder getContentProvider(
10770            IApplicationThread caller, String name, int userId, boolean stable) {
10771        enforceNotIsolatedCaller("getContentProvider");
10772        if (caller == null) {
10773            String msg = "null IApplicationThread when getting content provider "
10774                    + name;
10775            Slog.w(TAG, msg);
10776            throw new SecurityException(msg);
10777        }
10778        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10779        // with cross-user grant.
10780        return getContentProviderImpl(caller, name, null, stable, userId);
10781    }
10782
10783    public ContentProviderHolder getContentProviderExternal(
10784            String name, int userId, IBinder token) {
10785        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10786            "Do not have permission in call getContentProviderExternal()");
10787        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10788                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10789        return getContentProviderExternalUnchecked(name, token, userId);
10790    }
10791
10792    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10793            IBinder token, int userId) {
10794        return getContentProviderImpl(null, name, token, true, userId);
10795    }
10796
10797    /**
10798     * Drop a content provider from a ProcessRecord's bookkeeping
10799     */
10800    public void removeContentProvider(IBinder connection, boolean stable) {
10801        enforceNotIsolatedCaller("removeContentProvider");
10802        long ident = Binder.clearCallingIdentity();
10803        try {
10804            synchronized (this) {
10805                ContentProviderConnection conn;
10806                try {
10807                    conn = (ContentProviderConnection)connection;
10808                } catch (ClassCastException e) {
10809                    String msg ="removeContentProvider: " + connection
10810                            + " not a ContentProviderConnection";
10811                    Slog.w(TAG, msg);
10812                    throw new IllegalArgumentException(msg);
10813                }
10814                if (conn == null) {
10815                    throw new NullPointerException("connection is null");
10816                }
10817                if (decProviderCountLocked(conn, null, null, stable)) {
10818                    updateOomAdjLocked();
10819                }
10820            }
10821        } finally {
10822            Binder.restoreCallingIdentity(ident);
10823        }
10824    }
10825
10826    public void removeContentProviderExternal(String name, IBinder token) {
10827        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10828            "Do not have permission in call removeContentProviderExternal()");
10829        int userId = UserHandle.getCallingUserId();
10830        long ident = Binder.clearCallingIdentity();
10831        try {
10832            removeContentProviderExternalUnchecked(name, token, userId);
10833        } finally {
10834            Binder.restoreCallingIdentity(ident);
10835        }
10836    }
10837
10838    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10839        synchronized (this) {
10840            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10841            if(cpr == null) {
10842                //remove from mProvidersByClass
10843                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10844                return;
10845            }
10846
10847            //update content provider record entry info
10848            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10849            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10850            if (localCpr.hasExternalProcessHandles()) {
10851                if (localCpr.removeExternalProcessHandleLocked(token)) {
10852                    updateOomAdjLocked();
10853                } else {
10854                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10855                            + " with no external reference for token: "
10856                            + token + ".");
10857                }
10858            } else {
10859                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10860                        + " with no external references.");
10861            }
10862        }
10863    }
10864
10865    public final void publishContentProviders(IApplicationThread caller,
10866            List<ContentProviderHolder> providers) {
10867        if (providers == null) {
10868            return;
10869        }
10870
10871        enforceNotIsolatedCaller("publishContentProviders");
10872        synchronized (this) {
10873            final ProcessRecord r = getRecordForAppLocked(caller);
10874            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10875            if (r == null) {
10876                throw new SecurityException(
10877                        "Unable to find app for caller " + caller
10878                      + " (pid=" + Binder.getCallingPid()
10879                      + ") when publishing content providers");
10880            }
10881
10882            final long origId = Binder.clearCallingIdentity();
10883
10884            final int N = providers.size();
10885            for (int i = 0; i < N; i++) {
10886                ContentProviderHolder src = providers.get(i);
10887                if (src == null || src.info == null || src.provider == null) {
10888                    continue;
10889                }
10890                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10891                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10892                if (dst != null) {
10893                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10894                    mProviderMap.putProviderByClass(comp, dst);
10895                    String names[] = dst.info.authority.split(";");
10896                    for (int j = 0; j < names.length; j++) {
10897                        mProviderMap.putProviderByName(names[j], dst);
10898                    }
10899
10900                    int launchingCount = mLaunchingProviders.size();
10901                    int j;
10902                    boolean wasInLaunchingProviders = false;
10903                    for (j = 0; j < launchingCount; j++) {
10904                        if (mLaunchingProviders.get(j) == dst) {
10905                            mLaunchingProviders.remove(j);
10906                            wasInLaunchingProviders = true;
10907                            j--;
10908                            launchingCount--;
10909                        }
10910                    }
10911                    if (wasInLaunchingProviders) {
10912                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10913                    }
10914                    synchronized (dst) {
10915                        dst.provider = src.provider;
10916                        dst.proc = r;
10917                        dst.notifyAll();
10918                    }
10919                    updateOomAdjLocked(r);
10920                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10921                            src.info.authority);
10922                }
10923            }
10924
10925            Binder.restoreCallingIdentity(origId);
10926        }
10927    }
10928
10929    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10930        ContentProviderConnection conn;
10931        try {
10932            conn = (ContentProviderConnection)connection;
10933        } catch (ClassCastException e) {
10934            String msg ="refContentProvider: " + connection
10935                    + " not a ContentProviderConnection";
10936            Slog.w(TAG, msg);
10937            throw new IllegalArgumentException(msg);
10938        }
10939        if (conn == null) {
10940            throw new NullPointerException("connection is null");
10941        }
10942
10943        synchronized (this) {
10944            if (stable > 0) {
10945                conn.numStableIncs += stable;
10946            }
10947            stable = conn.stableCount + stable;
10948            if (stable < 0) {
10949                throw new IllegalStateException("stableCount < 0: " + stable);
10950            }
10951
10952            if (unstable > 0) {
10953                conn.numUnstableIncs += unstable;
10954            }
10955            unstable = conn.unstableCount + unstable;
10956            if (unstable < 0) {
10957                throw new IllegalStateException("unstableCount < 0: " + unstable);
10958            }
10959
10960            if ((stable+unstable) <= 0) {
10961                throw new IllegalStateException("ref counts can't go to zero here: stable="
10962                        + stable + " unstable=" + unstable);
10963            }
10964            conn.stableCount = stable;
10965            conn.unstableCount = unstable;
10966            return !conn.dead;
10967        }
10968    }
10969
10970    public void unstableProviderDied(IBinder connection) {
10971        ContentProviderConnection conn;
10972        try {
10973            conn = (ContentProviderConnection)connection;
10974        } catch (ClassCastException e) {
10975            String msg ="refContentProvider: " + connection
10976                    + " not a ContentProviderConnection";
10977            Slog.w(TAG, msg);
10978            throw new IllegalArgumentException(msg);
10979        }
10980        if (conn == null) {
10981            throw new NullPointerException("connection is null");
10982        }
10983
10984        // Safely retrieve the content provider associated with the connection.
10985        IContentProvider provider;
10986        synchronized (this) {
10987            provider = conn.provider.provider;
10988        }
10989
10990        if (provider == null) {
10991            // Um, yeah, we're way ahead of you.
10992            return;
10993        }
10994
10995        // Make sure the caller is being honest with us.
10996        if (provider.asBinder().pingBinder()) {
10997            // Er, no, still looks good to us.
10998            synchronized (this) {
10999                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11000                        + " says " + conn + " died, but we don't agree");
11001                return;
11002            }
11003        }
11004
11005        // Well look at that!  It's dead!
11006        synchronized (this) {
11007            if (conn.provider.provider != provider) {
11008                // But something changed...  good enough.
11009                return;
11010            }
11011
11012            ProcessRecord proc = conn.provider.proc;
11013            if (proc == null || proc.thread == null) {
11014                // Seems like the process is already cleaned up.
11015                return;
11016            }
11017
11018            // As far as we're concerned, this is just like receiving a
11019            // death notification...  just a bit prematurely.
11020            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11021                    + ") early provider death");
11022            final long ident = Binder.clearCallingIdentity();
11023            try {
11024                appDiedLocked(proc);
11025            } finally {
11026                Binder.restoreCallingIdentity(ident);
11027            }
11028        }
11029    }
11030
11031    @Override
11032    public void appNotRespondingViaProvider(IBinder connection) {
11033        enforceCallingPermission(
11034                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11035
11036        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11037        if (conn == null) {
11038            Slog.w(TAG, "ContentProviderConnection is null");
11039            return;
11040        }
11041
11042        final ProcessRecord host = conn.provider.proc;
11043        if (host == null) {
11044            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11045            return;
11046        }
11047
11048        mHandler.post(new Runnable() {
11049            @Override
11050            public void run() {
11051                mAppErrors.appNotResponding(host, null, null, false,
11052                        "ContentProvider not responding");
11053            }
11054        });
11055    }
11056
11057    public final void installSystemProviders() {
11058        List<ProviderInfo> providers;
11059        synchronized (this) {
11060            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11061            providers = generateApplicationProvidersLocked(app);
11062            if (providers != null) {
11063                for (int i=providers.size()-1; i>=0; i--) {
11064                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11065                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11066                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11067                                + ": not system .apk");
11068                        providers.remove(i);
11069                    }
11070                }
11071            }
11072        }
11073        if (providers != null) {
11074            mSystemThread.installSystemProviders(providers);
11075        }
11076
11077        mCoreSettingsObserver = new CoreSettingsObserver(this);
11078        mFontScaleSettingObserver = new FontScaleSettingObserver();
11079
11080        //mUsageStatsService.monitorPackages();
11081    }
11082
11083    private void startPersistentApps(int matchFlags) {
11084        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11085
11086        synchronized (this) {
11087            try {
11088                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11089                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11090                for (ApplicationInfo app : apps) {
11091                    if (!"android".equals(app.packageName)) {
11092                        addAppLocked(app, false, null /* ABI override */);
11093                    }
11094                }
11095            } catch (RemoteException ex) {
11096            }
11097        }
11098    }
11099
11100    /**
11101     * When a user is unlocked, we need to install encryption-unaware providers
11102     * belonging to any running apps.
11103     */
11104    private void installEncryptionUnawareProviders(int userId) {
11105        // We're only interested in providers that are encryption unaware, and
11106        // we don't care about uninstalled apps, since there's no way they're
11107        // running at this point.
11108        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11109
11110        synchronized (this) {
11111            final int NP = mProcessNames.getMap().size();
11112            for (int ip = 0; ip < NP; ip++) {
11113                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11114                final int NA = apps.size();
11115                for (int ia = 0; ia < NA; ia++) {
11116                    final ProcessRecord app = apps.valueAt(ia);
11117                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11118
11119                    final int NG = app.pkgList.size();
11120                    for (int ig = 0; ig < NG; ig++) {
11121                        try {
11122                            final String pkgName = app.pkgList.keyAt(ig);
11123                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11124                                    .getPackageInfo(pkgName, matchFlags, userId);
11125                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11126                                for (ProviderInfo provInfo : pkgInfo.providers) {
11127                                    Log.v(TAG, "Installing " + provInfo);
11128                                    app.thread.scheduleInstallProvider(provInfo);
11129                                }
11130                            }
11131                        } catch (RemoteException ignored) {
11132                        }
11133                    }
11134                }
11135            }
11136        }
11137    }
11138
11139    /**
11140     * Allows apps to retrieve the MIME type of a URI.
11141     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11142     * users, then it does not need permission to access the ContentProvider.
11143     * Either, it needs cross-user uri grants.
11144     *
11145     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11146     *
11147     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11148     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11149     */
11150    public String getProviderMimeType(Uri uri, int userId) {
11151        enforceNotIsolatedCaller("getProviderMimeType");
11152        final String name = uri.getAuthority();
11153        int callingUid = Binder.getCallingUid();
11154        int callingPid = Binder.getCallingPid();
11155        long ident = 0;
11156        boolean clearedIdentity = false;
11157        synchronized (this) {
11158            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11159        }
11160        if (canClearIdentity(callingPid, callingUid, userId)) {
11161            clearedIdentity = true;
11162            ident = Binder.clearCallingIdentity();
11163        }
11164        ContentProviderHolder holder = null;
11165        try {
11166            holder = getContentProviderExternalUnchecked(name, null, userId);
11167            if (holder != null) {
11168                return holder.provider.getType(uri);
11169            }
11170        } catch (RemoteException e) {
11171            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11172            return null;
11173        } finally {
11174            // We need to clear the identity to call removeContentProviderExternalUnchecked
11175            if (!clearedIdentity) {
11176                ident = Binder.clearCallingIdentity();
11177            }
11178            try {
11179                if (holder != null) {
11180                    removeContentProviderExternalUnchecked(name, null, userId);
11181                }
11182            } finally {
11183                Binder.restoreCallingIdentity(ident);
11184            }
11185        }
11186
11187        return null;
11188    }
11189
11190    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11191        if (UserHandle.getUserId(callingUid) == userId) {
11192            return true;
11193        }
11194        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11195                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11196                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11197                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11198                return true;
11199        }
11200        return false;
11201    }
11202
11203    // =========================================================
11204    // GLOBAL MANAGEMENT
11205    // =========================================================
11206
11207    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11208            boolean isolated, int isolatedUid) {
11209        String proc = customProcess != null ? customProcess : info.processName;
11210        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11211        final int userId = UserHandle.getUserId(info.uid);
11212        int uid = info.uid;
11213        if (isolated) {
11214            if (isolatedUid == 0) {
11215                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11216                while (true) {
11217                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11218                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11219                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11220                    }
11221                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11222                    mNextIsolatedProcessUid++;
11223                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11224                        // No process for this uid, use it.
11225                        break;
11226                    }
11227                    stepsLeft--;
11228                    if (stepsLeft <= 0) {
11229                        return null;
11230                    }
11231                }
11232            } else {
11233                // Special case for startIsolatedProcess (internal only), where
11234                // the uid of the isolated process is specified by the caller.
11235                uid = isolatedUid;
11236            }
11237        }
11238        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11239        if (!mBooted && !mBooting
11240                && userId == UserHandle.USER_SYSTEM
11241                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11242            r.persistent = true;
11243        }
11244        addProcessNameLocked(r);
11245        return r;
11246    }
11247
11248    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11249            String abiOverride) {
11250        ProcessRecord app;
11251        if (!isolated) {
11252            app = getProcessRecordLocked(info.processName, info.uid, true);
11253        } else {
11254            app = null;
11255        }
11256
11257        if (app == null) {
11258            app = newProcessRecordLocked(info, null, isolated, 0);
11259            updateLruProcessLocked(app, false, null);
11260            updateOomAdjLocked();
11261        }
11262
11263        // This package really, really can not be stopped.
11264        try {
11265            AppGlobals.getPackageManager().setPackageStoppedState(
11266                    info.packageName, false, UserHandle.getUserId(app.uid));
11267        } catch (RemoteException e) {
11268        } catch (IllegalArgumentException e) {
11269            Slog.w(TAG, "Failed trying to unstop package "
11270                    + info.packageName + ": " + e);
11271        }
11272
11273        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11274            app.persistent = true;
11275            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11276        }
11277        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11278            mPersistentStartingProcesses.add(app);
11279            startProcessLocked(app, "added application", app.processName, abiOverride,
11280                    null /* entryPoint */, null /* entryPointArgs */);
11281        }
11282
11283        return app;
11284    }
11285
11286    public void unhandledBack() {
11287        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11288                "unhandledBack()");
11289
11290        synchronized(this) {
11291            final long origId = Binder.clearCallingIdentity();
11292            try {
11293                getFocusedStack().unhandledBackLocked();
11294            } finally {
11295                Binder.restoreCallingIdentity(origId);
11296            }
11297        }
11298    }
11299
11300    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11301        enforceNotIsolatedCaller("openContentUri");
11302        final int userId = UserHandle.getCallingUserId();
11303        String name = uri.getAuthority();
11304        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11305        ParcelFileDescriptor pfd = null;
11306        if (cph != null) {
11307            // We record the binder invoker's uid in thread-local storage before
11308            // going to the content provider to open the file.  Later, in the code
11309            // that handles all permissions checks, we look for this uid and use
11310            // that rather than the Activity Manager's own uid.  The effect is that
11311            // we do the check against the caller's permissions even though it looks
11312            // to the content provider like the Activity Manager itself is making
11313            // the request.
11314            Binder token = new Binder();
11315            sCallerIdentity.set(new Identity(
11316                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11317            try {
11318                pfd = cph.provider.openFile(null, uri, "r", null, token);
11319            } catch (FileNotFoundException e) {
11320                // do nothing; pfd will be returned null
11321            } finally {
11322                // Ensure that whatever happens, we clean up the identity state
11323                sCallerIdentity.remove();
11324                // Ensure we're done with the provider.
11325                removeContentProviderExternalUnchecked(name, null, userId);
11326            }
11327        } else {
11328            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11329        }
11330        return pfd;
11331    }
11332
11333    // Actually is sleeping or shutting down or whatever else in the future
11334    // is an inactive state.
11335    public boolean isSleepingOrShuttingDown() {
11336        return isSleeping() || mShuttingDown;
11337    }
11338
11339    public boolean isSleeping() {
11340        return mSleeping;
11341    }
11342
11343    void onWakefulnessChanged(int wakefulness) {
11344        synchronized(this) {
11345            mWakefulness = wakefulness;
11346            updateSleepIfNeededLocked();
11347        }
11348    }
11349
11350    void finishRunningVoiceLocked() {
11351        if (mRunningVoice != null) {
11352            mRunningVoice = null;
11353            mVoiceWakeLock.release();
11354            updateSleepIfNeededLocked();
11355        }
11356    }
11357
11358    void startTimeTrackingFocusedActivityLocked() {
11359        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11360            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11361        }
11362    }
11363
11364    void updateSleepIfNeededLocked() {
11365        if (mSleeping && !shouldSleepLocked()) {
11366            mSleeping = false;
11367            startTimeTrackingFocusedActivityLocked();
11368            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11369            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11370            updateOomAdjLocked();
11371        } else if (!mSleeping && shouldSleepLocked()) {
11372            mSleeping = true;
11373            if (mCurAppTimeTracker != null) {
11374                mCurAppTimeTracker.stop();
11375            }
11376            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11377            mStackSupervisor.goingToSleepLocked();
11378            updateOomAdjLocked();
11379
11380            // Initialize the wake times of all processes.
11381            checkExcessivePowerUsageLocked(false);
11382            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11383            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11384            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11385        }
11386    }
11387
11388    private boolean shouldSleepLocked() {
11389        // Resume applications while running a voice interactor.
11390        if (mRunningVoice != null) {
11391            return false;
11392        }
11393
11394        // TODO: Transform the lock screen state into a sleep token instead.
11395        switch (mWakefulness) {
11396            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11397            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11398            case PowerManagerInternal.WAKEFULNESS_DOZING:
11399                // Pause applications whenever the lock screen is shown or any sleep
11400                // tokens have been acquired.
11401                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11402            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11403            default:
11404                // If we're asleep then pause applications unconditionally.
11405                return true;
11406        }
11407    }
11408
11409    /** Pokes the task persister. */
11410    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11411        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11412    }
11413
11414    /** Notifies all listeners when the task stack has changed. */
11415    void notifyTaskStackChangedLocked() {
11416        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11417        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11418        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11419        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11420    }
11421
11422    /** Notifies all listeners when an Activity is pinned. */
11423    void notifyActivityPinnedLocked() {
11424        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11425        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11426    }
11427
11428    /**
11429     * Notifies all listeners when an attempt was made to start an an activity that is already
11430     * running in the pinned stack and the activity was not actually started, but the task is
11431     * either brought to the front or a new Intent is delivered to it.
11432     */
11433    void notifyPinnedActivityRestartAttemptLocked() {
11434        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11435        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11436    }
11437
11438    /** Notifies all listeners when the pinned stack animation ends. */
11439    @Override
11440    public void notifyPinnedStackAnimationEnded() {
11441        synchronized (this) {
11442            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11443            mHandler.obtainMessage(
11444                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11445        }
11446    }
11447
11448    @Override
11449    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11450        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11451    }
11452
11453    @Override
11454    public boolean shutdown(int timeout) {
11455        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11456                != PackageManager.PERMISSION_GRANTED) {
11457            throw new SecurityException("Requires permission "
11458                    + android.Manifest.permission.SHUTDOWN);
11459        }
11460
11461        boolean timedout = false;
11462
11463        synchronized(this) {
11464            mShuttingDown = true;
11465            updateEventDispatchingLocked();
11466            timedout = mStackSupervisor.shutdownLocked(timeout);
11467        }
11468
11469        mAppOpsService.shutdown();
11470        if (mUsageStatsService != null) {
11471            mUsageStatsService.prepareShutdown();
11472        }
11473        mBatteryStatsService.shutdown();
11474        synchronized (this) {
11475            mProcessStats.shutdownLocked();
11476            notifyTaskPersisterLocked(null, true);
11477        }
11478
11479        return timedout;
11480    }
11481
11482    public final void activitySlept(IBinder token) {
11483        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11484
11485        final long origId = Binder.clearCallingIdentity();
11486
11487        synchronized (this) {
11488            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11489            if (r != null) {
11490                mStackSupervisor.activitySleptLocked(r);
11491            }
11492        }
11493
11494        Binder.restoreCallingIdentity(origId);
11495    }
11496
11497    private String lockScreenShownToString() {
11498        switch (mLockScreenShown) {
11499            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11500            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11501            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11502            default: return "Unknown=" + mLockScreenShown;
11503        }
11504    }
11505
11506    void logLockScreen(String msg) {
11507        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11508                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11509                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11510                + " mSleeping=" + mSleeping);
11511    }
11512
11513    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11514        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11515        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11516        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11517            boolean wasRunningVoice = mRunningVoice != null;
11518            mRunningVoice = session;
11519            if (!wasRunningVoice) {
11520                mVoiceWakeLock.acquire();
11521                updateSleepIfNeededLocked();
11522            }
11523        }
11524    }
11525
11526    private void updateEventDispatchingLocked() {
11527        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11528    }
11529
11530    public void setLockScreenShown(boolean showing, boolean occluded) {
11531        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11532                != PackageManager.PERMISSION_GRANTED) {
11533            throw new SecurityException("Requires permission "
11534                    + android.Manifest.permission.DEVICE_POWER);
11535        }
11536
11537        synchronized(this) {
11538            long ident = Binder.clearCallingIdentity();
11539            try {
11540                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11541                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11542                if (showing && occluded) {
11543                    // The lock screen is currently showing, but is occluded by a window that can
11544                    // show on top of the lock screen. In this can we want to dismiss the docked
11545                    // stack since it will be complicated/risky to try to put the activity on top
11546                    // of the lock screen in the right fullscreen configuration.
11547                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11548                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11549                }
11550
11551                updateSleepIfNeededLocked();
11552            } finally {
11553                Binder.restoreCallingIdentity(ident);
11554            }
11555        }
11556    }
11557
11558    @Override
11559    public void notifyLockedProfile(@UserIdInt int userId) {
11560        try {
11561            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11562                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11563            }
11564        } catch (RemoteException ex) {
11565            throw new SecurityException("Fail to check is caller a privileged app", ex);
11566        }
11567
11568        synchronized (this) {
11569            if (mStackSupervisor.isUserLockedProfile(userId)) {
11570                final long ident = Binder.clearCallingIdentity();
11571                try {
11572                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11573                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11574                        // If there is no device lock, we will show the profile's credential page.
11575                        mActivityStarter.showConfirmDeviceCredential(userId);
11576                    } else {
11577                        // Showing launcher to avoid user entering credential twice.
11578                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11579                    }
11580                } finally {
11581                    Binder.restoreCallingIdentity(ident);
11582                }
11583            }
11584        }
11585    }
11586
11587    @Override
11588    public void startConfirmDeviceCredentialIntent(Intent intent) {
11589        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11590        synchronized (this) {
11591            final long ident = Binder.clearCallingIdentity();
11592            try {
11593                mActivityStarter.startConfirmCredentialIntent(intent);
11594            } finally {
11595                Binder.restoreCallingIdentity(ident);
11596            }
11597        }
11598    }
11599
11600    @Override
11601    public void stopAppSwitches() {
11602        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11603                != PackageManager.PERMISSION_GRANTED) {
11604            throw new SecurityException("viewquires permission "
11605                    + android.Manifest.permission.STOP_APP_SWITCHES);
11606        }
11607
11608        synchronized(this) {
11609            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11610                    + APP_SWITCH_DELAY_TIME;
11611            mDidAppSwitch = false;
11612            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11613            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11614            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11615        }
11616    }
11617
11618    public void resumeAppSwitches() {
11619        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11620                != PackageManager.PERMISSION_GRANTED) {
11621            throw new SecurityException("Requires permission "
11622                    + android.Manifest.permission.STOP_APP_SWITCHES);
11623        }
11624
11625        synchronized(this) {
11626            // Note that we don't execute any pending app switches... we will
11627            // let those wait until either the timeout, or the next start
11628            // activity request.
11629            mAppSwitchesAllowedTime = 0;
11630        }
11631    }
11632
11633    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11634            int callingPid, int callingUid, String name) {
11635        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11636            return true;
11637        }
11638
11639        int perm = checkComponentPermission(
11640                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11641                sourceUid, -1, true);
11642        if (perm == PackageManager.PERMISSION_GRANTED) {
11643            return true;
11644        }
11645
11646        // If the actual IPC caller is different from the logical source, then
11647        // also see if they are allowed to control app switches.
11648        if (callingUid != -1 && callingUid != sourceUid) {
11649            perm = checkComponentPermission(
11650                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11651                    callingUid, -1, true);
11652            if (perm == PackageManager.PERMISSION_GRANTED) {
11653                return true;
11654            }
11655        }
11656
11657        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11658        return false;
11659    }
11660
11661    public void setDebugApp(String packageName, boolean waitForDebugger,
11662            boolean persistent) {
11663        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11664                "setDebugApp()");
11665
11666        long ident = Binder.clearCallingIdentity();
11667        try {
11668            // Note that this is not really thread safe if there are multiple
11669            // callers into it at the same time, but that's not a situation we
11670            // care about.
11671            if (persistent) {
11672                final ContentResolver resolver = mContext.getContentResolver();
11673                Settings.Global.putString(
11674                    resolver, Settings.Global.DEBUG_APP,
11675                    packageName);
11676                Settings.Global.putInt(
11677                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11678                    waitForDebugger ? 1 : 0);
11679            }
11680
11681            synchronized (this) {
11682                if (!persistent) {
11683                    mOrigDebugApp = mDebugApp;
11684                    mOrigWaitForDebugger = mWaitForDebugger;
11685                }
11686                mDebugApp = packageName;
11687                mWaitForDebugger = waitForDebugger;
11688                mDebugTransient = !persistent;
11689                if (packageName != null) {
11690                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11691                            false, UserHandle.USER_ALL, "set debug app");
11692                }
11693            }
11694        } finally {
11695            Binder.restoreCallingIdentity(ident);
11696        }
11697    }
11698
11699    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11700        synchronized (this) {
11701            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11702            if (!isDebuggable) {
11703                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11704                    throw new SecurityException("Process not debuggable: " + app.packageName);
11705                }
11706            }
11707
11708            mTrackAllocationApp = processName;
11709        }
11710    }
11711
11712    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11713        synchronized (this) {
11714            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11715            if (!isDebuggable) {
11716                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11717                    throw new SecurityException("Process not debuggable: " + app.packageName);
11718                }
11719            }
11720            mProfileApp = processName;
11721            mProfileFile = profilerInfo.profileFile;
11722            if (mProfileFd != null) {
11723                try {
11724                    mProfileFd.close();
11725                } catch (IOException e) {
11726                }
11727                mProfileFd = null;
11728            }
11729            mProfileFd = profilerInfo.profileFd;
11730            mSamplingInterval = profilerInfo.samplingInterval;
11731            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11732            mProfileType = 0;
11733        }
11734    }
11735
11736    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11737        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11738        if (!isDebuggable) {
11739            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11740                throw new SecurityException("Process not debuggable: " + app.packageName);
11741            }
11742        }
11743        mNativeDebuggingApp = processName;
11744    }
11745
11746    @Override
11747    public void setAlwaysFinish(boolean enabled) {
11748        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11749                "setAlwaysFinish()");
11750
11751        long ident = Binder.clearCallingIdentity();
11752        try {
11753            Settings.Global.putInt(
11754                    mContext.getContentResolver(),
11755                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11756
11757            synchronized (this) {
11758                mAlwaysFinishActivities = enabled;
11759            }
11760        } finally {
11761            Binder.restoreCallingIdentity(ident);
11762        }
11763    }
11764
11765    @Override
11766    public void setLenientBackgroundCheck(boolean enabled) {
11767        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11768                "setLenientBackgroundCheck()");
11769
11770        long ident = Binder.clearCallingIdentity();
11771        try {
11772            Settings.Global.putInt(
11773                    mContext.getContentResolver(),
11774                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11775
11776            synchronized (this) {
11777                mLenientBackgroundCheck = enabled;
11778            }
11779        } finally {
11780            Binder.restoreCallingIdentity(ident);
11781        }
11782    }
11783
11784    @Override
11785    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11786        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11787                "setActivityController()");
11788        synchronized (this) {
11789            mController = controller;
11790            mControllerIsAMonkey = imAMonkey;
11791            Watchdog.getInstance().setActivityController(controller);
11792        }
11793    }
11794
11795    @Override
11796    public void setUserIsMonkey(boolean userIsMonkey) {
11797        synchronized (this) {
11798            synchronized (mPidsSelfLocked) {
11799                final int callingPid = Binder.getCallingPid();
11800                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11801                if (precessRecord == null) {
11802                    throw new SecurityException("Unknown process: " + callingPid);
11803                }
11804                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11805                    throw new SecurityException("Only an instrumentation process "
11806                            + "with a UiAutomation can call setUserIsMonkey");
11807                }
11808            }
11809            mUserIsMonkey = userIsMonkey;
11810        }
11811    }
11812
11813    @Override
11814    public boolean isUserAMonkey() {
11815        synchronized (this) {
11816            // If there is a controller also implies the user is a monkey.
11817            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11818        }
11819    }
11820
11821    public void requestBugReport(int bugreportType) {
11822        String service = null;
11823        switch (bugreportType) {
11824            case ActivityManager.BUGREPORT_OPTION_FULL:
11825                service = "bugreport";
11826                break;
11827            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11828                service = "bugreportplus";
11829                break;
11830            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11831                service = "bugreportremote";
11832                break;
11833        }
11834        if (service == null) {
11835            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11836                    + bugreportType);
11837        }
11838        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11839        SystemProperties.set("ctl.start", service);
11840    }
11841
11842    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11843        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11844    }
11845
11846    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11847        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11848            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11849        }
11850        return KEY_DISPATCHING_TIMEOUT;
11851    }
11852
11853    @Override
11854    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11855        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11856                != PackageManager.PERMISSION_GRANTED) {
11857            throw new SecurityException("Requires permission "
11858                    + android.Manifest.permission.FILTER_EVENTS);
11859        }
11860        ProcessRecord proc;
11861        long timeout;
11862        synchronized (this) {
11863            synchronized (mPidsSelfLocked) {
11864                proc = mPidsSelfLocked.get(pid);
11865            }
11866            timeout = getInputDispatchingTimeoutLocked(proc);
11867        }
11868
11869        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11870            return -1;
11871        }
11872
11873        return timeout;
11874    }
11875
11876    /**
11877     * Handle input dispatching timeouts.
11878     * Returns whether input dispatching should be aborted or not.
11879     */
11880    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11881            final ActivityRecord activity, final ActivityRecord parent,
11882            final boolean aboveSystem, String reason) {
11883        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11884                != PackageManager.PERMISSION_GRANTED) {
11885            throw new SecurityException("Requires permission "
11886                    + android.Manifest.permission.FILTER_EVENTS);
11887        }
11888
11889        final String annotation;
11890        if (reason == null) {
11891            annotation = "Input dispatching timed out";
11892        } else {
11893            annotation = "Input dispatching timed out (" + reason + ")";
11894        }
11895
11896        if (proc != null) {
11897            synchronized (this) {
11898                if (proc.debugging) {
11899                    return false;
11900                }
11901
11902                if (mDidDexOpt) {
11903                    // Give more time since we were dexopting.
11904                    mDidDexOpt = false;
11905                    return false;
11906                }
11907
11908                if (proc.instrumentationClass != null) {
11909                    Bundle info = new Bundle();
11910                    info.putString("shortMsg", "keyDispatchingTimedOut");
11911                    info.putString("longMsg", annotation);
11912                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11913                    return true;
11914                }
11915            }
11916            mHandler.post(new Runnable() {
11917                @Override
11918                public void run() {
11919                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11920                }
11921            });
11922        }
11923
11924        return true;
11925    }
11926
11927    @Override
11928    public Bundle getAssistContextExtras(int requestType) {
11929        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11930                null, null, true /* focused */, true /* newSessionId */,
11931                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11932        if (pae == null) {
11933            return null;
11934        }
11935        synchronized (pae) {
11936            while (!pae.haveResult) {
11937                try {
11938                    pae.wait();
11939                } catch (InterruptedException e) {
11940                }
11941            }
11942        }
11943        synchronized (this) {
11944            buildAssistBundleLocked(pae, pae.result);
11945            mPendingAssistExtras.remove(pae);
11946            mUiHandler.removeCallbacks(pae);
11947        }
11948        return pae.extras;
11949    }
11950
11951    @Override
11952    public boolean isAssistDataAllowedOnCurrentActivity() {
11953        int userId;
11954        synchronized (this) {
11955            userId = mUserController.getCurrentUserIdLocked();
11956            ActivityRecord activity = getFocusedStack().topActivity();
11957            if (activity == null) {
11958                return false;
11959            }
11960            userId = activity.userId;
11961        }
11962        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11963                Context.DEVICE_POLICY_SERVICE);
11964        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11965    }
11966
11967    @Override
11968    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11969        long ident = Binder.clearCallingIdentity();
11970        try {
11971            synchronized (this) {
11972                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11973                ActivityRecord top = getFocusedStack().topActivity();
11974                if (top != caller) {
11975                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11976                            + " is not current top " + top);
11977                    return false;
11978                }
11979                if (!top.nowVisible) {
11980                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11981                            + " is not visible");
11982                    return false;
11983                }
11984            }
11985            AssistUtils utils = new AssistUtils(mContext);
11986            return utils.showSessionForActiveService(args,
11987                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11988        } finally {
11989            Binder.restoreCallingIdentity(ident);
11990        }
11991    }
11992
11993    @Override
11994    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11995            Bundle receiverExtras,
11996            IBinder activityToken, boolean focused, boolean newSessionId) {
11997        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11998                activityToken, focused, newSessionId,
11999                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12000                != null;
12001    }
12002
12003    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12004            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12005            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12006        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12007                "enqueueAssistContext()");
12008        synchronized (this) {
12009            ActivityRecord activity = getFocusedStack().topActivity();
12010            if (activity == null) {
12011                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12012                return null;
12013            }
12014            if (activity.app == null || activity.app.thread == null) {
12015                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12016                return null;
12017            }
12018            if (focused) {
12019                if (activityToken != null) {
12020                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12021                    if (activity != caller) {
12022                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12023                                + " is not current top " + activity);
12024                        return null;
12025                    }
12026                }
12027            } else {
12028                activity = ActivityRecord.forTokenLocked(activityToken);
12029                if (activity == null) {
12030                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12031                            + " couldn't be found");
12032                    return null;
12033                }
12034            }
12035
12036            PendingAssistExtras pae;
12037            Bundle extras = new Bundle();
12038            if (args != null) {
12039                extras.putAll(args);
12040            }
12041            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12042            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12043            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12044                    userHandle);
12045            // Increment the sessionId if necessary
12046            if (newSessionId) {
12047                mViSessionId++;
12048            }
12049            try {
12050                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12051                        requestType, mViSessionId);
12052                mPendingAssistExtras.add(pae);
12053                mUiHandler.postDelayed(pae, timeout);
12054            } catch (RemoteException e) {
12055                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12056                return null;
12057            }
12058            return pae;
12059        }
12060    }
12061
12062    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12063        IResultReceiver receiver;
12064        synchronized (this) {
12065            mPendingAssistExtras.remove(pae);
12066            receiver = pae.receiver;
12067        }
12068        if (receiver != null) {
12069            // Caller wants result sent back to them.
12070            Bundle sendBundle = new Bundle();
12071            // At least return the receiver extras
12072            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12073                    pae.receiverExtras);
12074            try {
12075                pae.receiver.send(0, sendBundle);
12076            } catch (RemoteException e) {
12077            }
12078        }
12079    }
12080
12081    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12082        if (result != null) {
12083            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12084        }
12085        if (pae.hint != null) {
12086            pae.extras.putBoolean(pae.hint, true);
12087        }
12088    }
12089
12090    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12091            AssistContent content, Uri referrer) {
12092        PendingAssistExtras pae = (PendingAssistExtras)token;
12093        synchronized (pae) {
12094            pae.result = extras;
12095            pae.structure = structure;
12096            pae.content = content;
12097            if (referrer != null) {
12098                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12099            }
12100            pae.haveResult = true;
12101            pae.notifyAll();
12102            if (pae.intent == null && pae.receiver == null) {
12103                // Caller is just waiting for the result.
12104                return;
12105            }
12106        }
12107
12108        // We are now ready to launch the assist activity.
12109        IResultReceiver sendReceiver = null;
12110        Bundle sendBundle = null;
12111        synchronized (this) {
12112            buildAssistBundleLocked(pae, extras);
12113            boolean exists = mPendingAssistExtras.remove(pae);
12114            mUiHandler.removeCallbacks(pae);
12115            if (!exists) {
12116                // Timed out.
12117                return;
12118            }
12119            if ((sendReceiver=pae.receiver) != null) {
12120                // Caller wants result sent back to them.
12121                sendBundle = new Bundle();
12122                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12123                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12124                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12125                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12126                        pae.receiverExtras);
12127            }
12128        }
12129        if (sendReceiver != null) {
12130            try {
12131                sendReceiver.send(0, sendBundle);
12132            } catch (RemoteException e) {
12133            }
12134            return;
12135        }
12136
12137        long ident = Binder.clearCallingIdentity();
12138        try {
12139            pae.intent.replaceExtras(pae.extras);
12140            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12141                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12142                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12143            closeSystemDialogs("assist");
12144            try {
12145                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12146            } catch (ActivityNotFoundException e) {
12147                Slog.w(TAG, "No activity to handle assist action.", e);
12148            }
12149        } finally {
12150            Binder.restoreCallingIdentity(ident);
12151        }
12152    }
12153
12154    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12155            Bundle args) {
12156        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12157                true /* focused */, true /* newSessionId */,
12158                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12159    }
12160
12161    public void registerProcessObserver(IProcessObserver observer) {
12162        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12163                "registerProcessObserver()");
12164        synchronized (this) {
12165            mProcessObservers.register(observer);
12166        }
12167    }
12168
12169    @Override
12170    public void unregisterProcessObserver(IProcessObserver observer) {
12171        synchronized (this) {
12172            mProcessObservers.unregister(observer);
12173        }
12174    }
12175
12176    @Override
12177    public void registerUidObserver(IUidObserver observer, int which) {
12178        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12179                "registerUidObserver()");
12180        synchronized (this) {
12181            mUidObservers.register(observer, which);
12182        }
12183    }
12184
12185    @Override
12186    public void unregisterUidObserver(IUidObserver observer) {
12187        synchronized (this) {
12188            mUidObservers.unregister(observer);
12189        }
12190    }
12191
12192    @Override
12193    public boolean convertFromTranslucent(IBinder token) {
12194        final long origId = Binder.clearCallingIdentity();
12195        try {
12196            synchronized (this) {
12197                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12198                if (r == null) {
12199                    return false;
12200                }
12201                final boolean translucentChanged = r.changeWindowTranslucency(true);
12202                if (translucentChanged) {
12203                    r.task.stack.releaseBackgroundResources(r);
12204                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12205                }
12206                mWindowManager.setAppFullscreen(token, true);
12207                return translucentChanged;
12208            }
12209        } finally {
12210            Binder.restoreCallingIdentity(origId);
12211        }
12212    }
12213
12214    @Override
12215    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12216        final long origId = Binder.clearCallingIdentity();
12217        try {
12218            synchronized (this) {
12219                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12220                if (r == null) {
12221                    return false;
12222                }
12223                int index = r.task.mActivities.lastIndexOf(r);
12224                if (index > 0) {
12225                    ActivityRecord under = r.task.mActivities.get(index - 1);
12226                    under.returningOptions = options;
12227                }
12228                final boolean translucentChanged = r.changeWindowTranslucency(false);
12229                if (translucentChanged) {
12230                    r.task.stack.convertActivityToTranslucent(r);
12231                }
12232                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12233                mWindowManager.setAppFullscreen(token, false);
12234                return translucentChanged;
12235            }
12236        } finally {
12237            Binder.restoreCallingIdentity(origId);
12238        }
12239    }
12240
12241    @Override
12242    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12243        final long origId = Binder.clearCallingIdentity();
12244        try {
12245            synchronized (this) {
12246                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12247                if (r != null) {
12248                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12249                }
12250            }
12251            return false;
12252        } finally {
12253            Binder.restoreCallingIdentity(origId);
12254        }
12255    }
12256
12257    @Override
12258    public boolean isBackgroundVisibleBehind(IBinder token) {
12259        final long origId = Binder.clearCallingIdentity();
12260        try {
12261            synchronized (this) {
12262                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12263                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12264                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12265                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12266                return visible;
12267            }
12268        } finally {
12269            Binder.restoreCallingIdentity(origId);
12270        }
12271    }
12272
12273    @Override
12274    public ActivityOptions getActivityOptions(IBinder token) {
12275        final long origId = Binder.clearCallingIdentity();
12276        try {
12277            synchronized (this) {
12278                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12279                if (r != null) {
12280                    final ActivityOptions activityOptions = r.pendingOptions;
12281                    r.pendingOptions = null;
12282                    return activityOptions;
12283                }
12284                return null;
12285            }
12286        } finally {
12287            Binder.restoreCallingIdentity(origId);
12288        }
12289    }
12290
12291    @Override
12292    public void setImmersive(IBinder token, boolean immersive) {
12293        synchronized(this) {
12294            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12295            if (r == null) {
12296                throw new IllegalArgumentException();
12297            }
12298            r.immersive = immersive;
12299
12300            // update associated state if we're frontmost
12301            if (r == mFocusedActivity) {
12302                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12303                applyUpdateLockStateLocked(r);
12304            }
12305        }
12306    }
12307
12308    @Override
12309    public boolean isImmersive(IBinder token) {
12310        synchronized (this) {
12311            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12312            if (r == null) {
12313                throw new IllegalArgumentException();
12314            }
12315            return r.immersive;
12316        }
12317    }
12318
12319    @Override
12320    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12321        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12322            throw new UnsupportedOperationException("VR mode not supported on this device!");
12323        }
12324
12325        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12326
12327        ActivityRecord r;
12328        synchronized (this) {
12329            r = ActivityRecord.isInStackLocked(token);
12330        }
12331
12332        if (r == null) {
12333            throw new IllegalArgumentException();
12334        }
12335
12336        int err;
12337        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12338                VrManagerInternal.NO_ERROR) {
12339            return err;
12340        }
12341
12342        synchronized(this) {
12343            r.requestedVrComponent = (enabled) ? packageName : null;
12344
12345            // Update associated state if this activity is currently focused
12346            if (r == mFocusedActivity) {
12347                applyUpdateVrModeLocked(r);
12348            }
12349            return 0;
12350        }
12351    }
12352
12353    @Override
12354    public boolean isVrModePackageEnabled(ComponentName packageName) {
12355        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12356            throw new UnsupportedOperationException("VR mode not supported on this device!");
12357        }
12358
12359        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12360
12361        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12362                VrManagerInternal.NO_ERROR;
12363    }
12364
12365    public boolean isTopActivityImmersive() {
12366        enforceNotIsolatedCaller("startActivity");
12367        synchronized (this) {
12368            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12369            return (r != null) ? r.immersive : false;
12370        }
12371    }
12372
12373    @Override
12374    public boolean isTopOfTask(IBinder token) {
12375        synchronized (this) {
12376            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12377            if (r == null) {
12378                throw new IllegalArgumentException();
12379            }
12380            return r.task.getTopActivity() == r;
12381        }
12382    }
12383
12384    public final void enterSafeMode() {
12385        synchronized(this) {
12386            // It only makes sense to do this before the system is ready
12387            // and started launching other packages.
12388            if (!mSystemReady) {
12389                try {
12390                    AppGlobals.getPackageManager().enterSafeMode();
12391                } catch (RemoteException e) {
12392                }
12393            }
12394
12395            mSafeMode = true;
12396        }
12397    }
12398
12399    public final void showSafeModeOverlay() {
12400        View v = LayoutInflater.from(mContext).inflate(
12401                com.android.internal.R.layout.safe_mode, null);
12402        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12403        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12404        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12405        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12406        lp.gravity = Gravity.BOTTOM | Gravity.START;
12407        lp.format = v.getBackground().getOpacity();
12408        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12409                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12410        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12411        ((WindowManager)mContext.getSystemService(
12412                Context.WINDOW_SERVICE)).addView(v, lp);
12413    }
12414
12415    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12416        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12417            return;
12418        }
12419        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12420        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12421        synchronized (stats) {
12422            if (mBatteryStatsService.isOnBattery()) {
12423                mBatteryStatsService.enforceCallingPermission();
12424                int MY_UID = Binder.getCallingUid();
12425                final int uid;
12426                if (sender == null) {
12427                    uid = sourceUid;
12428                } else {
12429                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12430                }
12431                BatteryStatsImpl.Uid.Pkg pkg =
12432                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12433                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12434                pkg.noteWakeupAlarmLocked(tag);
12435            }
12436        }
12437    }
12438
12439    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12440        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12441            return;
12442        }
12443        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12444        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12445        synchronized (stats) {
12446            mBatteryStatsService.enforceCallingPermission();
12447            int MY_UID = Binder.getCallingUid();
12448            final int uid;
12449            if (sender == null) {
12450                uid = sourceUid;
12451            } else {
12452                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12453            }
12454            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12455        }
12456    }
12457
12458    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12459        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12460            return;
12461        }
12462        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12463        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12464        synchronized (stats) {
12465            mBatteryStatsService.enforceCallingPermission();
12466            int MY_UID = Binder.getCallingUid();
12467            final int uid;
12468            if (sender == null) {
12469                uid = sourceUid;
12470            } else {
12471                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12472            }
12473            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12474        }
12475    }
12476
12477    public boolean killPids(int[] pids, String pReason, boolean secure) {
12478        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12479            throw new SecurityException("killPids only available to the system");
12480        }
12481        String reason = (pReason == null) ? "Unknown" : pReason;
12482        // XXX Note: don't acquire main activity lock here, because the window
12483        // manager calls in with its locks held.
12484
12485        boolean killed = false;
12486        synchronized (mPidsSelfLocked) {
12487            int worstType = 0;
12488            for (int i=0; i<pids.length; i++) {
12489                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12490                if (proc != null) {
12491                    int type = proc.setAdj;
12492                    if (type > worstType) {
12493                        worstType = type;
12494                    }
12495                }
12496            }
12497
12498            // If the worst oom_adj is somewhere in the cached proc LRU range,
12499            // then constrain it so we will kill all cached procs.
12500            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12501                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12502                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12503            }
12504
12505            // If this is not a secure call, don't let it kill processes that
12506            // are important.
12507            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12508                worstType = ProcessList.SERVICE_ADJ;
12509            }
12510
12511            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12512            for (int i=0; i<pids.length; i++) {
12513                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12514                if (proc == null) {
12515                    continue;
12516                }
12517                int adj = proc.setAdj;
12518                if (adj >= worstType && !proc.killedByAm) {
12519                    proc.kill(reason, true);
12520                    killed = true;
12521                }
12522            }
12523        }
12524        return killed;
12525    }
12526
12527    @Override
12528    public void killUid(int appId, int userId, String reason) {
12529        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12530        synchronized (this) {
12531            final long identity = Binder.clearCallingIdentity();
12532            try {
12533                killPackageProcessesLocked(null, appId, userId,
12534                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12535                        reason != null ? reason : "kill uid");
12536            } finally {
12537                Binder.restoreCallingIdentity(identity);
12538            }
12539        }
12540    }
12541
12542    @Override
12543    public boolean killProcessesBelowForeground(String reason) {
12544        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12545            throw new SecurityException("killProcessesBelowForeground() only available to system");
12546        }
12547
12548        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12549    }
12550
12551    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12552        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12553            throw new SecurityException("killProcessesBelowAdj() only available to system");
12554        }
12555
12556        boolean killed = false;
12557        synchronized (mPidsSelfLocked) {
12558            final int size = mPidsSelfLocked.size();
12559            for (int i = 0; i < size; i++) {
12560                final int pid = mPidsSelfLocked.keyAt(i);
12561                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12562                if (proc == null) continue;
12563
12564                final int adj = proc.setAdj;
12565                if (adj > belowAdj && !proc.killedByAm) {
12566                    proc.kill(reason, true);
12567                    killed = true;
12568                }
12569            }
12570        }
12571        return killed;
12572    }
12573
12574    @Override
12575    public void hang(final IBinder who, boolean allowRestart) {
12576        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12577                != PackageManager.PERMISSION_GRANTED) {
12578            throw new SecurityException("Requires permission "
12579                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12580        }
12581
12582        final IBinder.DeathRecipient death = new DeathRecipient() {
12583            @Override
12584            public void binderDied() {
12585                synchronized (this) {
12586                    notifyAll();
12587                }
12588            }
12589        };
12590
12591        try {
12592            who.linkToDeath(death, 0);
12593        } catch (RemoteException e) {
12594            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12595            return;
12596        }
12597
12598        synchronized (this) {
12599            Watchdog.getInstance().setAllowRestart(allowRestart);
12600            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12601            synchronized (death) {
12602                while (who.isBinderAlive()) {
12603                    try {
12604                        death.wait();
12605                    } catch (InterruptedException e) {
12606                    }
12607                }
12608            }
12609            Watchdog.getInstance().setAllowRestart(true);
12610        }
12611    }
12612
12613    @Override
12614    public void restart() {
12615        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12616                != PackageManager.PERMISSION_GRANTED) {
12617            throw new SecurityException("Requires permission "
12618                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12619        }
12620
12621        Log.i(TAG, "Sending shutdown broadcast...");
12622
12623        BroadcastReceiver br = new BroadcastReceiver() {
12624            @Override public void onReceive(Context context, Intent intent) {
12625                // Now the broadcast is done, finish up the low-level shutdown.
12626                Log.i(TAG, "Shutting down activity manager...");
12627                shutdown(10000);
12628                Log.i(TAG, "Shutdown complete, restarting!");
12629                Process.killProcess(Process.myPid());
12630                System.exit(10);
12631            }
12632        };
12633
12634        // First send the high-level shut down broadcast.
12635        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12636        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12637        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12638        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12639        mContext.sendOrderedBroadcastAsUser(intent,
12640                UserHandle.ALL, null, br, mHandler, 0, null, null);
12641        */
12642        br.onReceive(mContext, intent);
12643    }
12644
12645    private long getLowRamTimeSinceIdle(long now) {
12646        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12647    }
12648
12649    @Override
12650    public void performIdleMaintenance() {
12651        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12652                != PackageManager.PERMISSION_GRANTED) {
12653            throw new SecurityException("Requires permission "
12654                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12655        }
12656
12657        synchronized (this) {
12658            final long now = SystemClock.uptimeMillis();
12659            final long timeSinceLastIdle = now - mLastIdleTime;
12660            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12661            mLastIdleTime = now;
12662            mLowRamTimeSinceLastIdle = 0;
12663            if (mLowRamStartTime != 0) {
12664                mLowRamStartTime = now;
12665            }
12666
12667            StringBuilder sb = new StringBuilder(128);
12668            sb.append("Idle maintenance over ");
12669            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12670            sb.append(" low RAM for ");
12671            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12672            Slog.i(TAG, sb.toString());
12673
12674            // If at least 1/3 of our time since the last idle period has been spent
12675            // with RAM low, then we want to kill processes.
12676            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12677
12678            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12679                ProcessRecord proc = mLruProcesses.get(i);
12680                if (proc.notCachedSinceIdle) {
12681                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12682                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12683                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12684                        if (doKilling && proc.initialIdlePss != 0
12685                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12686                            sb = new StringBuilder(128);
12687                            sb.append("Kill");
12688                            sb.append(proc.processName);
12689                            sb.append(" in idle maint: pss=");
12690                            sb.append(proc.lastPss);
12691                            sb.append(", swapPss=");
12692                            sb.append(proc.lastSwapPss);
12693                            sb.append(", initialPss=");
12694                            sb.append(proc.initialIdlePss);
12695                            sb.append(", period=");
12696                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12697                            sb.append(", lowRamPeriod=");
12698                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12699                            Slog.wtfQuiet(TAG, sb.toString());
12700                            proc.kill("idle maint (pss " + proc.lastPss
12701                                    + " from " + proc.initialIdlePss + ")", true);
12702                        }
12703                    }
12704                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12705                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12706                    proc.notCachedSinceIdle = true;
12707                    proc.initialIdlePss = 0;
12708                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12709                            mTestPssMode, isSleeping(), now);
12710                }
12711            }
12712
12713            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12714            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12715        }
12716    }
12717
12718    @Override
12719    public void sendIdleJobTrigger() {
12720        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12721                != PackageManager.PERMISSION_GRANTED) {
12722            throw new SecurityException("Requires permission "
12723                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12724        }
12725
12726        final long ident = Binder.clearCallingIdentity();
12727        try {
12728            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12729                    .setPackage("android")
12730                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12731            broadcastIntent(null, intent, null, null, 0, null, null, null,
12732                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12733        } finally {
12734            Binder.restoreCallingIdentity(ident);
12735        }
12736    }
12737
12738    private void retrieveSettings() {
12739        final ContentResolver resolver = mContext.getContentResolver();
12740        final boolean freeformWindowManagement =
12741                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12742                        || Settings.Global.getInt(
12743                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12744        final boolean supportsPictureInPicture =
12745                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12746
12747        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12748        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12749        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12750        final boolean alwaysFinishActivities =
12751                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12752        final boolean lenientBackgroundCheck =
12753                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12754        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12755        final boolean forceResizable = Settings.Global.getInt(
12756                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12757        // Transfer any global setting for forcing RTL layout, into a System Property
12758        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12759
12760        final Configuration configuration = new Configuration();
12761        Settings.System.getConfiguration(resolver, configuration);
12762        if (forceRtl) {
12763            // This will take care of setting the correct layout direction flags
12764            configuration.setLayoutDirection(configuration.locale);
12765        }
12766
12767        synchronized (this) {
12768            mDebugApp = mOrigDebugApp = debugApp;
12769            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12770            mAlwaysFinishActivities = alwaysFinishActivities;
12771            mLenientBackgroundCheck = lenientBackgroundCheck;
12772            mForceResizableActivities = forceResizable;
12773            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12774            if (supportsMultiWindow || forceResizable) {
12775                mSupportsMultiWindow = true;
12776                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12777                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12778            } else {
12779                mSupportsMultiWindow = false;
12780                mSupportsFreeformWindowManagement = false;
12781                mSupportsPictureInPicture = false;
12782            }
12783            // This happens before any activities are started, so we can
12784            // change mConfiguration in-place.
12785            updateConfigurationLocked(configuration, null, true);
12786            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12787                    "Initial config: " + mConfiguration);
12788
12789            // Load resources only after the current configuration has been set.
12790            final Resources res = mContext.getResources();
12791            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12792            mThumbnailWidth = res.getDimensionPixelSize(
12793                    com.android.internal.R.dimen.thumbnail_width);
12794            mThumbnailHeight = res.getDimensionPixelSize(
12795                    com.android.internal.R.dimen.thumbnail_height);
12796            mFullscreenThumbnailScale = res.getFraction(
12797                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12798            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12799                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12800            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12801                    com.android.internal.R.string.config_appsNotReportingCrashes));
12802        }
12803    }
12804
12805    public boolean testIsSystemReady() {
12806        // no need to synchronize(this) just to read & return the value
12807        return mSystemReady;
12808    }
12809
12810    public void systemReady(final Runnable goingCallback) {
12811        synchronized(this) {
12812            if (mSystemReady) {
12813                // If we're done calling all the receivers, run the next "boot phase" passed in
12814                // by the SystemServer
12815                if (goingCallback != null) {
12816                    goingCallback.run();
12817                }
12818                return;
12819            }
12820
12821            mLocalDeviceIdleController
12822                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12823
12824            // Make sure we have the current profile info, since it is needed for security checks.
12825            mUserController.onSystemReady();
12826            mRecentTasks.onSystemReadyLocked();
12827            mAppOpsService.systemReady();
12828            mSystemReady = true;
12829        }
12830
12831        ArrayList<ProcessRecord> procsToKill = null;
12832        synchronized(mPidsSelfLocked) {
12833            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12834                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12835                if (!isAllowedWhileBooting(proc.info)){
12836                    if (procsToKill == null) {
12837                        procsToKill = new ArrayList<ProcessRecord>();
12838                    }
12839                    procsToKill.add(proc);
12840                }
12841            }
12842        }
12843
12844        synchronized(this) {
12845            if (procsToKill != null) {
12846                for (int i=procsToKill.size()-1; i>=0; i--) {
12847                    ProcessRecord proc = procsToKill.get(i);
12848                    Slog.i(TAG, "Removing system update proc: " + proc);
12849                    removeProcessLocked(proc, true, false, "system update done");
12850                }
12851            }
12852
12853            // Now that we have cleaned up any update processes, we
12854            // are ready to start launching real processes and know that
12855            // we won't trample on them any more.
12856            mProcessesReady = true;
12857        }
12858
12859        Slog.i(TAG, "System now ready");
12860        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12861            SystemClock.uptimeMillis());
12862
12863        synchronized(this) {
12864            // Make sure we have no pre-ready processes sitting around.
12865
12866            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12867                ResolveInfo ri = mContext.getPackageManager()
12868                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12869                                STOCK_PM_FLAGS);
12870                CharSequence errorMsg = null;
12871                if (ri != null) {
12872                    ActivityInfo ai = ri.activityInfo;
12873                    ApplicationInfo app = ai.applicationInfo;
12874                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12875                        mTopAction = Intent.ACTION_FACTORY_TEST;
12876                        mTopData = null;
12877                        mTopComponent = new ComponentName(app.packageName,
12878                                ai.name);
12879                    } else {
12880                        errorMsg = mContext.getResources().getText(
12881                                com.android.internal.R.string.factorytest_not_system);
12882                    }
12883                } else {
12884                    errorMsg = mContext.getResources().getText(
12885                            com.android.internal.R.string.factorytest_no_action);
12886                }
12887                if (errorMsg != null) {
12888                    mTopAction = null;
12889                    mTopData = null;
12890                    mTopComponent = null;
12891                    Message msg = Message.obtain();
12892                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12893                    msg.getData().putCharSequence("msg", errorMsg);
12894                    mUiHandler.sendMessage(msg);
12895                }
12896            }
12897        }
12898
12899        retrieveSettings();
12900        final int currentUserId;
12901        synchronized (this) {
12902            currentUserId = mUserController.getCurrentUserIdLocked();
12903            readGrantedUriPermissionsLocked();
12904        }
12905
12906        if (goingCallback != null) goingCallback.run();
12907
12908        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12909                Integer.toString(currentUserId), currentUserId);
12910        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12911                Integer.toString(currentUserId), currentUserId);
12912        mSystemServiceManager.startUser(currentUserId);
12913
12914        synchronized (this) {
12915            // Only start up encryption-aware persistent apps; once user is
12916            // unlocked we'll come back around and start unaware apps
12917            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12918
12919            // Start up initial activity.
12920            mBooting = true;
12921            // Enable home activity for system user, so that the system can always boot
12922            if (UserManager.isSplitSystemUser()) {
12923                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12924                try {
12925                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12926                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12927                            UserHandle.USER_SYSTEM);
12928                } catch (RemoteException e) {
12929                    throw e.rethrowAsRuntimeException();
12930                }
12931            }
12932            startHomeActivityLocked(currentUserId, "systemReady");
12933
12934            try {
12935                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12936                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12937                            + " data partition or your device will be unstable.");
12938                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12939                }
12940            } catch (RemoteException e) {
12941            }
12942
12943            if (!Build.isBuildConsistent()) {
12944                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12945                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12946            }
12947
12948            long ident = Binder.clearCallingIdentity();
12949            try {
12950                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12951                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12952                        | Intent.FLAG_RECEIVER_FOREGROUND);
12953                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12954                broadcastIntentLocked(null, null, intent,
12955                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12956                        null, false, false, MY_PID, Process.SYSTEM_UID,
12957                        currentUserId);
12958                intent = new Intent(Intent.ACTION_USER_STARTING);
12959                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12960                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12961                broadcastIntentLocked(null, null, intent,
12962                        null, new IIntentReceiver.Stub() {
12963                            @Override
12964                            public void performReceive(Intent intent, int resultCode, String data,
12965                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12966                                    throws RemoteException {
12967                            }
12968                        }, 0, null, null,
12969                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12970                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12971            } catch (Throwable t) {
12972                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12973            } finally {
12974                Binder.restoreCallingIdentity(ident);
12975            }
12976            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12977            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12978        }
12979    }
12980
12981    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12982        synchronized (this) {
12983            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12984        }
12985    }
12986
12987    void skipCurrentReceiverLocked(ProcessRecord app) {
12988        for (BroadcastQueue queue : mBroadcastQueues) {
12989            queue.skipCurrentReceiverLocked(app);
12990        }
12991    }
12992
12993    /**
12994     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12995     * The application process will exit immediately after this call returns.
12996     * @param app object of the crashing app, null for the system server
12997     * @param crashInfo describing the exception
12998     */
12999    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13000        ProcessRecord r = findAppProcess(app, "Crash");
13001        final String processName = app == null ? "system_server"
13002                : (r == null ? "unknown" : r.processName);
13003
13004        handleApplicationCrashInner("crash", r, processName, crashInfo);
13005    }
13006
13007    /* Native crash reporting uses this inner version because it needs to be somewhat
13008     * decoupled from the AM-managed cleanup lifecycle
13009     */
13010    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13011            ApplicationErrorReport.CrashInfo crashInfo) {
13012        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13013                UserHandle.getUserId(Binder.getCallingUid()), processName,
13014                r == null ? -1 : r.info.flags,
13015                crashInfo.exceptionClassName,
13016                crashInfo.exceptionMessage,
13017                crashInfo.throwFileName,
13018                crashInfo.throwLineNumber);
13019
13020        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13021
13022        mAppErrors.crashApplication(r, crashInfo);
13023    }
13024
13025    public void handleApplicationStrictModeViolation(
13026            IBinder app,
13027            int violationMask,
13028            StrictMode.ViolationInfo info) {
13029        ProcessRecord r = findAppProcess(app, "StrictMode");
13030        if (r == null) {
13031            return;
13032        }
13033
13034        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13035            Integer stackFingerprint = info.hashCode();
13036            boolean logIt = true;
13037            synchronized (mAlreadyLoggedViolatedStacks) {
13038                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13039                    logIt = false;
13040                    // TODO: sub-sample into EventLog for these, with
13041                    // the info.durationMillis?  Then we'd get
13042                    // the relative pain numbers, without logging all
13043                    // the stack traces repeatedly.  We'd want to do
13044                    // likewise in the client code, which also does
13045                    // dup suppression, before the Binder call.
13046                } else {
13047                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13048                        mAlreadyLoggedViolatedStacks.clear();
13049                    }
13050                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13051                }
13052            }
13053            if (logIt) {
13054                logStrictModeViolationToDropBox(r, info);
13055            }
13056        }
13057
13058        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13059            AppErrorResult result = new AppErrorResult();
13060            synchronized (this) {
13061                final long origId = Binder.clearCallingIdentity();
13062
13063                Message msg = Message.obtain();
13064                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13065                HashMap<String, Object> data = new HashMap<String, Object>();
13066                data.put("result", result);
13067                data.put("app", r);
13068                data.put("violationMask", violationMask);
13069                data.put("info", info);
13070                msg.obj = data;
13071                mUiHandler.sendMessage(msg);
13072
13073                Binder.restoreCallingIdentity(origId);
13074            }
13075            int res = result.get();
13076            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13077        }
13078    }
13079
13080    // Depending on the policy in effect, there could be a bunch of
13081    // these in quick succession so we try to batch these together to
13082    // minimize disk writes, number of dropbox entries, and maximize
13083    // compression, by having more fewer, larger records.
13084    private void logStrictModeViolationToDropBox(
13085            ProcessRecord process,
13086            StrictMode.ViolationInfo info) {
13087        if (info == null) {
13088            return;
13089        }
13090        final boolean isSystemApp = process == null ||
13091                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13092                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13093        final String processName = process == null ? "unknown" : process.processName;
13094        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13095        final DropBoxManager dbox = (DropBoxManager)
13096                mContext.getSystemService(Context.DROPBOX_SERVICE);
13097
13098        // Exit early if the dropbox isn't configured to accept this report type.
13099        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13100
13101        boolean bufferWasEmpty;
13102        boolean needsFlush;
13103        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13104        synchronized (sb) {
13105            bufferWasEmpty = sb.length() == 0;
13106            appendDropBoxProcessHeaders(process, processName, sb);
13107            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13108            sb.append("System-App: ").append(isSystemApp).append("\n");
13109            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13110            if (info.violationNumThisLoop != 0) {
13111                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13112            }
13113            if (info.numAnimationsRunning != 0) {
13114                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13115            }
13116            if (info.broadcastIntentAction != null) {
13117                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13118            }
13119            if (info.durationMillis != -1) {
13120                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13121            }
13122            if (info.numInstances != -1) {
13123                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13124            }
13125            if (info.tags != null) {
13126                for (String tag : info.tags) {
13127                    sb.append("Span-Tag: ").append(tag).append("\n");
13128                }
13129            }
13130            sb.append("\n");
13131            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13132                sb.append(info.crashInfo.stackTrace);
13133                sb.append("\n");
13134            }
13135            if (info.message != null) {
13136                sb.append(info.message);
13137                sb.append("\n");
13138            }
13139
13140            // Only buffer up to ~64k.  Various logging bits truncate
13141            // things at 128k.
13142            needsFlush = (sb.length() > 64 * 1024);
13143        }
13144
13145        // Flush immediately if the buffer's grown too large, or this
13146        // is a non-system app.  Non-system apps are isolated with a
13147        // different tag & policy and not batched.
13148        //
13149        // Batching is useful during internal testing with
13150        // StrictMode settings turned up high.  Without batching,
13151        // thousands of separate files could be created on boot.
13152        if (!isSystemApp || needsFlush) {
13153            new Thread("Error dump: " + dropboxTag) {
13154                @Override
13155                public void run() {
13156                    String report;
13157                    synchronized (sb) {
13158                        report = sb.toString();
13159                        sb.delete(0, sb.length());
13160                        sb.trimToSize();
13161                    }
13162                    if (report.length() != 0) {
13163                        dbox.addText(dropboxTag, report);
13164                    }
13165                }
13166            }.start();
13167            return;
13168        }
13169
13170        // System app batching:
13171        if (!bufferWasEmpty) {
13172            // An existing dropbox-writing thread is outstanding, so
13173            // we don't need to start it up.  The existing thread will
13174            // catch the buffer appends we just did.
13175            return;
13176        }
13177
13178        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13179        // (After this point, we shouldn't access AMS internal data structures.)
13180        new Thread("Error dump: " + dropboxTag) {
13181            @Override
13182            public void run() {
13183                // 5 second sleep to let stacks arrive and be batched together
13184                try {
13185                    Thread.sleep(5000);  // 5 seconds
13186                } catch (InterruptedException e) {}
13187
13188                String errorReport;
13189                synchronized (mStrictModeBuffer) {
13190                    errorReport = mStrictModeBuffer.toString();
13191                    if (errorReport.length() == 0) {
13192                        return;
13193                    }
13194                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13195                    mStrictModeBuffer.trimToSize();
13196                }
13197                dbox.addText(dropboxTag, errorReport);
13198            }
13199        }.start();
13200    }
13201
13202    /**
13203     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13204     * @param app object of the crashing app, null for the system server
13205     * @param tag reported by the caller
13206     * @param system whether this wtf is coming from the system
13207     * @param crashInfo describing the context of the error
13208     * @return true if the process should exit immediately (WTF is fatal)
13209     */
13210    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13211            final ApplicationErrorReport.CrashInfo crashInfo) {
13212        final int callingUid = Binder.getCallingUid();
13213        final int callingPid = Binder.getCallingPid();
13214
13215        if (system) {
13216            // If this is coming from the system, we could very well have low-level
13217            // system locks held, so we want to do this all asynchronously.  And we
13218            // never want this to become fatal, so there is that too.
13219            mHandler.post(new Runnable() {
13220                @Override public void run() {
13221                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13222                }
13223            });
13224            return false;
13225        }
13226
13227        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13228                crashInfo);
13229
13230        if (r != null && r.pid != Process.myPid() &&
13231                Settings.Global.getInt(mContext.getContentResolver(),
13232                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13233            mAppErrors.crashApplication(r, crashInfo);
13234            return true;
13235        } else {
13236            return false;
13237        }
13238    }
13239
13240    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13241            final ApplicationErrorReport.CrashInfo crashInfo) {
13242        final ProcessRecord r = findAppProcess(app, "WTF");
13243        final String processName = app == null ? "system_server"
13244                : (r == null ? "unknown" : r.processName);
13245
13246        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13247                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13248
13249        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13250
13251        return r;
13252    }
13253
13254    /**
13255     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13256     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13257     */
13258    private ProcessRecord findAppProcess(IBinder app, String reason) {
13259        if (app == null) {
13260            return null;
13261        }
13262
13263        synchronized (this) {
13264            final int NP = mProcessNames.getMap().size();
13265            for (int ip=0; ip<NP; ip++) {
13266                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13267                final int NA = apps.size();
13268                for (int ia=0; ia<NA; ia++) {
13269                    ProcessRecord p = apps.valueAt(ia);
13270                    if (p.thread != null && p.thread.asBinder() == app) {
13271                        return p;
13272                    }
13273                }
13274            }
13275
13276            Slog.w(TAG, "Can't find mystery application for " + reason
13277                    + " from pid=" + Binder.getCallingPid()
13278                    + " uid=" + Binder.getCallingUid() + ": " + app);
13279            return null;
13280        }
13281    }
13282
13283    /**
13284     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13285     * to append various headers to the dropbox log text.
13286     */
13287    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13288            StringBuilder sb) {
13289        // Watchdog thread ends up invoking this function (with
13290        // a null ProcessRecord) to add the stack file to dropbox.
13291        // Do not acquire a lock on this (am) in such cases, as it
13292        // could cause a potential deadlock, if and when watchdog
13293        // is invoked due to unavailability of lock on am and it
13294        // would prevent watchdog from killing system_server.
13295        if (process == null) {
13296            sb.append("Process: ").append(processName).append("\n");
13297            return;
13298        }
13299        // Note: ProcessRecord 'process' is guarded by the service
13300        // instance.  (notably process.pkgList, which could otherwise change
13301        // concurrently during execution of this method)
13302        synchronized (this) {
13303            sb.append("Process: ").append(processName).append("\n");
13304            int flags = process.info.flags;
13305            IPackageManager pm = AppGlobals.getPackageManager();
13306            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13307            for (int ip=0; ip<process.pkgList.size(); ip++) {
13308                String pkg = process.pkgList.keyAt(ip);
13309                sb.append("Package: ").append(pkg);
13310                try {
13311                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13312                    if (pi != null) {
13313                        sb.append(" v").append(pi.versionCode);
13314                        if (pi.versionName != null) {
13315                            sb.append(" (").append(pi.versionName).append(")");
13316                        }
13317                    }
13318                } catch (RemoteException e) {
13319                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13320                }
13321                sb.append("\n");
13322            }
13323        }
13324    }
13325
13326    private static String processClass(ProcessRecord process) {
13327        if (process == null || process.pid == MY_PID) {
13328            return "system_server";
13329        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13330            return "system_app";
13331        } else {
13332            return "data_app";
13333        }
13334    }
13335
13336    private volatile long mWtfClusterStart;
13337    private volatile int mWtfClusterCount;
13338
13339    /**
13340     * Write a description of an error (crash, WTF, ANR) to the drop box.
13341     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13342     * @param process which caused the error, null means the system server
13343     * @param activity which triggered the error, null if unknown
13344     * @param parent activity related to the error, null if unknown
13345     * @param subject line related to the error, null if absent
13346     * @param report in long form describing the error, null if absent
13347     * @param logFile to include in the report, null if none
13348     * @param crashInfo giving an application stack trace, null if absent
13349     */
13350    public void addErrorToDropBox(String eventType,
13351            ProcessRecord process, String processName, ActivityRecord activity,
13352            ActivityRecord parent, String subject,
13353            final String report, final File logFile,
13354            final ApplicationErrorReport.CrashInfo crashInfo) {
13355        // NOTE -- this must never acquire the ActivityManagerService lock,
13356        // otherwise the watchdog may be prevented from resetting the system.
13357
13358        final String dropboxTag = processClass(process) + "_" + eventType;
13359        final DropBoxManager dbox = (DropBoxManager)
13360                mContext.getSystemService(Context.DROPBOX_SERVICE);
13361
13362        // Exit early if the dropbox isn't configured to accept this report type.
13363        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13364
13365        // Rate-limit how often we're willing to do the heavy lifting below to
13366        // collect and record logs; currently 5 logs per 10 second period.
13367        final long now = SystemClock.elapsedRealtime();
13368        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13369            mWtfClusterStart = now;
13370            mWtfClusterCount = 1;
13371        } else {
13372            if (mWtfClusterCount++ >= 5) return;
13373        }
13374
13375        final StringBuilder sb = new StringBuilder(1024);
13376        appendDropBoxProcessHeaders(process, processName, sb);
13377        if (process != null) {
13378            sb.append("Foreground: ")
13379                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13380                    .append("\n");
13381        }
13382        if (activity != null) {
13383            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13384        }
13385        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13386            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13387        }
13388        if (parent != null && parent != activity) {
13389            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13390        }
13391        if (subject != null) {
13392            sb.append("Subject: ").append(subject).append("\n");
13393        }
13394        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13395        if (Debug.isDebuggerConnected()) {
13396            sb.append("Debugger: Connected\n");
13397        }
13398        sb.append("\n");
13399
13400        // Do the rest in a worker thread to avoid blocking the caller on I/O
13401        // (After this point, we shouldn't access AMS internal data structures.)
13402        Thread worker = new Thread("Error dump: " + dropboxTag) {
13403            @Override
13404            public void run() {
13405                if (report != null) {
13406                    sb.append(report);
13407                }
13408                if (logFile != null) {
13409                    try {
13410                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13411                                    "\n\n[[TRUNCATED]]"));
13412                    } catch (IOException e) {
13413                        Slog.e(TAG, "Error reading " + logFile, e);
13414                    }
13415                }
13416                if (crashInfo != null && crashInfo.stackTrace != null) {
13417                    sb.append(crashInfo.stackTrace);
13418                }
13419
13420                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13421                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13422                if (lines > 0) {
13423                    sb.append("\n");
13424
13425                    // Merge several logcat streams, and take the last N lines
13426                    InputStreamReader input = null;
13427                    try {
13428                        java.lang.Process logcat = new ProcessBuilder(
13429                                "/system/bin/timeout", "-k", "15s", "10s",
13430                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13431                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13432                                        .redirectErrorStream(true).start();
13433
13434                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13435                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13436                        input = new InputStreamReader(logcat.getInputStream());
13437
13438                        int num;
13439                        char[] buf = new char[8192];
13440                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13441                    } catch (IOException e) {
13442                        Slog.e(TAG, "Error running logcat", e);
13443                    } finally {
13444                        if (input != null) try { input.close(); } catch (IOException e) {}
13445                    }
13446                }
13447
13448                dbox.addText(dropboxTag, sb.toString());
13449            }
13450        };
13451
13452        if (process == null) {
13453            // If process is null, we are being called from some internal code
13454            // and may be about to die -- run this synchronously.
13455            worker.run();
13456        } else {
13457            worker.start();
13458        }
13459    }
13460
13461    @Override
13462    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13463        enforceNotIsolatedCaller("getProcessesInErrorState");
13464        // assume our apps are happy - lazy create the list
13465        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13466
13467        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13468                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13469        int userId = UserHandle.getUserId(Binder.getCallingUid());
13470
13471        synchronized (this) {
13472
13473            // iterate across all processes
13474            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13475                ProcessRecord app = mLruProcesses.get(i);
13476                if (!allUsers && app.userId != userId) {
13477                    continue;
13478                }
13479                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13480                    // This one's in trouble, so we'll generate a report for it
13481                    // crashes are higher priority (in case there's a crash *and* an anr)
13482                    ActivityManager.ProcessErrorStateInfo report = null;
13483                    if (app.crashing) {
13484                        report = app.crashingReport;
13485                    } else if (app.notResponding) {
13486                        report = app.notRespondingReport;
13487                    }
13488
13489                    if (report != null) {
13490                        if (errList == null) {
13491                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13492                        }
13493                        errList.add(report);
13494                    } else {
13495                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13496                                " crashing = " + app.crashing +
13497                                " notResponding = " + app.notResponding);
13498                    }
13499                }
13500            }
13501        }
13502
13503        return errList;
13504    }
13505
13506    static int procStateToImportance(int procState, int memAdj,
13507            ActivityManager.RunningAppProcessInfo currApp) {
13508        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13509        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13510            currApp.lru = memAdj;
13511        } else {
13512            currApp.lru = 0;
13513        }
13514        return imp;
13515    }
13516
13517    private void fillInProcMemInfo(ProcessRecord app,
13518            ActivityManager.RunningAppProcessInfo outInfo) {
13519        outInfo.pid = app.pid;
13520        outInfo.uid = app.info.uid;
13521        if (mHeavyWeightProcess == app) {
13522            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13523        }
13524        if (app.persistent) {
13525            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13526        }
13527        if (app.activities.size() > 0) {
13528            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13529        }
13530        outInfo.lastTrimLevel = app.trimMemoryLevel;
13531        int adj = app.curAdj;
13532        int procState = app.curProcState;
13533        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13534        outInfo.importanceReasonCode = app.adjTypeCode;
13535        outInfo.processState = app.curProcState;
13536    }
13537
13538    @Override
13539    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13540        enforceNotIsolatedCaller("getRunningAppProcesses");
13541
13542        final int callingUid = Binder.getCallingUid();
13543
13544        // Lazy instantiation of list
13545        List<ActivityManager.RunningAppProcessInfo> runList = null;
13546        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13547                callingUid) == PackageManager.PERMISSION_GRANTED;
13548        final int userId = UserHandle.getUserId(callingUid);
13549        final boolean allUids = isGetTasksAllowed(
13550                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13551
13552        synchronized (this) {
13553            // Iterate across all processes
13554            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13555                ProcessRecord app = mLruProcesses.get(i);
13556                if ((!allUsers && app.userId != userId)
13557                        || (!allUids && app.uid != callingUid)) {
13558                    continue;
13559                }
13560                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13561                    // Generate process state info for running application
13562                    ActivityManager.RunningAppProcessInfo currApp =
13563                        new ActivityManager.RunningAppProcessInfo(app.processName,
13564                                app.pid, app.getPackageList());
13565                    fillInProcMemInfo(app, currApp);
13566                    if (app.adjSource instanceof ProcessRecord) {
13567                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13568                        currApp.importanceReasonImportance =
13569                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13570                                        app.adjSourceProcState);
13571                    } else if (app.adjSource instanceof ActivityRecord) {
13572                        ActivityRecord r = (ActivityRecord)app.adjSource;
13573                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13574                    }
13575                    if (app.adjTarget instanceof ComponentName) {
13576                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13577                    }
13578                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13579                    //        + " lru=" + currApp.lru);
13580                    if (runList == null) {
13581                        runList = new ArrayList<>();
13582                    }
13583                    runList.add(currApp);
13584                }
13585            }
13586        }
13587        return runList;
13588    }
13589
13590    @Override
13591    public List<ApplicationInfo> getRunningExternalApplications() {
13592        enforceNotIsolatedCaller("getRunningExternalApplications");
13593        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13594        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13595        if (runningApps != null && runningApps.size() > 0) {
13596            Set<String> extList = new HashSet<String>();
13597            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13598                if (app.pkgList != null) {
13599                    for (String pkg : app.pkgList) {
13600                        extList.add(pkg);
13601                    }
13602                }
13603            }
13604            IPackageManager pm = AppGlobals.getPackageManager();
13605            for (String pkg : extList) {
13606                try {
13607                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13608                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13609                        retList.add(info);
13610                    }
13611                } catch (RemoteException e) {
13612                }
13613            }
13614        }
13615        return retList;
13616    }
13617
13618    @Override
13619    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13620        enforceNotIsolatedCaller("getMyMemoryState");
13621        synchronized (this) {
13622            ProcessRecord proc;
13623            synchronized (mPidsSelfLocked) {
13624                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13625            }
13626            fillInProcMemInfo(proc, outInfo);
13627        }
13628    }
13629
13630    @Override
13631    public int getMemoryTrimLevel() {
13632        enforceNotIsolatedCaller("getMyMemoryState");
13633        synchronized (this) {
13634            return mLastMemoryLevel;
13635        }
13636    }
13637
13638    @Override
13639    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13640            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13641        (new ActivityManagerShellCommand(this, false)).exec(
13642                this, in, out, err, args, resultReceiver);
13643    }
13644
13645    @Override
13646    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13647        if (checkCallingPermission(android.Manifest.permission.DUMP)
13648                != PackageManager.PERMISSION_GRANTED) {
13649            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13650                    + Binder.getCallingPid()
13651                    + ", uid=" + Binder.getCallingUid()
13652                    + " without permission "
13653                    + android.Manifest.permission.DUMP);
13654            return;
13655        }
13656
13657        boolean dumpAll = false;
13658        boolean dumpClient = false;
13659        String dumpPackage = null;
13660
13661        int opti = 0;
13662        while (opti < args.length) {
13663            String opt = args[opti];
13664            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13665                break;
13666            }
13667            opti++;
13668            if ("-a".equals(opt)) {
13669                dumpAll = true;
13670            } else if ("-c".equals(opt)) {
13671                dumpClient = true;
13672            } else if ("-p".equals(opt)) {
13673                if (opti < args.length) {
13674                    dumpPackage = args[opti];
13675                    opti++;
13676                } else {
13677                    pw.println("Error: -p option requires package argument");
13678                    return;
13679                }
13680                dumpClient = true;
13681            } else if ("-h".equals(opt)) {
13682                ActivityManagerShellCommand.dumpHelp(pw, true);
13683                return;
13684            } else {
13685                pw.println("Unknown argument: " + opt + "; use -h for help");
13686            }
13687        }
13688
13689        long origId = Binder.clearCallingIdentity();
13690        boolean more = false;
13691        // Is the caller requesting to dump a particular piece of data?
13692        if (opti < args.length) {
13693            String cmd = args[opti];
13694            opti++;
13695            if ("activities".equals(cmd) || "a".equals(cmd)) {
13696                synchronized (this) {
13697                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13698                }
13699            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13700                synchronized (this) {
13701                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13702                }
13703            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13704                String[] newArgs;
13705                String name;
13706                if (opti >= args.length) {
13707                    name = null;
13708                    newArgs = EMPTY_STRING_ARRAY;
13709                } else {
13710                    dumpPackage = args[opti];
13711                    opti++;
13712                    newArgs = new String[args.length - opti];
13713                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13714                            args.length - opti);
13715                }
13716                synchronized (this) {
13717                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13718                }
13719            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13720                String[] newArgs;
13721                String name;
13722                if (opti >= args.length) {
13723                    name = null;
13724                    newArgs = EMPTY_STRING_ARRAY;
13725                } else {
13726                    dumpPackage = args[opti];
13727                    opti++;
13728                    newArgs = new String[args.length - opti];
13729                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13730                            args.length - opti);
13731                }
13732                synchronized (this) {
13733                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13734                }
13735            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13736                String[] newArgs;
13737                String name;
13738                if (opti >= args.length) {
13739                    name = null;
13740                    newArgs = EMPTY_STRING_ARRAY;
13741                } else {
13742                    dumpPackage = args[opti];
13743                    opti++;
13744                    newArgs = new String[args.length - opti];
13745                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13746                            args.length - opti);
13747                }
13748                synchronized (this) {
13749                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13750                }
13751            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13752                synchronized (this) {
13753                    dumpOomLocked(fd, pw, args, opti, true);
13754                }
13755            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13756                synchronized (this) {
13757                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13758                }
13759            } else if ("provider".equals(cmd)) {
13760                String[] newArgs;
13761                String name;
13762                if (opti >= args.length) {
13763                    name = null;
13764                    newArgs = EMPTY_STRING_ARRAY;
13765                } else {
13766                    name = args[opti];
13767                    opti++;
13768                    newArgs = new String[args.length - opti];
13769                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13770                }
13771                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13772                    pw.println("No providers match: " + name);
13773                    pw.println("Use -h for help.");
13774                }
13775            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13776                synchronized (this) {
13777                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13778                }
13779            } else if ("service".equals(cmd)) {
13780                String[] newArgs;
13781                String name;
13782                if (opti >= args.length) {
13783                    name = null;
13784                    newArgs = EMPTY_STRING_ARRAY;
13785                } else {
13786                    name = args[opti];
13787                    opti++;
13788                    newArgs = new String[args.length - opti];
13789                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13790                            args.length - opti);
13791                }
13792                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13793                    pw.println("No services match: " + name);
13794                    pw.println("Use -h for help.");
13795                }
13796            } else if ("package".equals(cmd)) {
13797                String[] newArgs;
13798                if (opti >= args.length) {
13799                    pw.println("package: no package name specified");
13800                    pw.println("Use -h for help.");
13801                } else {
13802                    dumpPackage = args[opti];
13803                    opti++;
13804                    newArgs = new String[args.length - opti];
13805                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13806                            args.length - opti);
13807                    args = newArgs;
13808                    opti = 0;
13809                    more = true;
13810                }
13811            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13812                synchronized (this) {
13813                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13814                }
13815            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13816                if (dumpClient) {
13817                    ActiveServices.ServiceDumper dumper;
13818                    synchronized (this) {
13819                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13820                                dumpPackage);
13821                    }
13822                    dumper.dumpWithClient();
13823                } else {
13824                    synchronized (this) {
13825                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13826                                dumpPackage).dumpLocked();
13827                    }
13828                }
13829            } else if ("locks".equals(cmd)) {
13830                LockGuard.dump(fd, pw, args);
13831            } else {
13832                // Dumping a single activity?
13833                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13834                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13835                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13836                    if (res < 0) {
13837                        pw.println("Bad activity command, or no activities match: " + cmd);
13838                        pw.println("Use -h for help.");
13839                    }
13840                }
13841            }
13842            if (!more) {
13843                Binder.restoreCallingIdentity(origId);
13844                return;
13845            }
13846        }
13847
13848        // No piece of data specified, dump everything.
13849        if (dumpClient) {
13850            ActiveServices.ServiceDumper sdumper;
13851            synchronized (this) {
13852                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13853                pw.println();
13854                if (dumpAll) {
13855                    pw.println("-------------------------------------------------------------------------------");
13856                }
13857                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13858                pw.println();
13859                if (dumpAll) {
13860                    pw.println("-------------------------------------------------------------------------------");
13861                }
13862                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13863                pw.println();
13864                if (dumpAll) {
13865                    pw.println("-------------------------------------------------------------------------------");
13866                }
13867                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13868                pw.println();
13869                if (dumpAll) {
13870                    pw.println("-------------------------------------------------------------------------------");
13871                }
13872                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13873                        dumpPackage);
13874            }
13875            sdumper.dumpWithClient();
13876            pw.println();
13877            synchronized (this) {
13878                if (dumpAll) {
13879                    pw.println("-------------------------------------------------------------------------------");
13880                }
13881                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13882                pw.println();
13883                if (dumpAll) {
13884                    pw.println("-------------------------------------------------------------------------------");
13885                }
13886                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13887                if (mAssociations.size() > 0) {
13888                    pw.println();
13889                    if (dumpAll) {
13890                        pw.println("-------------------------------------------------------------------------------");
13891                    }
13892                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13893                }
13894                pw.println();
13895                if (dumpAll) {
13896                    pw.println("-------------------------------------------------------------------------------");
13897                }
13898                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13899            }
13900
13901        } else {
13902            synchronized (this) {
13903                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13904                pw.println();
13905                if (dumpAll) {
13906                    pw.println("-------------------------------------------------------------------------------");
13907                }
13908                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13909                pw.println();
13910                if (dumpAll) {
13911                    pw.println("-------------------------------------------------------------------------------");
13912                }
13913                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13914                pw.println();
13915                if (dumpAll) {
13916                    pw.println("-------------------------------------------------------------------------------");
13917                }
13918                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13919                pw.println();
13920                if (dumpAll) {
13921                    pw.println("-------------------------------------------------------------------------------");
13922                }
13923                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
13924                        .dumpLocked();
13925                pw.println();
13926                if (dumpAll) {
13927                    pw.println("-------------------------------------------------------------------------------");
13928                }
13929                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13930                pw.println();
13931                if (dumpAll) {
13932                    pw.println("-------------------------------------------------------------------------------");
13933                }
13934                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13935                if (mAssociations.size() > 0) {
13936                    pw.println();
13937                    if (dumpAll) {
13938                        pw.println("-------------------------------------------------------------------------------");
13939                    }
13940                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13941                }
13942                pw.println();
13943                if (dumpAll) {
13944                    pw.println("-------------------------------------------------------------------------------");
13945                }
13946                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13947            }
13948        }
13949        Binder.restoreCallingIdentity(origId);
13950    }
13951
13952    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13953            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13954        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13955
13956        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13957                dumpPackage);
13958        boolean needSep = printedAnything;
13959
13960        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13961                dumpPackage, needSep, "  mFocusedActivity: ");
13962        if (printed) {
13963            printedAnything = true;
13964            needSep = false;
13965        }
13966
13967        if (dumpPackage == null) {
13968            if (needSep) {
13969                pw.println();
13970            }
13971            needSep = true;
13972            printedAnything = true;
13973            mStackSupervisor.dump(pw, "  ");
13974        }
13975
13976        if (!printedAnything) {
13977            pw.println("  (nothing)");
13978        }
13979    }
13980
13981    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13982            int opti, boolean dumpAll, String dumpPackage) {
13983        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13984
13985        boolean printedAnything = false;
13986
13987        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13988            boolean printedHeader = false;
13989
13990            final int N = mRecentTasks.size();
13991            for (int i=0; i<N; i++) {
13992                TaskRecord tr = mRecentTasks.get(i);
13993                if (dumpPackage != null) {
13994                    if (tr.realActivity == null ||
13995                            !dumpPackage.equals(tr.realActivity)) {
13996                        continue;
13997                    }
13998                }
13999                if (!printedHeader) {
14000                    pw.println("  Recent tasks:");
14001                    printedHeader = true;
14002                    printedAnything = true;
14003                }
14004                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14005                        pw.println(tr);
14006                if (dumpAll) {
14007                    mRecentTasks.get(i).dump(pw, "    ");
14008                }
14009            }
14010        }
14011
14012        if (!printedAnything) {
14013            pw.println("  (nothing)");
14014        }
14015    }
14016
14017    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14018            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14019        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14020
14021        int dumpUid = 0;
14022        if (dumpPackage != null) {
14023            IPackageManager pm = AppGlobals.getPackageManager();
14024            try {
14025                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14026            } catch (RemoteException e) {
14027            }
14028        }
14029
14030        boolean printedAnything = false;
14031
14032        final long now = SystemClock.uptimeMillis();
14033
14034        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14035            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14036                    = mAssociations.valueAt(i1);
14037            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14038                SparseArray<ArrayMap<String, Association>> sourceUids
14039                        = targetComponents.valueAt(i2);
14040                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14041                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14042                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14043                        Association ass = sourceProcesses.valueAt(i4);
14044                        if (dumpPackage != null) {
14045                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14046                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14047                                continue;
14048                            }
14049                        }
14050                        printedAnything = true;
14051                        pw.print("  ");
14052                        pw.print(ass.mTargetProcess);
14053                        pw.print("/");
14054                        UserHandle.formatUid(pw, ass.mTargetUid);
14055                        pw.print(" <- ");
14056                        pw.print(ass.mSourceProcess);
14057                        pw.print("/");
14058                        UserHandle.formatUid(pw, ass.mSourceUid);
14059                        pw.println();
14060                        pw.print("    via ");
14061                        pw.print(ass.mTargetComponent.flattenToShortString());
14062                        pw.println();
14063                        pw.print("    ");
14064                        long dur = ass.mTime;
14065                        if (ass.mNesting > 0) {
14066                            dur += now - ass.mStartTime;
14067                        }
14068                        TimeUtils.formatDuration(dur, pw);
14069                        pw.print(" (");
14070                        pw.print(ass.mCount);
14071                        pw.print(" times)");
14072                        pw.print("  ");
14073                        for (int i=0; i<ass.mStateTimes.length; i++) {
14074                            long amt = ass.mStateTimes[i];
14075                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14076                                amt += now - ass.mLastStateUptime;
14077                            }
14078                            if (amt != 0) {
14079                                pw.print(" ");
14080                                pw.print(ProcessList.makeProcStateString(
14081                                            i + ActivityManager.MIN_PROCESS_STATE));
14082                                pw.print("=");
14083                                TimeUtils.formatDuration(amt, pw);
14084                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14085                                    pw.print("*");
14086                                }
14087                            }
14088                        }
14089                        pw.println();
14090                        if (ass.mNesting > 0) {
14091                            pw.print("    Currently active: ");
14092                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14093                            pw.println();
14094                        }
14095                    }
14096                }
14097            }
14098
14099        }
14100
14101        if (!printedAnything) {
14102            pw.println("  (nothing)");
14103        }
14104    }
14105
14106    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14107            String header, boolean needSep) {
14108        boolean printed = false;
14109        int whichAppId = -1;
14110        if (dumpPackage != null) {
14111            try {
14112                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14113                        dumpPackage, 0);
14114                whichAppId = UserHandle.getAppId(info.uid);
14115            } catch (NameNotFoundException e) {
14116                e.printStackTrace();
14117            }
14118        }
14119        for (int i=0; i<uids.size(); i++) {
14120            UidRecord uidRec = uids.valueAt(i);
14121            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14122                continue;
14123            }
14124            if (!printed) {
14125                printed = true;
14126                if (needSep) {
14127                    pw.println();
14128                }
14129                pw.print("  ");
14130                pw.println(header);
14131                needSep = true;
14132            }
14133            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14134            pw.print(": "); pw.println(uidRec);
14135        }
14136        return printed;
14137    }
14138
14139    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14140            int opti, boolean dumpAll, String dumpPackage) {
14141        boolean needSep = false;
14142        boolean printedAnything = false;
14143        int numPers = 0;
14144
14145        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14146
14147        if (dumpAll) {
14148            final int NP = mProcessNames.getMap().size();
14149            for (int ip=0; ip<NP; ip++) {
14150                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14151                final int NA = procs.size();
14152                for (int ia=0; ia<NA; ia++) {
14153                    ProcessRecord r = procs.valueAt(ia);
14154                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14155                        continue;
14156                    }
14157                    if (!needSep) {
14158                        pw.println("  All known processes:");
14159                        needSep = true;
14160                        printedAnything = true;
14161                    }
14162                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14163                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14164                        pw.print(" "); pw.println(r);
14165                    r.dump(pw, "    ");
14166                    if (r.persistent) {
14167                        numPers++;
14168                    }
14169                }
14170            }
14171        }
14172
14173        if (mIsolatedProcesses.size() > 0) {
14174            boolean printed = false;
14175            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14176                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14177                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14178                    continue;
14179                }
14180                if (!printed) {
14181                    if (needSep) {
14182                        pw.println();
14183                    }
14184                    pw.println("  Isolated process list (sorted by uid):");
14185                    printedAnything = true;
14186                    printed = true;
14187                    needSep = true;
14188                }
14189                pw.println(String.format("%sIsolated #%2d: %s",
14190                        "    ", i, r.toString()));
14191            }
14192        }
14193
14194        if (mActiveUids.size() > 0) {
14195            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14196                printedAnything = needSep = true;
14197            }
14198        }
14199        if (mValidateUids.size() > 0) {
14200            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14201                printedAnything = needSep = true;
14202            }
14203        }
14204
14205        if (mLruProcesses.size() > 0) {
14206            if (needSep) {
14207                pw.println();
14208            }
14209            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14210                    pw.print(" total, non-act at ");
14211                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14212                    pw.print(", non-svc at ");
14213                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14214                    pw.println("):");
14215            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14216            needSep = true;
14217            printedAnything = true;
14218        }
14219
14220        if (dumpAll || dumpPackage != null) {
14221            synchronized (mPidsSelfLocked) {
14222                boolean printed = false;
14223                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14224                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14225                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14226                        continue;
14227                    }
14228                    if (!printed) {
14229                        if (needSep) pw.println();
14230                        needSep = true;
14231                        pw.println("  PID mappings:");
14232                        printed = true;
14233                        printedAnything = true;
14234                    }
14235                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14236                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14237                }
14238            }
14239        }
14240
14241        if (mForegroundProcesses.size() > 0) {
14242            synchronized (mPidsSelfLocked) {
14243                boolean printed = false;
14244                for (int i=0; i<mForegroundProcesses.size(); i++) {
14245                    ProcessRecord r = mPidsSelfLocked.get(
14246                            mForegroundProcesses.valueAt(i).pid);
14247                    if (dumpPackage != null && (r == null
14248                            || !r.pkgList.containsKey(dumpPackage))) {
14249                        continue;
14250                    }
14251                    if (!printed) {
14252                        if (needSep) pw.println();
14253                        needSep = true;
14254                        pw.println("  Foreground Processes:");
14255                        printed = true;
14256                        printedAnything = true;
14257                    }
14258                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14259                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14260                }
14261            }
14262        }
14263
14264        if (mPersistentStartingProcesses.size() > 0) {
14265            if (needSep) pw.println();
14266            needSep = true;
14267            printedAnything = true;
14268            pw.println("  Persisent processes that are starting:");
14269            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14270                    "Starting Norm", "Restarting PERS", dumpPackage);
14271        }
14272
14273        if (mRemovedProcesses.size() > 0) {
14274            if (needSep) pw.println();
14275            needSep = true;
14276            printedAnything = true;
14277            pw.println("  Processes that are being removed:");
14278            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14279                    "Removed Norm", "Removed PERS", dumpPackage);
14280        }
14281
14282        if (mProcessesOnHold.size() > 0) {
14283            if (needSep) pw.println();
14284            needSep = true;
14285            printedAnything = true;
14286            pw.println("  Processes that are on old until the system is ready:");
14287            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14288                    "OnHold Norm", "OnHold PERS", dumpPackage);
14289        }
14290
14291        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14292
14293        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14294        if (needSep) {
14295            printedAnything = true;
14296        }
14297
14298        if (dumpPackage == null) {
14299            pw.println();
14300            needSep = false;
14301            mUserController.dump(pw, dumpAll);
14302        }
14303        if (mHomeProcess != null && (dumpPackage == null
14304                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14305            if (needSep) {
14306                pw.println();
14307                needSep = false;
14308            }
14309            pw.println("  mHomeProcess: " + mHomeProcess);
14310        }
14311        if (mPreviousProcess != null && (dumpPackage == null
14312                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14313            if (needSep) {
14314                pw.println();
14315                needSep = false;
14316            }
14317            pw.println("  mPreviousProcess: " + mPreviousProcess);
14318        }
14319        if (dumpAll) {
14320            StringBuilder sb = new StringBuilder(128);
14321            sb.append("  mPreviousProcessVisibleTime: ");
14322            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14323            pw.println(sb);
14324        }
14325        if (mHeavyWeightProcess != null && (dumpPackage == null
14326                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14327            if (needSep) {
14328                pw.println();
14329                needSep = false;
14330            }
14331            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14332        }
14333        if (dumpPackage == null) {
14334            pw.println("  mConfiguration: " + mConfiguration);
14335        }
14336        if (dumpAll) {
14337            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14338            if (mCompatModePackages.getPackages().size() > 0) {
14339                boolean printed = false;
14340                for (Map.Entry<String, Integer> entry
14341                        : mCompatModePackages.getPackages().entrySet()) {
14342                    String pkg = entry.getKey();
14343                    int mode = entry.getValue();
14344                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14345                        continue;
14346                    }
14347                    if (!printed) {
14348                        pw.println("  mScreenCompatPackages:");
14349                        printed = true;
14350                    }
14351                    pw.print("    "); pw.print(pkg); pw.print(": ");
14352                            pw.print(mode); pw.println();
14353                }
14354            }
14355        }
14356        if (dumpPackage == null) {
14357            pw.println("  mWakefulness="
14358                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14359            pw.println("  mSleepTokens=" + mSleepTokens);
14360            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14361                    + lockScreenShownToString());
14362            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14363            if (mRunningVoice != null) {
14364                pw.println("  mRunningVoice=" + mRunningVoice);
14365                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14366            }
14367        }
14368        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14369                || mOrigWaitForDebugger) {
14370            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14371                    || dumpPackage.equals(mOrigDebugApp)) {
14372                if (needSep) {
14373                    pw.println();
14374                    needSep = false;
14375                }
14376                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14377                        + " mDebugTransient=" + mDebugTransient
14378                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14379            }
14380        }
14381        if (mCurAppTimeTracker != null) {
14382            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14383        }
14384        if (mMemWatchProcesses.getMap().size() > 0) {
14385            pw.println("  Mem watch processes:");
14386            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14387                    = mMemWatchProcesses.getMap();
14388            for (int i=0; i<procs.size(); i++) {
14389                final String proc = procs.keyAt(i);
14390                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14391                for (int j=0; j<uids.size(); j++) {
14392                    if (needSep) {
14393                        pw.println();
14394                        needSep = false;
14395                    }
14396                    StringBuilder sb = new StringBuilder();
14397                    sb.append("    ").append(proc).append('/');
14398                    UserHandle.formatUid(sb, uids.keyAt(j));
14399                    Pair<Long, String> val = uids.valueAt(j);
14400                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14401                    if (val.second != null) {
14402                        sb.append(", report to ").append(val.second);
14403                    }
14404                    pw.println(sb.toString());
14405                }
14406            }
14407            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14408            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14409            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14410                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14411        }
14412        if (mTrackAllocationApp != null) {
14413            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14414                if (needSep) {
14415                    pw.println();
14416                    needSep = false;
14417                }
14418                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14419            }
14420        }
14421        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14422                || mProfileFd != null) {
14423            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14424                if (needSep) {
14425                    pw.println();
14426                    needSep = false;
14427                }
14428                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14429                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14430                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14431                        + mAutoStopProfiler);
14432                pw.println("  mProfileType=" + mProfileType);
14433            }
14434        }
14435        if (mNativeDebuggingApp != null) {
14436            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14437                if (needSep) {
14438                    pw.println();
14439                    needSep = false;
14440                }
14441                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14442            }
14443        }
14444        if (dumpPackage == null) {
14445            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14446                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14447                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14448            }
14449            if (mController != null) {
14450                pw.println("  mController=" + mController
14451                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14452            }
14453            if (dumpAll) {
14454                pw.println("  Total persistent processes: " + numPers);
14455                pw.println("  mProcessesReady=" + mProcessesReady
14456                        + " mSystemReady=" + mSystemReady
14457                        + " mBooted=" + mBooted
14458                        + " mFactoryTest=" + mFactoryTest);
14459                pw.println("  mBooting=" + mBooting
14460                        + " mCallFinishBooting=" + mCallFinishBooting
14461                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14462                pw.print("  mLastPowerCheckRealtime=");
14463                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14464                        pw.println("");
14465                pw.print("  mLastPowerCheckUptime=");
14466                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14467                        pw.println("");
14468                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14469                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14470                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14471                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14472                        + " (" + mLruProcesses.size() + " total)"
14473                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14474                        + " mNumServiceProcs=" + mNumServiceProcs
14475                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14476                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14477                        + " mLastMemoryLevel=" + mLastMemoryLevel
14478                        + " mLastNumProcesses=" + mLastNumProcesses);
14479                long now = SystemClock.uptimeMillis();
14480                pw.print("  mLastIdleTime=");
14481                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14482                        pw.print(" mLowRamSinceLastIdle=");
14483                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14484                        pw.println();
14485            }
14486        }
14487
14488        if (!printedAnything) {
14489            pw.println("  (nothing)");
14490        }
14491    }
14492
14493    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14494            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14495        if (mProcessesToGc.size() > 0) {
14496            boolean printed = false;
14497            long now = SystemClock.uptimeMillis();
14498            for (int i=0; i<mProcessesToGc.size(); i++) {
14499                ProcessRecord proc = mProcessesToGc.get(i);
14500                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14501                    continue;
14502                }
14503                if (!printed) {
14504                    if (needSep) pw.println();
14505                    needSep = true;
14506                    pw.println("  Processes that are waiting to GC:");
14507                    printed = true;
14508                }
14509                pw.print("    Process "); pw.println(proc);
14510                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14511                        pw.print(", last gced=");
14512                        pw.print(now-proc.lastRequestedGc);
14513                        pw.print(" ms ago, last lowMem=");
14514                        pw.print(now-proc.lastLowMemory);
14515                        pw.println(" ms ago");
14516
14517            }
14518        }
14519        return needSep;
14520    }
14521
14522    void printOomLevel(PrintWriter pw, String name, int adj) {
14523        pw.print("    ");
14524        if (adj >= 0) {
14525            pw.print(' ');
14526            if (adj < 10) pw.print(' ');
14527        } else {
14528            if (adj > -10) pw.print(' ');
14529        }
14530        pw.print(adj);
14531        pw.print(": ");
14532        pw.print(name);
14533        pw.print(" (");
14534        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14535        pw.println(")");
14536    }
14537
14538    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14539            int opti, boolean dumpAll) {
14540        boolean needSep = false;
14541
14542        if (mLruProcesses.size() > 0) {
14543            if (needSep) pw.println();
14544            needSep = true;
14545            pw.println("  OOM levels:");
14546            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14547            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14548            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14549            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14550            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14551            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14552            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14553            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14554            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14555            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14556            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14557            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14558            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14559            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14560
14561            if (needSep) pw.println();
14562            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14563                    pw.print(" total, non-act at ");
14564                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14565                    pw.print(", non-svc at ");
14566                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14567                    pw.println("):");
14568            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14569            needSep = true;
14570        }
14571
14572        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14573
14574        pw.println();
14575        pw.println("  mHomeProcess: " + mHomeProcess);
14576        pw.println("  mPreviousProcess: " + mPreviousProcess);
14577        if (mHeavyWeightProcess != null) {
14578            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14579        }
14580
14581        return true;
14582    }
14583
14584    /**
14585     * There are three ways to call this:
14586     *  - no provider specified: dump all the providers
14587     *  - a flattened component name that matched an existing provider was specified as the
14588     *    first arg: dump that one provider
14589     *  - the first arg isn't the flattened component name of an existing provider:
14590     *    dump all providers whose component contains the first arg as a substring
14591     */
14592    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14593            int opti, boolean dumpAll) {
14594        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14595    }
14596
14597    static class ItemMatcher {
14598        ArrayList<ComponentName> components;
14599        ArrayList<String> strings;
14600        ArrayList<Integer> objects;
14601        boolean all;
14602
14603        ItemMatcher() {
14604            all = true;
14605        }
14606
14607        void build(String name) {
14608            ComponentName componentName = ComponentName.unflattenFromString(name);
14609            if (componentName != null) {
14610                if (components == null) {
14611                    components = new ArrayList<ComponentName>();
14612                }
14613                components.add(componentName);
14614                all = false;
14615            } else {
14616                int objectId = 0;
14617                // Not a '/' separated full component name; maybe an object ID?
14618                try {
14619                    objectId = Integer.parseInt(name, 16);
14620                    if (objects == null) {
14621                        objects = new ArrayList<Integer>();
14622                    }
14623                    objects.add(objectId);
14624                    all = false;
14625                } catch (RuntimeException e) {
14626                    // Not an integer; just do string match.
14627                    if (strings == null) {
14628                        strings = new ArrayList<String>();
14629                    }
14630                    strings.add(name);
14631                    all = false;
14632                }
14633            }
14634        }
14635
14636        int build(String[] args, int opti) {
14637            for (; opti<args.length; opti++) {
14638                String name = args[opti];
14639                if ("--".equals(name)) {
14640                    return opti+1;
14641                }
14642                build(name);
14643            }
14644            return opti;
14645        }
14646
14647        boolean match(Object object, ComponentName comp) {
14648            if (all) {
14649                return true;
14650            }
14651            if (components != null) {
14652                for (int i=0; i<components.size(); i++) {
14653                    if (components.get(i).equals(comp)) {
14654                        return true;
14655                    }
14656                }
14657            }
14658            if (objects != null) {
14659                for (int i=0; i<objects.size(); i++) {
14660                    if (System.identityHashCode(object) == objects.get(i)) {
14661                        return true;
14662                    }
14663                }
14664            }
14665            if (strings != null) {
14666                String flat = comp.flattenToString();
14667                for (int i=0; i<strings.size(); i++) {
14668                    if (flat.contains(strings.get(i))) {
14669                        return true;
14670                    }
14671                }
14672            }
14673            return false;
14674        }
14675    }
14676
14677    /**
14678     * There are three things that cmd can be:
14679     *  - a flattened component name that matches an existing activity
14680     *  - the cmd arg isn't the flattened component name of an existing activity:
14681     *    dump all activity whose component contains the cmd as a substring
14682     *  - A hex number of the ActivityRecord object instance.
14683     */
14684    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14685            int opti, boolean dumpAll) {
14686        ArrayList<ActivityRecord> activities;
14687
14688        synchronized (this) {
14689            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14690        }
14691
14692        if (activities.size() <= 0) {
14693            return false;
14694        }
14695
14696        String[] newArgs = new String[args.length - opti];
14697        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14698
14699        TaskRecord lastTask = null;
14700        boolean needSep = false;
14701        for (int i=activities.size()-1; i>=0; i--) {
14702            ActivityRecord r = activities.get(i);
14703            if (needSep) {
14704                pw.println();
14705            }
14706            needSep = true;
14707            synchronized (this) {
14708                if (lastTask != r.task) {
14709                    lastTask = r.task;
14710                    pw.print("TASK "); pw.print(lastTask.affinity);
14711                            pw.print(" id="); pw.println(lastTask.taskId);
14712                    if (dumpAll) {
14713                        lastTask.dump(pw, "  ");
14714                    }
14715                }
14716            }
14717            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14718        }
14719        return true;
14720    }
14721
14722    /**
14723     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14724     * there is a thread associated with the activity.
14725     */
14726    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14727            final ActivityRecord r, String[] args, boolean dumpAll) {
14728        String innerPrefix = prefix + "  ";
14729        synchronized (this) {
14730            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14731                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14732                    pw.print(" pid=");
14733                    if (r.app != null) pw.println(r.app.pid);
14734                    else pw.println("(not running)");
14735            if (dumpAll) {
14736                r.dump(pw, innerPrefix);
14737            }
14738        }
14739        if (r.app != null && r.app.thread != null) {
14740            // flush anything that is already in the PrintWriter since the thread is going
14741            // to write to the file descriptor directly
14742            pw.flush();
14743            try {
14744                TransferPipe tp = new TransferPipe();
14745                try {
14746                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14747                            r.appToken, innerPrefix, args);
14748                    tp.go(fd);
14749                } finally {
14750                    tp.kill();
14751                }
14752            } catch (IOException e) {
14753                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14754            } catch (RemoteException e) {
14755                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14756            }
14757        }
14758    }
14759
14760    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14761            int opti, boolean dumpAll, String dumpPackage) {
14762        boolean needSep = false;
14763        boolean onlyHistory = false;
14764        boolean printedAnything = false;
14765
14766        if ("history".equals(dumpPackage)) {
14767            if (opti < args.length && "-s".equals(args[opti])) {
14768                dumpAll = false;
14769            }
14770            onlyHistory = true;
14771            dumpPackage = null;
14772        }
14773
14774        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14775        if (!onlyHistory && dumpAll) {
14776            if (mRegisteredReceivers.size() > 0) {
14777                boolean printed = false;
14778                Iterator it = mRegisteredReceivers.values().iterator();
14779                while (it.hasNext()) {
14780                    ReceiverList r = (ReceiverList)it.next();
14781                    if (dumpPackage != null && (r.app == null ||
14782                            !dumpPackage.equals(r.app.info.packageName))) {
14783                        continue;
14784                    }
14785                    if (!printed) {
14786                        pw.println("  Registered Receivers:");
14787                        needSep = true;
14788                        printed = true;
14789                        printedAnything = true;
14790                    }
14791                    pw.print("  * "); pw.println(r);
14792                    r.dump(pw, "    ");
14793                }
14794            }
14795
14796            if (mReceiverResolver.dump(pw, needSep ?
14797                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14798                    "    ", dumpPackage, false, false)) {
14799                needSep = true;
14800                printedAnything = true;
14801            }
14802        }
14803
14804        for (BroadcastQueue q : mBroadcastQueues) {
14805            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14806            printedAnything |= needSep;
14807        }
14808
14809        needSep = true;
14810
14811        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14812            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14813                if (needSep) {
14814                    pw.println();
14815                }
14816                needSep = true;
14817                printedAnything = true;
14818                pw.print("  Sticky broadcasts for user ");
14819                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14820                StringBuilder sb = new StringBuilder(128);
14821                for (Map.Entry<String, ArrayList<Intent>> ent
14822                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14823                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14824                    if (dumpAll) {
14825                        pw.println(":");
14826                        ArrayList<Intent> intents = ent.getValue();
14827                        final int N = intents.size();
14828                        for (int i=0; i<N; i++) {
14829                            sb.setLength(0);
14830                            sb.append("    Intent: ");
14831                            intents.get(i).toShortString(sb, false, true, false, false);
14832                            pw.println(sb.toString());
14833                            Bundle bundle = intents.get(i).getExtras();
14834                            if (bundle != null) {
14835                                pw.print("      ");
14836                                pw.println(bundle.toString());
14837                            }
14838                        }
14839                    } else {
14840                        pw.println("");
14841                    }
14842                }
14843            }
14844        }
14845
14846        if (!onlyHistory && dumpAll) {
14847            pw.println();
14848            for (BroadcastQueue queue : mBroadcastQueues) {
14849                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14850                        + queue.mBroadcastsScheduled);
14851            }
14852            pw.println("  mHandler:");
14853            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14854            needSep = true;
14855            printedAnything = true;
14856        }
14857
14858        if (!printedAnything) {
14859            pw.println("  (nothing)");
14860        }
14861    }
14862
14863    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14864            int opti, boolean dumpAll, String dumpPackage) {
14865        boolean needSep;
14866        boolean printedAnything = false;
14867
14868        ItemMatcher matcher = new ItemMatcher();
14869        matcher.build(args, opti);
14870
14871        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14872
14873        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14874        printedAnything |= needSep;
14875
14876        if (mLaunchingProviders.size() > 0) {
14877            boolean printed = false;
14878            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14879                ContentProviderRecord r = mLaunchingProviders.get(i);
14880                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14881                    continue;
14882                }
14883                if (!printed) {
14884                    if (needSep) pw.println();
14885                    needSep = true;
14886                    pw.println("  Launching content providers:");
14887                    printed = true;
14888                    printedAnything = true;
14889                }
14890                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14891                        pw.println(r);
14892            }
14893        }
14894
14895        if (!printedAnything) {
14896            pw.println("  (nothing)");
14897        }
14898    }
14899
14900    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14901            int opti, boolean dumpAll, String dumpPackage) {
14902        boolean needSep = false;
14903        boolean printedAnything = false;
14904
14905        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14906
14907        if (mGrantedUriPermissions.size() > 0) {
14908            boolean printed = false;
14909            int dumpUid = -2;
14910            if (dumpPackage != null) {
14911                try {
14912                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14913                            MATCH_UNINSTALLED_PACKAGES, 0);
14914                } catch (NameNotFoundException e) {
14915                    dumpUid = -1;
14916                }
14917            }
14918            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14919                int uid = mGrantedUriPermissions.keyAt(i);
14920                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14921                    continue;
14922                }
14923                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14924                if (!printed) {
14925                    if (needSep) pw.println();
14926                    needSep = true;
14927                    pw.println("  Granted Uri Permissions:");
14928                    printed = true;
14929                    printedAnything = true;
14930                }
14931                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14932                for (UriPermission perm : perms.values()) {
14933                    pw.print("    "); pw.println(perm);
14934                    if (dumpAll) {
14935                        perm.dump(pw, "      ");
14936                    }
14937                }
14938            }
14939        }
14940
14941        if (!printedAnything) {
14942            pw.println("  (nothing)");
14943        }
14944    }
14945
14946    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14947            int opti, boolean dumpAll, String dumpPackage) {
14948        boolean printed = false;
14949
14950        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14951
14952        if (mIntentSenderRecords.size() > 0) {
14953            Iterator<WeakReference<PendingIntentRecord>> it
14954                    = mIntentSenderRecords.values().iterator();
14955            while (it.hasNext()) {
14956                WeakReference<PendingIntentRecord> ref = it.next();
14957                PendingIntentRecord rec = ref != null ? ref.get(): null;
14958                if (dumpPackage != null && (rec == null
14959                        || !dumpPackage.equals(rec.key.packageName))) {
14960                    continue;
14961                }
14962                printed = true;
14963                if (rec != null) {
14964                    pw.print("  * "); pw.println(rec);
14965                    if (dumpAll) {
14966                        rec.dump(pw, "    ");
14967                    }
14968                } else {
14969                    pw.print("  * "); pw.println(ref);
14970                }
14971            }
14972        }
14973
14974        if (!printed) {
14975            pw.println("  (nothing)");
14976        }
14977    }
14978
14979    private static final int dumpProcessList(PrintWriter pw,
14980            ActivityManagerService service, List list,
14981            String prefix, String normalLabel, String persistentLabel,
14982            String dumpPackage) {
14983        int numPers = 0;
14984        final int N = list.size()-1;
14985        for (int i=N; i>=0; i--) {
14986            ProcessRecord r = (ProcessRecord)list.get(i);
14987            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14988                continue;
14989            }
14990            pw.println(String.format("%s%s #%2d: %s",
14991                    prefix, (r.persistent ? persistentLabel : normalLabel),
14992                    i, r.toString()));
14993            if (r.persistent) {
14994                numPers++;
14995            }
14996        }
14997        return numPers;
14998    }
14999
15000    private static final boolean dumpProcessOomList(PrintWriter pw,
15001            ActivityManagerService service, List<ProcessRecord> origList,
15002            String prefix, String normalLabel, String persistentLabel,
15003            boolean inclDetails, String dumpPackage) {
15004
15005        ArrayList<Pair<ProcessRecord, Integer>> list
15006                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15007        for (int i=0; i<origList.size(); i++) {
15008            ProcessRecord r = origList.get(i);
15009            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15010                continue;
15011            }
15012            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15013        }
15014
15015        if (list.size() <= 0) {
15016            return false;
15017        }
15018
15019        Comparator<Pair<ProcessRecord, Integer>> comparator
15020                = new Comparator<Pair<ProcessRecord, Integer>>() {
15021            @Override
15022            public int compare(Pair<ProcessRecord, Integer> object1,
15023                    Pair<ProcessRecord, Integer> object2) {
15024                if (object1.first.setAdj != object2.first.setAdj) {
15025                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15026                }
15027                if (object1.first.setProcState != object2.first.setProcState) {
15028                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15029                }
15030                if (object1.second.intValue() != object2.second.intValue()) {
15031                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15032                }
15033                return 0;
15034            }
15035        };
15036
15037        Collections.sort(list, comparator);
15038
15039        final long curRealtime = SystemClock.elapsedRealtime();
15040        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15041        final long curUptime = SystemClock.uptimeMillis();
15042        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15043
15044        for (int i=list.size()-1; i>=0; i--) {
15045            ProcessRecord r = list.get(i).first;
15046            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15047            char schedGroup;
15048            switch (r.setSchedGroup) {
15049                case ProcessList.SCHED_GROUP_BACKGROUND:
15050                    schedGroup = 'B';
15051                    break;
15052                case ProcessList.SCHED_GROUP_DEFAULT:
15053                    schedGroup = 'F';
15054                    break;
15055                case ProcessList.SCHED_GROUP_TOP_APP:
15056                    schedGroup = 'T';
15057                    break;
15058                default:
15059                    schedGroup = '?';
15060                    break;
15061            }
15062            char foreground;
15063            if (r.foregroundActivities) {
15064                foreground = 'A';
15065            } else if (r.foregroundServices) {
15066                foreground = 'S';
15067            } else {
15068                foreground = ' ';
15069            }
15070            String procState = ProcessList.makeProcStateString(r.curProcState);
15071            pw.print(prefix);
15072            pw.print(r.persistent ? persistentLabel : normalLabel);
15073            pw.print(" #");
15074            int num = (origList.size()-1)-list.get(i).second;
15075            if (num < 10) pw.print(' ');
15076            pw.print(num);
15077            pw.print(": ");
15078            pw.print(oomAdj);
15079            pw.print(' ');
15080            pw.print(schedGroup);
15081            pw.print('/');
15082            pw.print(foreground);
15083            pw.print('/');
15084            pw.print(procState);
15085            pw.print(" trm:");
15086            if (r.trimMemoryLevel < 10) pw.print(' ');
15087            pw.print(r.trimMemoryLevel);
15088            pw.print(' ');
15089            pw.print(r.toShortString());
15090            pw.print(" (");
15091            pw.print(r.adjType);
15092            pw.println(')');
15093            if (r.adjSource != null || r.adjTarget != null) {
15094                pw.print(prefix);
15095                pw.print("    ");
15096                if (r.adjTarget instanceof ComponentName) {
15097                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15098                } else if (r.adjTarget != null) {
15099                    pw.print(r.adjTarget.toString());
15100                } else {
15101                    pw.print("{null}");
15102                }
15103                pw.print("<=");
15104                if (r.adjSource instanceof ProcessRecord) {
15105                    pw.print("Proc{");
15106                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15107                    pw.println("}");
15108                } else if (r.adjSource != null) {
15109                    pw.println(r.adjSource.toString());
15110                } else {
15111                    pw.println("{null}");
15112                }
15113            }
15114            if (inclDetails) {
15115                pw.print(prefix);
15116                pw.print("    ");
15117                pw.print("oom: max="); pw.print(r.maxAdj);
15118                pw.print(" curRaw="); pw.print(r.curRawAdj);
15119                pw.print(" setRaw="); pw.print(r.setRawAdj);
15120                pw.print(" cur="); pw.print(r.curAdj);
15121                pw.print(" set="); pw.println(r.setAdj);
15122                pw.print(prefix);
15123                pw.print("    ");
15124                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15125                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15126                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15127                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15128                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15129                pw.println();
15130                pw.print(prefix);
15131                pw.print("    ");
15132                pw.print("cached="); pw.print(r.cached);
15133                pw.print(" empty="); pw.print(r.empty);
15134                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15135
15136                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15137                    if (r.lastWakeTime != 0) {
15138                        long wtime;
15139                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15140                        synchronized (stats) {
15141                            wtime = stats.getProcessWakeTime(r.info.uid,
15142                                    r.pid, curRealtime);
15143                        }
15144                        long timeUsed = wtime - r.lastWakeTime;
15145                        pw.print(prefix);
15146                        pw.print("    ");
15147                        pw.print("keep awake over ");
15148                        TimeUtils.formatDuration(realtimeSince, pw);
15149                        pw.print(" used ");
15150                        TimeUtils.formatDuration(timeUsed, pw);
15151                        pw.print(" (");
15152                        pw.print((timeUsed*100)/realtimeSince);
15153                        pw.println("%)");
15154                    }
15155                    if (r.lastCpuTime != 0) {
15156                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15157                        pw.print(prefix);
15158                        pw.print("    ");
15159                        pw.print("run cpu over ");
15160                        TimeUtils.formatDuration(uptimeSince, pw);
15161                        pw.print(" used ");
15162                        TimeUtils.formatDuration(timeUsed, pw);
15163                        pw.print(" (");
15164                        pw.print((timeUsed*100)/uptimeSince);
15165                        pw.println("%)");
15166                    }
15167                }
15168            }
15169        }
15170        return true;
15171    }
15172
15173    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15174            String[] args) {
15175        ArrayList<ProcessRecord> procs;
15176        synchronized (this) {
15177            if (args != null && args.length > start
15178                    && args[start].charAt(0) != '-') {
15179                procs = new ArrayList<ProcessRecord>();
15180                int pid = -1;
15181                try {
15182                    pid = Integer.parseInt(args[start]);
15183                } catch (NumberFormatException e) {
15184                }
15185                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15186                    ProcessRecord proc = mLruProcesses.get(i);
15187                    if (proc.pid == pid) {
15188                        procs.add(proc);
15189                    } else if (allPkgs && proc.pkgList != null
15190                            && proc.pkgList.containsKey(args[start])) {
15191                        procs.add(proc);
15192                    } else if (proc.processName.equals(args[start])) {
15193                        procs.add(proc);
15194                    }
15195                }
15196                if (procs.size() <= 0) {
15197                    return null;
15198                }
15199            } else {
15200                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15201            }
15202        }
15203        return procs;
15204    }
15205
15206    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15207            PrintWriter pw, String[] args) {
15208        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15209        if (procs == null) {
15210            pw.println("No process found for: " + args[0]);
15211            return;
15212        }
15213
15214        long uptime = SystemClock.uptimeMillis();
15215        long realtime = SystemClock.elapsedRealtime();
15216        pw.println("Applications Graphics Acceleration Info:");
15217        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15218
15219        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15220            ProcessRecord r = procs.get(i);
15221            if (r.thread != null) {
15222                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15223                pw.flush();
15224                try {
15225                    TransferPipe tp = new TransferPipe();
15226                    try {
15227                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15228                        tp.go(fd);
15229                    } finally {
15230                        tp.kill();
15231                    }
15232                } catch (IOException e) {
15233                    pw.println("Failure while dumping the app: " + r);
15234                    pw.flush();
15235                } catch (RemoteException e) {
15236                    pw.println("Got a RemoteException while dumping the app " + r);
15237                    pw.flush();
15238                }
15239            }
15240        }
15241    }
15242
15243    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15244        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15245        if (procs == null) {
15246            pw.println("No process found for: " + args[0]);
15247            return;
15248        }
15249
15250        pw.println("Applications Database Info:");
15251
15252        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15253            ProcessRecord r = procs.get(i);
15254            if (r.thread != null) {
15255                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15256                pw.flush();
15257                try {
15258                    TransferPipe tp = new TransferPipe();
15259                    try {
15260                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15261                        tp.go(fd);
15262                    } finally {
15263                        tp.kill();
15264                    }
15265                } catch (IOException e) {
15266                    pw.println("Failure while dumping the app: " + r);
15267                    pw.flush();
15268                } catch (RemoteException e) {
15269                    pw.println("Got a RemoteException while dumping the app " + r);
15270                    pw.flush();
15271                }
15272            }
15273        }
15274    }
15275
15276    final static class MemItem {
15277        final boolean isProc;
15278        final String label;
15279        final String shortLabel;
15280        final long pss;
15281        final long swapPss;
15282        final int id;
15283        final boolean hasActivities;
15284        ArrayList<MemItem> subitems;
15285
15286        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15287                boolean _hasActivities) {
15288            isProc = true;
15289            label = _label;
15290            shortLabel = _shortLabel;
15291            pss = _pss;
15292            swapPss = _swapPss;
15293            id = _id;
15294            hasActivities = _hasActivities;
15295        }
15296
15297        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15298            isProc = false;
15299            label = _label;
15300            shortLabel = _shortLabel;
15301            pss = _pss;
15302            swapPss = _swapPss;
15303            id = _id;
15304            hasActivities = false;
15305        }
15306    }
15307
15308    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15309            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15310        if (sort && !isCompact) {
15311            Collections.sort(items, new Comparator<MemItem>() {
15312                @Override
15313                public int compare(MemItem lhs, MemItem rhs) {
15314                    if (lhs.pss < rhs.pss) {
15315                        return 1;
15316                    } else if (lhs.pss > rhs.pss) {
15317                        return -1;
15318                    }
15319                    return 0;
15320                }
15321            });
15322        }
15323
15324        for (int i=0; i<items.size(); i++) {
15325            MemItem mi = items.get(i);
15326            if (!isCompact) {
15327                if (dumpSwapPss) {
15328                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15329                            mi.label, stringifyKBSize(mi.swapPss));
15330                } else {
15331                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15332                }
15333            } else if (mi.isProc) {
15334                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15335                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15336                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15337                pw.println(mi.hasActivities ? ",a" : ",e");
15338            } else {
15339                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15340                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15341            }
15342            if (mi.subitems != null) {
15343                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15344                        true, isCompact, dumpSwapPss);
15345            }
15346        }
15347    }
15348
15349    // These are in KB.
15350    static final long[] DUMP_MEM_BUCKETS = new long[] {
15351        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15352        120*1024, 160*1024, 200*1024,
15353        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15354        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15355    };
15356
15357    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15358            boolean stackLike) {
15359        int start = label.lastIndexOf('.');
15360        if (start >= 0) start++;
15361        else start = 0;
15362        int end = label.length();
15363        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15364            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15365                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15366                out.append(bucket);
15367                out.append(stackLike ? "MB." : "MB ");
15368                out.append(label, start, end);
15369                return;
15370            }
15371        }
15372        out.append(memKB/1024);
15373        out.append(stackLike ? "MB." : "MB ");
15374        out.append(label, start, end);
15375    }
15376
15377    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15378            ProcessList.NATIVE_ADJ,
15379            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15380            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15381            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15382            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15383            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15384            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15385    };
15386    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15387            "Native",
15388            "System", "Persistent", "Persistent Service", "Foreground",
15389            "Visible", "Perceptible",
15390            "Heavy Weight", "Backup",
15391            "A Services", "Home",
15392            "Previous", "B Services", "Cached"
15393    };
15394    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15395            "native",
15396            "sys", "pers", "persvc", "fore",
15397            "vis", "percept",
15398            "heavy", "backup",
15399            "servicea", "home",
15400            "prev", "serviceb", "cached"
15401    };
15402
15403    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15404            long realtime, boolean isCheckinRequest, boolean isCompact) {
15405        if (isCompact) {
15406            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15407        }
15408        if (isCheckinRequest || isCompact) {
15409            // short checkin version
15410            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15411        } else {
15412            pw.println("Applications Memory Usage (in Kilobytes):");
15413            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15414        }
15415    }
15416
15417    private static final int KSM_SHARED = 0;
15418    private static final int KSM_SHARING = 1;
15419    private static final int KSM_UNSHARED = 2;
15420    private static final int KSM_VOLATILE = 3;
15421
15422    private final long[] getKsmInfo() {
15423        long[] longOut = new long[4];
15424        final int[] SINGLE_LONG_FORMAT = new int[] {
15425            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15426        };
15427        long[] longTmp = new long[1];
15428        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15429                SINGLE_LONG_FORMAT, null, longTmp, null);
15430        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15431        longTmp[0] = 0;
15432        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15433                SINGLE_LONG_FORMAT, null, longTmp, null);
15434        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15435        longTmp[0] = 0;
15436        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15437                SINGLE_LONG_FORMAT, null, longTmp, null);
15438        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15439        longTmp[0] = 0;
15440        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15441                SINGLE_LONG_FORMAT, null, longTmp, null);
15442        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15443        return longOut;
15444    }
15445
15446    private static String stringifySize(long size, int order) {
15447        Locale locale = Locale.US;
15448        switch (order) {
15449            case 1:
15450                return String.format(locale, "%,13d", size);
15451            case 1024:
15452                return String.format(locale, "%,9dK", size / 1024);
15453            case 1024 * 1024:
15454                return String.format(locale, "%,5dM", size / 1024 / 1024);
15455            case 1024 * 1024 * 1024:
15456                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15457            default:
15458                throw new IllegalArgumentException("Invalid size order");
15459        }
15460    }
15461
15462    private static String stringifyKBSize(long size) {
15463        return stringifySize(size * 1024, 1024);
15464    }
15465
15466    // Update this version number in case you change the 'compact' format
15467    private static final int MEMINFO_COMPACT_VERSION = 1;
15468
15469    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15470            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15471        boolean dumpDetails = false;
15472        boolean dumpFullDetails = false;
15473        boolean dumpDalvik = false;
15474        boolean dumpSummaryOnly = false;
15475        boolean dumpUnreachable = false;
15476        boolean oomOnly = false;
15477        boolean isCompact = false;
15478        boolean localOnly = false;
15479        boolean packages = false;
15480        boolean isCheckinRequest = false;
15481        boolean dumpSwapPss = false;
15482
15483        int opti = 0;
15484        while (opti < args.length) {
15485            String opt = args[opti];
15486            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15487                break;
15488            }
15489            opti++;
15490            if ("-a".equals(opt)) {
15491                dumpDetails = true;
15492                dumpFullDetails = true;
15493                dumpDalvik = true;
15494                dumpSwapPss = true;
15495            } else if ("-d".equals(opt)) {
15496                dumpDalvik = true;
15497            } else if ("-c".equals(opt)) {
15498                isCompact = true;
15499            } else if ("-s".equals(opt)) {
15500                dumpDetails = true;
15501                dumpSummaryOnly = true;
15502            } else if ("-S".equals(opt)) {
15503                dumpSwapPss = true;
15504            } else if ("--unreachable".equals(opt)) {
15505                dumpUnreachable = true;
15506            } else if ("--oom".equals(opt)) {
15507                oomOnly = true;
15508            } else if ("--local".equals(opt)) {
15509                localOnly = true;
15510            } else if ("--package".equals(opt)) {
15511                packages = true;
15512            } else if ("--checkin".equals(opt)) {
15513                isCheckinRequest = true;
15514
15515            } else if ("-h".equals(opt)) {
15516                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15517                pw.println("  -a: include all available information for each process.");
15518                pw.println("  -d: include dalvik details.");
15519                pw.println("  -c: dump in a compact machine-parseable representation.");
15520                pw.println("  -s: dump only summary of application memory usage.");
15521                pw.println("  -S: dump also SwapPss.");
15522                pw.println("  --oom: only show processes organized by oom adj.");
15523                pw.println("  --local: only collect details locally, don't call process.");
15524                pw.println("  --package: interpret process arg as package, dumping all");
15525                pw.println("             processes that have loaded that package.");
15526                pw.println("  --checkin: dump data for a checkin");
15527                pw.println("If [process] is specified it can be the name or ");
15528                pw.println("pid of a specific process to dump.");
15529                return;
15530            } else {
15531                pw.println("Unknown argument: " + opt + "; use -h for help");
15532            }
15533        }
15534
15535        long uptime = SystemClock.uptimeMillis();
15536        long realtime = SystemClock.elapsedRealtime();
15537        final long[] tmpLong = new long[1];
15538
15539        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15540        if (procs == null) {
15541            // No Java processes.  Maybe they want to print a native process.
15542            if (args != null && args.length > opti
15543                    && args[opti].charAt(0) != '-') {
15544                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15545                        = new ArrayList<ProcessCpuTracker.Stats>();
15546                updateCpuStatsNow();
15547                int findPid = -1;
15548                try {
15549                    findPid = Integer.parseInt(args[opti]);
15550                } catch (NumberFormatException e) {
15551                }
15552                synchronized (mProcessCpuTracker) {
15553                    final int N = mProcessCpuTracker.countStats();
15554                    for (int i=0; i<N; i++) {
15555                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15556                        if (st.pid == findPid || (st.baseName != null
15557                                && st.baseName.equals(args[opti]))) {
15558                            nativeProcs.add(st);
15559                        }
15560                    }
15561                }
15562                if (nativeProcs.size() > 0) {
15563                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15564                            isCompact);
15565                    Debug.MemoryInfo mi = null;
15566                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15567                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15568                        final int pid = r.pid;
15569                        if (!isCheckinRequest && dumpDetails) {
15570                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15571                        }
15572                        if (mi == null) {
15573                            mi = new Debug.MemoryInfo();
15574                        }
15575                        if (dumpDetails || (!brief && !oomOnly)) {
15576                            Debug.getMemoryInfo(pid, mi);
15577                        } else {
15578                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15579                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15580                        }
15581                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15582                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15583                        if (isCheckinRequest) {
15584                            pw.println();
15585                        }
15586                    }
15587                    return;
15588                }
15589            }
15590            pw.println("No process found for: " + args[opti]);
15591            return;
15592        }
15593
15594        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15595            dumpDetails = true;
15596        }
15597
15598        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15599
15600        String[] innerArgs = new String[args.length-opti];
15601        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15602
15603        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15604        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15605        long nativePss = 0;
15606        long nativeSwapPss = 0;
15607        long dalvikPss = 0;
15608        long dalvikSwapPss = 0;
15609        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15610                EmptyArray.LONG;
15611        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15612                EmptyArray.LONG;
15613        long otherPss = 0;
15614        long otherSwapPss = 0;
15615        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15616        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15617
15618        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15619        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15620        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15621                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15622
15623        long totalPss = 0;
15624        long totalSwapPss = 0;
15625        long cachedPss = 0;
15626        long cachedSwapPss = 0;
15627        boolean hasSwapPss = false;
15628
15629        Debug.MemoryInfo mi = null;
15630        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15631            final ProcessRecord r = procs.get(i);
15632            final IApplicationThread thread;
15633            final int pid;
15634            final int oomAdj;
15635            final boolean hasActivities;
15636            synchronized (this) {
15637                thread = r.thread;
15638                pid = r.pid;
15639                oomAdj = r.getSetAdjWithServices();
15640                hasActivities = r.activities.size() > 0;
15641            }
15642            if (thread != null) {
15643                if (!isCheckinRequest && dumpDetails) {
15644                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15645                }
15646                if (mi == null) {
15647                    mi = new Debug.MemoryInfo();
15648                }
15649                if (dumpDetails || (!brief && !oomOnly)) {
15650                    Debug.getMemoryInfo(pid, mi);
15651                    hasSwapPss = mi.hasSwappedOutPss;
15652                } else {
15653                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15654                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15655                }
15656                if (dumpDetails) {
15657                    if (localOnly) {
15658                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15659                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15660                        if (isCheckinRequest) {
15661                            pw.println();
15662                        }
15663                    } else {
15664                        try {
15665                            pw.flush();
15666                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15667                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15668                        } catch (RemoteException e) {
15669                            if (!isCheckinRequest) {
15670                                pw.println("Got RemoteException!");
15671                                pw.flush();
15672                            }
15673                        }
15674                    }
15675                }
15676
15677                final long myTotalPss = mi.getTotalPss();
15678                final long myTotalUss = mi.getTotalUss();
15679                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15680
15681                synchronized (this) {
15682                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15683                        // Record this for posterity if the process has been stable.
15684                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15685                    }
15686                }
15687
15688                if (!isCheckinRequest && mi != null) {
15689                    totalPss += myTotalPss;
15690                    totalSwapPss += myTotalSwapPss;
15691                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15692                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15693                            myTotalSwapPss, pid, hasActivities);
15694                    procMems.add(pssItem);
15695                    procMemsMap.put(pid, pssItem);
15696
15697                    nativePss += mi.nativePss;
15698                    nativeSwapPss += mi.nativeSwappedOutPss;
15699                    dalvikPss += mi.dalvikPss;
15700                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15701                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15702                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15703                        dalvikSubitemSwapPss[j] +=
15704                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15705                    }
15706                    otherPss += mi.otherPss;
15707                    otherSwapPss += mi.otherSwappedOutPss;
15708                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15709                        long mem = mi.getOtherPss(j);
15710                        miscPss[j] += mem;
15711                        otherPss -= mem;
15712                        mem = mi.getOtherSwappedOutPss(j);
15713                        miscSwapPss[j] += mem;
15714                        otherSwapPss -= mem;
15715                    }
15716
15717                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15718                        cachedPss += myTotalPss;
15719                        cachedSwapPss += myTotalSwapPss;
15720                    }
15721
15722                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15723                        if (oomIndex == (oomPss.length - 1)
15724                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15725                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15726                            oomPss[oomIndex] += myTotalPss;
15727                            oomSwapPss[oomIndex] += myTotalSwapPss;
15728                            if (oomProcs[oomIndex] == null) {
15729                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15730                            }
15731                            oomProcs[oomIndex].add(pssItem);
15732                            break;
15733                        }
15734                    }
15735                }
15736            }
15737        }
15738
15739        long nativeProcTotalPss = 0;
15740
15741        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15742            // If we are showing aggregations, also look for native processes to
15743            // include so that our aggregations are more accurate.
15744            updateCpuStatsNow();
15745            mi = null;
15746            synchronized (mProcessCpuTracker) {
15747                final int N = mProcessCpuTracker.countStats();
15748                for (int i=0; i<N; i++) {
15749                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15750                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15751                        if (mi == null) {
15752                            mi = new Debug.MemoryInfo();
15753                        }
15754                        if (!brief && !oomOnly) {
15755                            Debug.getMemoryInfo(st.pid, mi);
15756                        } else {
15757                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15758                            mi.nativePrivateDirty = (int)tmpLong[0];
15759                        }
15760
15761                        final long myTotalPss = mi.getTotalPss();
15762                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15763                        totalPss += myTotalPss;
15764                        nativeProcTotalPss += myTotalPss;
15765
15766                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15767                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15768                        procMems.add(pssItem);
15769
15770                        nativePss += mi.nativePss;
15771                        nativeSwapPss += mi.nativeSwappedOutPss;
15772                        dalvikPss += mi.dalvikPss;
15773                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15774                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15775                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15776                            dalvikSubitemSwapPss[j] +=
15777                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15778                        }
15779                        otherPss += mi.otherPss;
15780                        otherSwapPss += mi.otherSwappedOutPss;
15781                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15782                            long mem = mi.getOtherPss(j);
15783                            miscPss[j] += mem;
15784                            otherPss -= mem;
15785                            mem = mi.getOtherSwappedOutPss(j);
15786                            miscSwapPss[j] += mem;
15787                            otherSwapPss -= mem;
15788                        }
15789                        oomPss[0] += myTotalPss;
15790                        oomSwapPss[0] += myTotalSwapPss;
15791                        if (oomProcs[0] == null) {
15792                            oomProcs[0] = new ArrayList<MemItem>();
15793                        }
15794                        oomProcs[0].add(pssItem);
15795                    }
15796                }
15797            }
15798
15799            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15800
15801            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15802            final MemItem dalvikItem =
15803                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15804            if (dalvikSubitemPss.length > 0) {
15805                dalvikItem.subitems = new ArrayList<MemItem>();
15806                for (int j=0; j<dalvikSubitemPss.length; j++) {
15807                    final String name = Debug.MemoryInfo.getOtherLabel(
15808                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15809                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15810                                    dalvikSubitemSwapPss[j], j));
15811                }
15812            }
15813            catMems.add(dalvikItem);
15814            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15815            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15816                String label = Debug.MemoryInfo.getOtherLabel(j);
15817                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15818            }
15819
15820            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15821            for (int j=0; j<oomPss.length; j++) {
15822                if (oomPss[j] != 0) {
15823                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15824                            : DUMP_MEM_OOM_LABEL[j];
15825                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15826                            DUMP_MEM_OOM_ADJ[j]);
15827                    item.subitems = oomProcs[j];
15828                    oomMems.add(item);
15829                }
15830            }
15831
15832            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15833            if (!brief && !oomOnly && !isCompact) {
15834                pw.println();
15835                pw.println("Total PSS by process:");
15836                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15837                pw.println();
15838            }
15839            if (!isCompact) {
15840                pw.println("Total PSS by OOM adjustment:");
15841            }
15842            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15843            if (!brief && !oomOnly) {
15844                PrintWriter out = categoryPw != null ? categoryPw : pw;
15845                if (!isCompact) {
15846                    out.println();
15847                    out.println("Total PSS by category:");
15848                }
15849                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15850            }
15851            if (!isCompact) {
15852                pw.println();
15853            }
15854            MemInfoReader memInfo = new MemInfoReader();
15855            memInfo.readMemInfo();
15856            if (nativeProcTotalPss > 0) {
15857                synchronized (this) {
15858                    final long cachedKb = memInfo.getCachedSizeKb();
15859                    final long freeKb = memInfo.getFreeSizeKb();
15860                    final long zramKb = memInfo.getZramTotalSizeKb();
15861                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15862                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15863                            kernelKb*1024, nativeProcTotalPss*1024);
15864                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15865                            nativeProcTotalPss);
15866                }
15867            }
15868            if (!brief) {
15869                if (!isCompact) {
15870                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15871                    pw.print(" (status ");
15872                    switch (mLastMemoryLevel) {
15873                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15874                            pw.println("normal)");
15875                            break;
15876                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15877                            pw.println("moderate)");
15878                            break;
15879                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15880                            pw.println("low)");
15881                            break;
15882                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15883                            pw.println("critical)");
15884                            break;
15885                        default:
15886                            pw.print(mLastMemoryLevel);
15887                            pw.println(")");
15888                            break;
15889                    }
15890                    pw.print(" Free RAM: ");
15891                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15892                            + memInfo.getFreeSizeKb()));
15893                    pw.print(" (");
15894                    pw.print(stringifyKBSize(cachedPss));
15895                    pw.print(" cached pss + ");
15896                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15897                    pw.print(" cached kernel + ");
15898                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15899                    pw.println(" free)");
15900                } else {
15901                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15902                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15903                            + memInfo.getFreeSizeKb()); pw.print(",");
15904                    pw.println(totalPss - cachedPss);
15905                }
15906            }
15907            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15908                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15909                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15910            if (!isCompact) {
15911                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15912                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15913                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15914                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15915                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15916            } else {
15917                pw.print("lostram,"); pw.println(lostRAM);
15918            }
15919            if (!brief) {
15920                if (memInfo.getZramTotalSizeKb() != 0) {
15921                    if (!isCompact) {
15922                        pw.print("     ZRAM: ");
15923                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15924                                pw.print(" physical used for ");
15925                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15926                                        - memInfo.getSwapFreeSizeKb()));
15927                                pw.print(" in swap (");
15928                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15929                                pw.println(" total swap)");
15930                    } else {
15931                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15932                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15933                                pw.println(memInfo.getSwapFreeSizeKb());
15934                    }
15935                }
15936                final long[] ksm = getKsmInfo();
15937                if (!isCompact) {
15938                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15939                            || ksm[KSM_VOLATILE] != 0) {
15940                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15941                                pw.print(" saved from shared ");
15942                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15943                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15944                                pw.print(" unshared; ");
15945                                pw.print(stringifyKBSize(
15946                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15947                    }
15948                    pw.print("   Tuning: ");
15949                    pw.print(ActivityManager.staticGetMemoryClass());
15950                    pw.print(" (large ");
15951                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15952                    pw.print("), oom ");
15953                    pw.print(stringifySize(
15954                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15955                    pw.print(", restore limit ");
15956                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15957                    if (ActivityManager.isLowRamDeviceStatic()) {
15958                        pw.print(" (low-ram)");
15959                    }
15960                    if (ActivityManager.isHighEndGfx()) {
15961                        pw.print(" (high-end-gfx)");
15962                    }
15963                    pw.println();
15964                } else {
15965                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15966                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15967                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15968                    pw.print("tuning,");
15969                    pw.print(ActivityManager.staticGetMemoryClass());
15970                    pw.print(',');
15971                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15972                    pw.print(',');
15973                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15974                    if (ActivityManager.isLowRamDeviceStatic()) {
15975                        pw.print(",low-ram");
15976                    }
15977                    if (ActivityManager.isHighEndGfx()) {
15978                        pw.print(",high-end-gfx");
15979                    }
15980                    pw.println();
15981                }
15982            }
15983        }
15984    }
15985
15986    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15987            long memtrack, String name) {
15988        sb.append("  ");
15989        sb.append(ProcessList.makeOomAdjString(oomAdj));
15990        sb.append(' ');
15991        sb.append(ProcessList.makeProcStateString(procState));
15992        sb.append(' ');
15993        ProcessList.appendRamKb(sb, pss);
15994        sb.append(": ");
15995        sb.append(name);
15996        if (memtrack > 0) {
15997            sb.append(" (");
15998            sb.append(stringifyKBSize(memtrack));
15999            sb.append(" memtrack)");
16000        }
16001    }
16002
16003    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16004        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16005        sb.append(" (pid ");
16006        sb.append(mi.pid);
16007        sb.append(") ");
16008        sb.append(mi.adjType);
16009        sb.append('\n');
16010        if (mi.adjReason != null) {
16011            sb.append("                      ");
16012            sb.append(mi.adjReason);
16013            sb.append('\n');
16014        }
16015    }
16016
16017    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16018        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16019        for (int i=0, N=memInfos.size(); i<N; i++) {
16020            ProcessMemInfo mi = memInfos.get(i);
16021            infoMap.put(mi.pid, mi);
16022        }
16023        updateCpuStatsNow();
16024        long[] memtrackTmp = new long[1];
16025        synchronized (mProcessCpuTracker) {
16026            final int N = mProcessCpuTracker.countStats();
16027            for (int i=0; i<N; i++) {
16028                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16029                if (st.vsize > 0) {
16030                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16031                    if (pss > 0) {
16032                        if (infoMap.indexOfKey(st.pid) < 0) {
16033                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16034                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16035                            mi.pss = pss;
16036                            mi.memtrack = memtrackTmp[0];
16037                            memInfos.add(mi);
16038                        }
16039                    }
16040                }
16041            }
16042        }
16043
16044        long totalPss = 0;
16045        long totalMemtrack = 0;
16046        for (int i=0, N=memInfos.size(); i<N; i++) {
16047            ProcessMemInfo mi = memInfos.get(i);
16048            if (mi.pss == 0) {
16049                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16050                mi.memtrack = memtrackTmp[0];
16051            }
16052            totalPss += mi.pss;
16053            totalMemtrack += mi.memtrack;
16054        }
16055        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16056            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16057                if (lhs.oomAdj != rhs.oomAdj) {
16058                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16059                }
16060                if (lhs.pss != rhs.pss) {
16061                    return lhs.pss < rhs.pss ? 1 : -1;
16062                }
16063                return 0;
16064            }
16065        });
16066
16067        StringBuilder tag = new StringBuilder(128);
16068        StringBuilder stack = new StringBuilder(128);
16069        tag.append("Low on memory -- ");
16070        appendMemBucket(tag, totalPss, "total", false);
16071        appendMemBucket(stack, totalPss, "total", true);
16072
16073        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16074        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16075        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16076
16077        boolean firstLine = true;
16078        int lastOomAdj = Integer.MIN_VALUE;
16079        long extraNativeRam = 0;
16080        long extraNativeMemtrack = 0;
16081        long cachedPss = 0;
16082        for (int i=0, N=memInfos.size(); i<N; i++) {
16083            ProcessMemInfo mi = memInfos.get(i);
16084
16085            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16086                cachedPss += mi.pss;
16087            }
16088
16089            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16090                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16091                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16092                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16093                if (lastOomAdj != mi.oomAdj) {
16094                    lastOomAdj = mi.oomAdj;
16095                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16096                        tag.append(" / ");
16097                    }
16098                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16099                        if (firstLine) {
16100                            stack.append(":");
16101                            firstLine = false;
16102                        }
16103                        stack.append("\n\t at ");
16104                    } else {
16105                        stack.append("$");
16106                    }
16107                } else {
16108                    tag.append(" ");
16109                    stack.append("$");
16110                }
16111                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16112                    appendMemBucket(tag, mi.pss, mi.name, false);
16113                }
16114                appendMemBucket(stack, mi.pss, mi.name, true);
16115                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16116                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16117                    stack.append("(");
16118                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16119                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16120                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16121                            stack.append(":");
16122                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16123                        }
16124                    }
16125                    stack.append(")");
16126                }
16127            }
16128
16129            appendMemInfo(fullNativeBuilder, mi);
16130            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16131                // The short form only has native processes that are >= 512K.
16132                if (mi.pss >= 512) {
16133                    appendMemInfo(shortNativeBuilder, mi);
16134                } else {
16135                    extraNativeRam += mi.pss;
16136                    extraNativeMemtrack += mi.memtrack;
16137                }
16138            } else {
16139                // Short form has all other details, but if we have collected RAM
16140                // from smaller native processes let's dump a summary of that.
16141                if (extraNativeRam > 0) {
16142                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16143                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16144                    shortNativeBuilder.append('\n');
16145                    extraNativeRam = 0;
16146                }
16147                appendMemInfo(fullJavaBuilder, mi);
16148            }
16149        }
16150
16151        fullJavaBuilder.append("           ");
16152        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16153        fullJavaBuilder.append(": TOTAL");
16154        if (totalMemtrack > 0) {
16155            fullJavaBuilder.append(" (");
16156            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16157            fullJavaBuilder.append(" memtrack)");
16158        } else {
16159        }
16160        fullJavaBuilder.append("\n");
16161
16162        MemInfoReader memInfo = new MemInfoReader();
16163        memInfo.readMemInfo();
16164        final long[] infos = memInfo.getRawInfo();
16165
16166        StringBuilder memInfoBuilder = new StringBuilder(1024);
16167        Debug.getMemInfo(infos);
16168        memInfoBuilder.append("  MemInfo: ");
16169        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16170        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16171        memInfoBuilder.append(stringifyKBSize(
16172                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16173        memInfoBuilder.append(stringifyKBSize(
16174                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16175        memInfoBuilder.append(stringifyKBSize(
16176                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16177        memInfoBuilder.append("           ");
16178        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16179        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16180        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16181        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16182        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16183            memInfoBuilder.append("  ZRAM: ");
16184            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16185            memInfoBuilder.append(" RAM, ");
16186            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16187            memInfoBuilder.append(" swap total, ");
16188            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16189            memInfoBuilder.append(" swap free\n");
16190        }
16191        final long[] ksm = getKsmInfo();
16192        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16193                || ksm[KSM_VOLATILE] != 0) {
16194            memInfoBuilder.append("  KSM: ");
16195            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16196            memInfoBuilder.append(" saved from shared ");
16197            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16198            memInfoBuilder.append("\n       ");
16199            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16200            memInfoBuilder.append(" unshared; ");
16201            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16202            memInfoBuilder.append(" volatile\n");
16203        }
16204        memInfoBuilder.append("  Free RAM: ");
16205        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16206                + memInfo.getFreeSizeKb()));
16207        memInfoBuilder.append("\n");
16208        memInfoBuilder.append("  Used RAM: ");
16209        memInfoBuilder.append(stringifyKBSize(
16210                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16211        memInfoBuilder.append("\n");
16212        memInfoBuilder.append("  Lost RAM: ");
16213        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16214                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16215                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16216        memInfoBuilder.append("\n");
16217        Slog.i(TAG, "Low on memory:");
16218        Slog.i(TAG, shortNativeBuilder.toString());
16219        Slog.i(TAG, fullJavaBuilder.toString());
16220        Slog.i(TAG, memInfoBuilder.toString());
16221
16222        StringBuilder dropBuilder = new StringBuilder(1024);
16223        /*
16224        StringWriter oomSw = new StringWriter();
16225        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16226        StringWriter catSw = new StringWriter();
16227        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16228        String[] emptyArgs = new String[] { };
16229        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16230        oomPw.flush();
16231        String oomString = oomSw.toString();
16232        */
16233        dropBuilder.append("Low on memory:");
16234        dropBuilder.append(stack);
16235        dropBuilder.append('\n');
16236        dropBuilder.append(fullNativeBuilder);
16237        dropBuilder.append(fullJavaBuilder);
16238        dropBuilder.append('\n');
16239        dropBuilder.append(memInfoBuilder);
16240        dropBuilder.append('\n');
16241        /*
16242        dropBuilder.append(oomString);
16243        dropBuilder.append('\n');
16244        */
16245        StringWriter catSw = new StringWriter();
16246        synchronized (ActivityManagerService.this) {
16247            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16248            String[] emptyArgs = new String[] { };
16249            catPw.println();
16250            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16251            catPw.println();
16252            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16253                    false, null).dumpLocked();
16254            catPw.println();
16255            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16256            catPw.flush();
16257        }
16258        dropBuilder.append(catSw.toString());
16259        addErrorToDropBox("lowmem", null, "system_server", null,
16260                null, tag.toString(), dropBuilder.toString(), null, null);
16261        //Slog.i(TAG, "Sent to dropbox:");
16262        //Slog.i(TAG, dropBuilder.toString());
16263        synchronized (ActivityManagerService.this) {
16264            long now = SystemClock.uptimeMillis();
16265            if (mLastMemUsageReportTime < now) {
16266                mLastMemUsageReportTime = now;
16267            }
16268        }
16269    }
16270
16271    /**
16272     * Searches array of arguments for the specified string
16273     * @param args array of argument strings
16274     * @param value value to search for
16275     * @return true if the value is contained in the array
16276     */
16277    private static boolean scanArgs(String[] args, String value) {
16278        if (args != null) {
16279            for (String arg : args) {
16280                if (value.equals(arg)) {
16281                    return true;
16282                }
16283            }
16284        }
16285        return false;
16286    }
16287
16288    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16289            ContentProviderRecord cpr, boolean always) {
16290        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16291
16292        if (!inLaunching || always) {
16293            synchronized (cpr) {
16294                cpr.launchingApp = null;
16295                cpr.notifyAll();
16296            }
16297            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16298            String names[] = cpr.info.authority.split(";");
16299            for (int j = 0; j < names.length; j++) {
16300                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16301            }
16302        }
16303
16304        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16305            ContentProviderConnection conn = cpr.connections.get(i);
16306            if (conn.waiting) {
16307                // If this connection is waiting for the provider, then we don't
16308                // need to mess with its process unless we are always removing
16309                // or for some reason the provider is not currently launching.
16310                if (inLaunching && !always) {
16311                    continue;
16312                }
16313            }
16314            ProcessRecord capp = conn.client;
16315            conn.dead = true;
16316            if (conn.stableCount > 0) {
16317                if (!capp.persistent && capp.thread != null
16318                        && capp.pid != 0
16319                        && capp.pid != MY_PID) {
16320                    capp.kill("depends on provider "
16321                            + cpr.name.flattenToShortString()
16322                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16323                }
16324            } else if (capp.thread != null && conn.provider.provider != null) {
16325                try {
16326                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16327                } catch (RemoteException e) {
16328                }
16329                // In the protocol here, we don't expect the client to correctly
16330                // clean up this connection, we'll just remove it.
16331                cpr.connections.remove(i);
16332                if (conn.client.conProviders.remove(conn)) {
16333                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16334                }
16335            }
16336        }
16337
16338        if (inLaunching && always) {
16339            mLaunchingProviders.remove(cpr);
16340        }
16341        return inLaunching;
16342    }
16343
16344    /**
16345     * Main code for cleaning up a process when it has gone away.  This is
16346     * called both as a result of the process dying, or directly when stopping
16347     * a process when running in single process mode.
16348     *
16349     * @return Returns true if the given process has been restarted, so the
16350     * app that was passed in must remain on the process lists.
16351     */
16352    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16353            boolean restarting, boolean allowRestart, int index) {
16354        if (index >= 0) {
16355            removeLruProcessLocked(app);
16356            ProcessList.remove(app.pid);
16357        }
16358
16359        mProcessesToGc.remove(app);
16360        mPendingPssProcesses.remove(app);
16361
16362        // Dismiss any open dialogs.
16363        if (app.crashDialog != null && !app.forceCrashReport) {
16364            app.crashDialog.dismiss();
16365            app.crashDialog = null;
16366        }
16367        if (app.anrDialog != null) {
16368            app.anrDialog.dismiss();
16369            app.anrDialog = null;
16370        }
16371        if (app.waitDialog != null) {
16372            app.waitDialog.dismiss();
16373            app.waitDialog = null;
16374        }
16375
16376        app.crashing = false;
16377        app.notResponding = false;
16378
16379        app.resetPackageList(mProcessStats);
16380        app.unlinkDeathRecipient();
16381        app.makeInactive(mProcessStats);
16382        app.waitingToKill = null;
16383        app.forcingToForeground = null;
16384        updateProcessForegroundLocked(app, false, false);
16385        app.foregroundActivities = false;
16386        app.hasShownUi = false;
16387        app.treatLikeActivity = false;
16388        app.hasAboveClient = false;
16389        app.hasClientActivities = false;
16390
16391        mServices.killServicesLocked(app, allowRestart);
16392
16393        boolean restart = false;
16394
16395        // Remove published content providers.
16396        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16397            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16398            final boolean always = app.bad || !allowRestart;
16399            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16400            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16401                // We left the provider in the launching list, need to
16402                // restart it.
16403                restart = true;
16404            }
16405
16406            cpr.provider = null;
16407            cpr.proc = null;
16408        }
16409        app.pubProviders.clear();
16410
16411        // Take care of any launching providers waiting for this process.
16412        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16413            restart = true;
16414        }
16415
16416        // Unregister from connected content providers.
16417        if (!app.conProviders.isEmpty()) {
16418            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16419                ContentProviderConnection conn = app.conProviders.get(i);
16420                conn.provider.connections.remove(conn);
16421                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16422                        conn.provider.name);
16423            }
16424            app.conProviders.clear();
16425        }
16426
16427        // At this point there may be remaining entries in mLaunchingProviders
16428        // where we were the only one waiting, so they are no longer of use.
16429        // Look for these and clean up if found.
16430        // XXX Commented out for now.  Trying to figure out a way to reproduce
16431        // the actual situation to identify what is actually going on.
16432        if (false) {
16433            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16434                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16435                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16436                    synchronized (cpr) {
16437                        cpr.launchingApp = null;
16438                        cpr.notifyAll();
16439                    }
16440                }
16441            }
16442        }
16443
16444        skipCurrentReceiverLocked(app);
16445
16446        // Unregister any receivers.
16447        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16448            removeReceiverLocked(app.receivers.valueAt(i));
16449        }
16450        app.receivers.clear();
16451
16452        // If the app is undergoing backup, tell the backup manager about it
16453        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16454            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16455                    + mBackupTarget.appInfo + " died during backup");
16456            try {
16457                IBackupManager bm = IBackupManager.Stub.asInterface(
16458                        ServiceManager.getService(Context.BACKUP_SERVICE));
16459                bm.agentDisconnected(app.info.packageName);
16460            } catch (RemoteException e) {
16461                // can't happen; backup manager is local
16462            }
16463        }
16464
16465        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16466            ProcessChangeItem item = mPendingProcessChanges.get(i);
16467            if (item.pid == app.pid) {
16468                mPendingProcessChanges.remove(i);
16469                mAvailProcessChanges.add(item);
16470            }
16471        }
16472        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16473                null).sendToTarget();
16474
16475        // If the caller is restarting this app, then leave it in its
16476        // current lists and let the caller take care of it.
16477        if (restarting) {
16478            return false;
16479        }
16480
16481        if (!app.persistent || app.isolated) {
16482            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16483                    "Removing non-persistent process during cleanup: " + app);
16484            removeProcessNameLocked(app.processName, app.uid);
16485            if (mHeavyWeightProcess == app) {
16486                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16487                        mHeavyWeightProcess.userId, 0));
16488                mHeavyWeightProcess = null;
16489            }
16490        } else if (!app.removed) {
16491            // This app is persistent, so we need to keep its record around.
16492            // If it is not already on the pending app list, add it there
16493            // and start a new process for it.
16494            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16495                mPersistentStartingProcesses.add(app);
16496                restart = true;
16497            }
16498        }
16499        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16500                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16501        mProcessesOnHold.remove(app);
16502
16503        if (app == mHomeProcess) {
16504            mHomeProcess = null;
16505        }
16506        if (app == mPreviousProcess) {
16507            mPreviousProcess = null;
16508        }
16509
16510        if (restart && !app.isolated) {
16511            // We have components that still need to be running in the
16512            // process, so re-launch it.
16513            if (index < 0) {
16514                ProcessList.remove(app.pid);
16515            }
16516            addProcessNameLocked(app);
16517            startProcessLocked(app, "restart", app.processName);
16518            return true;
16519        } else if (app.pid > 0 && app.pid != MY_PID) {
16520            // Goodbye!
16521            boolean removed;
16522            synchronized (mPidsSelfLocked) {
16523                mPidsSelfLocked.remove(app.pid);
16524                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16525            }
16526            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16527            if (app.isolated) {
16528                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16529            }
16530            app.setPid(0);
16531        }
16532        return false;
16533    }
16534
16535    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16536        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16537            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16538            if (cpr.launchingApp == app) {
16539                return true;
16540            }
16541        }
16542        return false;
16543    }
16544
16545    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16546        // Look through the content providers we are waiting to have launched,
16547        // and if any run in this process then either schedule a restart of
16548        // the process or kill the client waiting for it if this process has
16549        // gone bad.
16550        boolean restart = false;
16551        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16552            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16553            if (cpr.launchingApp == app) {
16554                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16555                    restart = true;
16556                } else {
16557                    removeDyingProviderLocked(app, cpr, true);
16558                }
16559            }
16560        }
16561        return restart;
16562    }
16563
16564    // =========================================================
16565    // SERVICES
16566    // =========================================================
16567
16568    @Override
16569    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16570            int flags) {
16571        enforceNotIsolatedCaller("getServices");
16572        synchronized (this) {
16573            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16574        }
16575    }
16576
16577    @Override
16578    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16579        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16580        synchronized (this) {
16581            return mServices.getRunningServiceControlPanelLocked(name);
16582        }
16583    }
16584
16585    @Override
16586    public ComponentName startService(IApplicationThread caller, Intent service,
16587            String resolvedType, String callingPackage, int userId)
16588            throws TransactionTooLargeException {
16589        enforceNotIsolatedCaller("startService");
16590        // Refuse possible leaked file descriptors
16591        if (service != null && service.hasFileDescriptors() == true) {
16592            throw new IllegalArgumentException("File descriptors passed in Intent");
16593        }
16594
16595        if (callingPackage == null) {
16596            throw new IllegalArgumentException("callingPackage cannot be null");
16597        }
16598
16599        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16600                "startService: " + service + " type=" + resolvedType);
16601        synchronized(this) {
16602            final int callingPid = Binder.getCallingPid();
16603            final int callingUid = Binder.getCallingUid();
16604            final long origId = Binder.clearCallingIdentity();
16605            ComponentName res = mServices.startServiceLocked(caller, service,
16606                    resolvedType, callingPid, callingUid, callingPackage, userId);
16607            Binder.restoreCallingIdentity(origId);
16608            return res;
16609        }
16610    }
16611
16612    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16613            String callingPackage, int userId)
16614            throws TransactionTooLargeException {
16615        synchronized(this) {
16616            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16617                    "startServiceInPackage: " + service + " type=" + resolvedType);
16618            final long origId = Binder.clearCallingIdentity();
16619            ComponentName res = mServices.startServiceLocked(null, service,
16620                    resolvedType, -1, uid, callingPackage, userId);
16621            Binder.restoreCallingIdentity(origId);
16622            return res;
16623        }
16624    }
16625
16626    @Override
16627    public int stopService(IApplicationThread caller, Intent service,
16628            String resolvedType, int userId) {
16629        enforceNotIsolatedCaller("stopService");
16630        // Refuse possible leaked file descriptors
16631        if (service != null && service.hasFileDescriptors() == true) {
16632            throw new IllegalArgumentException("File descriptors passed in Intent");
16633        }
16634
16635        synchronized(this) {
16636            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16637        }
16638    }
16639
16640    @Override
16641    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16642        enforceNotIsolatedCaller("peekService");
16643        // Refuse possible leaked file descriptors
16644        if (service != null && service.hasFileDescriptors() == true) {
16645            throw new IllegalArgumentException("File descriptors passed in Intent");
16646        }
16647
16648        if (callingPackage == null) {
16649            throw new IllegalArgumentException("callingPackage cannot be null");
16650        }
16651
16652        synchronized(this) {
16653            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16654        }
16655    }
16656
16657    @Override
16658    public boolean stopServiceToken(ComponentName className, IBinder token,
16659            int startId) {
16660        synchronized(this) {
16661            return mServices.stopServiceTokenLocked(className, token, startId);
16662        }
16663    }
16664
16665    @Override
16666    public void setServiceForeground(ComponentName className, IBinder token,
16667            int id, Notification notification, int flags) {
16668        synchronized(this) {
16669            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16670        }
16671    }
16672
16673    @Override
16674    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16675            boolean requireFull, String name, String callerPackage) {
16676        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16677                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16678    }
16679
16680    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16681            String className, int flags) {
16682        boolean result = false;
16683        // For apps that don't have pre-defined UIDs, check for permission
16684        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16685            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16686                if (ActivityManager.checkUidPermission(
16687                        INTERACT_ACROSS_USERS,
16688                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16689                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16690                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16691                            + " requests FLAG_SINGLE_USER, but app does not hold "
16692                            + INTERACT_ACROSS_USERS;
16693                    Slog.w(TAG, msg);
16694                    throw new SecurityException(msg);
16695                }
16696                // Permission passed
16697                result = true;
16698            }
16699        } else if ("system".equals(componentProcessName)) {
16700            result = true;
16701        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16702            // Phone app and persistent apps are allowed to export singleuser providers.
16703            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16704                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16705        }
16706        if (DEBUG_MU) Slog.v(TAG_MU,
16707                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16708                + Integer.toHexString(flags) + ") = " + result);
16709        return result;
16710    }
16711
16712    /**
16713     * Checks to see if the caller is in the same app as the singleton
16714     * component, or the component is in a special app. It allows special apps
16715     * to export singleton components but prevents exporting singleton
16716     * components for regular apps.
16717     */
16718    boolean isValidSingletonCall(int callingUid, int componentUid) {
16719        int componentAppId = UserHandle.getAppId(componentUid);
16720        return UserHandle.isSameApp(callingUid, componentUid)
16721                || componentAppId == Process.SYSTEM_UID
16722                || componentAppId == Process.PHONE_UID
16723                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16724                        == PackageManager.PERMISSION_GRANTED;
16725    }
16726
16727    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16728            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16729            int userId) throws TransactionTooLargeException {
16730        enforceNotIsolatedCaller("bindService");
16731
16732        // Refuse possible leaked file descriptors
16733        if (service != null && service.hasFileDescriptors() == true) {
16734            throw new IllegalArgumentException("File descriptors passed in Intent");
16735        }
16736
16737        if (callingPackage == null) {
16738            throw new IllegalArgumentException("callingPackage cannot be null");
16739        }
16740
16741        synchronized(this) {
16742            return mServices.bindServiceLocked(caller, token, service,
16743                    resolvedType, connection, flags, callingPackage, userId);
16744        }
16745    }
16746
16747    public boolean unbindService(IServiceConnection connection) {
16748        synchronized (this) {
16749            return mServices.unbindServiceLocked(connection);
16750        }
16751    }
16752
16753    public void publishService(IBinder token, Intent intent, IBinder service) {
16754        // Refuse possible leaked file descriptors
16755        if (intent != null && intent.hasFileDescriptors() == true) {
16756            throw new IllegalArgumentException("File descriptors passed in Intent");
16757        }
16758
16759        synchronized(this) {
16760            if (!(token instanceof ServiceRecord)) {
16761                throw new IllegalArgumentException("Invalid service token");
16762            }
16763            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16764        }
16765    }
16766
16767    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16768        // Refuse possible leaked file descriptors
16769        if (intent != null && intent.hasFileDescriptors() == true) {
16770            throw new IllegalArgumentException("File descriptors passed in Intent");
16771        }
16772
16773        synchronized(this) {
16774            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16775        }
16776    }
16777
16778    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16779        synchronized(this) {
16780            if (!(token instanceof ServiceRecord)) {
16781                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16782                throw new IllegalArgumentException("Invalid service token");
16783            }
16784            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16785        }
16786    }
16787
16788    // =========================================================
16789    // BACKUP AND RESTORE
16790    // =========================================================
16791
16792    // Cause the target app to be launched if necessary and its backup agent
16793    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16794    // activity manager to announce its creation.
16795    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16796        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16797                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16798        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16799
16800        synchronized(this) {
16801            // !!! TODO: currently no check here that we're already bound
16802            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16803            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16804            synchronized (stats) {
16805                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16806            }
16807
16808            // Backup agent is now in use, its package can't be stopped.
16809            try {
16810                AppGlobals.getPackageManager().setPackageStoppedState(
16811                        app.packageName, false, UserHandle.getUserId(app.uid));
16812            } catch (RemoteException e) {
16813            } catch (IllegalArgumentException e) {
16814                Slog.w(TAG, "Failed trying to unstop package "
16815                        + app.packageName + ": " + e);
16816            }
16817
16818            BackupRecord r = new BackupRecord(ss, app, backupMode);
16819            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16820                    ? new ComponentName(app.packageName, app.backupAgentName)
16821                    : new ComponentName("android", "FullBackupAgent");
16822            // startProcessLocked() returns existing proc's record if it's already running
16823            ProcessRecord proc = startProcessLocked(app.processName, app,
16824                    false, 0, "backup", hostingName, false, false, false);
16825            if (proc == null) {
16826                Slog.e(TAG, "Unable to start backup agent process " + r);
16827                return false;
16828            }
16829
16830            r.app = proc;
16831            mBackupTarget = r;
16832            mBackupAppName = app.packageName;
16833
16834            // Try not to kill the process during backup
16835            updateOomAdjLocked(proc);
16836
16837            // If the process is already attached, schedule the creation of the backup agent now.
16838            // If it is not yet live, this will be done when it attaches to the framework.
16839            if (proc.thread != null) {
16840                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16841                try {
16842                    proc.thread.scheduleCreateBackupAgent(app,
16843                            compatibilityInfoForPackageLocked(app), backupMode);
16844                } catch (RemoteException e) {
16845                    // Will time out on the backup manager side
16846                }
16847            } else {
16848                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16849            }
16850            // Invariants: at this point, the target app process exists and the application
16851            // is either already running or in the process of coming up.  mBackupTarget and
16852            // mBackupAppName describe the app, so that when it binds back to the AM we
16853            // know that it's scheduled for a backup-agent operation.
16854        }
16855
16856        return true;
16857    }
16858
16859    @Override
16860    public void clearPendingBackup() {
16861        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16862        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16863
16864        synchronized (this) {
16865            mBackupTarget = null;
16866            mBackupAppName = null;
16867        }
16868    }
16869
16870    // A backup agent has just come up
16871    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16872        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16873                + " = " + agent);
16874
16875        synchronized(this) {
16876            if (!agentPackageName.equals(mBackupAppName)) {
16877                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16878                return;
16879            }
16880        }
16881
16882        long oldIdent = Binder.clearCallingIdentity();
16883        try {
16884            IBackupManager bm = IBackupManager.Stub.asInterface(
16885                    ServiceManager.getService(Context.BACKUP_SERVICE));
16886            bm.agentConnected(agentPackageName, agent);
16887        } catch (RemoteException e) {
16888            // can't happen; the backup manager service is local
16889        } catch (Exception e) {
16890            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16891            e.printStackTrace();
16892        } finally {
16893            Binder.restoreCallingIdentity(oldIdent);
16894        }
16895    }
16896
16897    // done with this agent
16898    public void unbindBackupAgent(ApplicationInfo appInfo) {
16899        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16900        if (appInfo == null) {
16901            Slog.w(TAG, "unbind backup agent for null app");
16902            return;
16903        }
16904
16905        synchronized(this) {
16906            try {
16907                if (mBackupAppName == null) {
16908                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16909                    return;
16910                }
16911
16912                if (!mBackupAppName.equals(appInfo.packageName)) {
16913                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16914                    return;
16915                }
16916
16917                // Not backing this app up any more; reset its OOM adjustment
16918                final ProcessRecord proc = mBackupTarget.app;
16919                updateOomAdjLocked(proc);
16920
16921                // If the app crashed during backup, 'thread' will be null here
16922                if (proc.thread != null) {
16923                    try {
16924                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16925                                compatibilityInfoForPackageLocked(appInfo));
16926                    } catch (Exception e) {
16927                        Slog.e(TAG, "Exception when unbinding backup agent:");
16928                        e.printStackTrace();
16929                    }
16930                }
16931            } finally {
16932                mBackupTarget = null;
16933                mBackupAppName = null;
16934            }
16935        }
16936    }
16937    // =========================================================
16938    // BROADCASTS
16939    // =========================================================
16940
16941    boolean isPendingBroadcastProcessLocked(int pid) {
16942        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16943                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16944    }
16945
16946    void skipPendingBroadcastLocked(int pid) {
16947            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16948            for (BroadcastQueue queue : mBroadcastQueues) {
16949                queue.skipPendingBroadcastLocked(pid);
16950            }
16951    }
16952
16953    // The app just attached; send any pending broadcasts that it should receive
16954    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16955        boolean didSomething = false;
16956        for (BroadcastQueue queue : mBroadcastQueues) {
16957            didSomething |= queue.sendPendingBroadcastsLocked(app);
16958        }
16959        return didSomething;
16960    }
16961
16962    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16963            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16964        enforceNotIsolatedCaller("registerReceiver");
16965        ArrayList<Intent> stickyIntents = null;
16966        ProcessRecord callerApp = null;
16967        int callingUid;
16968        int callingPid;
16969        synchronized(this) {
16970            if (caller != null) {
16971                callerApp = getRecordForAppLocked(caller);
16972                if (callerApp == null) {
16973                    throw new SecurityException(
16974                            "Unable to find app for caller " + caller
16975                            + " (pid=" + Binder.getCallingPid()
16976                            + ") when registering receiver " + receiver);
16977                }
16978                if (callerApp.info.uid != Process.SYSTEM_UID &&
16979                        !callerApp.pkgList.containsKey(callerPackage) &&
16980                        !"android".equals(callerPackage)) {
16981                    throw new SecurityException("Given caller package " + callerPackage
16982                            + " is not running in process " + callerApp);
16983                }
16984                callingUid = callerApp.info.uid;
16985                callingPid = callerApp.pid;
16986            } else {
16987                callerPackage = null;
16988                callingUid = Binder.getCallingUid();
16989                callingPid = Binder.getCallingPid();
16990            }
16991
16992            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16993                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16994
16995            Iterator<String> actions = filter.actionsIterator();
16996            if (actions == null) {
16997                ArrayList<String> noAction = new ArrayList<String>(1);
16998                noAction.add(null);
16999                actions = noAction.iterator();
17000            }
17001
17002            // Collect stickies of users
17003            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17004            while (actions.hasNext()) {
17005                String action = actions.next();
17006                for (int id : userIds) {
17007                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17008                    if (stickies != null) {
17009                        ArrayList<Intent> intents = stickies.get(action);
17010                        if (intents != null) {
17011                            if (stickyIntents == null) {
17012                                stickyIntents = new ArrayList<Intent>();
17013                            }
17014                            stickyIntents.addAll(intents);
17015                        }
17016                    }
17017                }
17018            }
17019        }
17020
17021        ArrayList<Intent> allSticky = null;
17022        if (stickyIntents != null) {
17023            final ContentResolver resolver = mContext.getContentResolver();
17024            // Look for any matching sticky broadcasts...
17025            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17026                Intent intent = stickyIntents.get(i);
17027                // If intent has scheme "content", it will need to acccess
17028                // provider that needs to lock mProviderMap in ActivityThread
17029                // and also it may need to wait application response, so we
17030                // cannot lock ActivityManagerService here.
17031                if (filter.match(resolver, intent, true, TAG) >= 0) {
17032                    if (allSticky == null) {
17033                        allSticky = new ArrayList<Intent>();
17034                    }
17035                    allSticky.add(intent);
17036                }
17037            }
17038        }
17039
17040        // The first sticky in the list is returned directly back to the client.
17041        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17042        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17043        if (receiver == null) {
17044            return sticky;
17045        }
17046
17047        synchronized (this) {
17048            if (callerApp != null && (callerApp.thread == null
17049                    || callerApp.thread.asBinder() != caller.asBinder())) {
17050                // Original caller already died
17051                return null;
17052            }
17053            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17054            if (rl == null) {
17055                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17056                        userId, receiver);
17057                if (rl.app != null) {
17058                    rl.app.receivers.add(rl);
17059                } else {
17060                    try {
17061                        receiver.asBinder().linkToDeath(rl, 0);
17062                    } catch (RemoteException e) {
17063                        return sticky;
17064                    }
17065                    rl.linkedToDeath = true;
17066                }
17067                mRegisteredReceivers.put(receiver.asBinder(), rl);
17068            } else if (rl.uid != callingUid) {
17069                throw new IllegalArgumentException(
17070                        "Receiver requested to register for uid " + callingUid
17071                        + " was previously registered for uid " + rl.uid);
17072            } else if (rl.pid != callingPid) {
17073                throw new IllegalArgumentException(
17074                        "Receiver requested to register for pid " + callingPid
17075                        + " was previously registered for pid " + rl.pid);
17076            } else if (rl.userId != userId) {
17077                throw new IllegalArgumentException(
17078                        "Receiver requested to register for user " + userId
17079                        + " was previously registered for user " + rl.userId);
17080            }
17081            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17082                    permission, callingUid, userId);
17083            rl.add(bf);
17084            if (!bf.debugCheck()) {
17085                Slog.w(TAG, "==> For Dynamic broadcast");
17086            }
17087            mReceiverResolver.addFilter(bf);
17088
17089            // Enqueue broadcasts for all existing stickies that match
17090            // this filter.
17091            if (allSticky != null) {
17092                ArrayList receivers = new ArrayList();
17093                receivers.add(bf);
17094
17095                final int stickyCount = allSticky.size();
17096                for (int i = 0; i < stickyCount; i++) {
17097                    Intent intent = allSticky.get(i);
17098                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17099                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17100                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17101                            null, 0, null, null, false, true, true, -1);
17102                    queue.enqueueParallelBroadcastLocked(r);
17103                    queue.scheduleBroadcastsLocked();
17104                }
17105            }
17106
17107            return sticky;
17108        }
17109    }
17110
17111    public void unregisterReceiver(IIntentReceiver receiver) {
17112        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17113
17114        final long origId = Binder.clearCallingIdentity();
17115        try {
17116            boolean doTrim = false;
17117
17118            synchronized(this) {
17119                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17120                if (rl != null) {
17121                    final BroadcastRecord r = rl.curBroadcast;
17122                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17123                        final boolean doNext = r.queue.finishReceiverLocked(
17124                                r, r.resultCode, r.resultData, r.resultExtras,
17125                                r.resultAbort, false);
17126                        if (doNext) {
17127                            doTrim = true;
17128                            r.queue.processNextBroadcast(false);
17129                        }
17130                    }
17131
17132                    if (rl.app != null) {
17133                        rl.app.receivers.remove(rl);
17134                    }
17135                    removeReceiverLocked(rl);
17136                    if (rl.linkedToDeath) {
17137                        rl.linkedToDeath = false;
17138                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17139                    }
17140                }
17141            }
17142
17143            // If we actually concluded any broadcasts, we might now be able
17144            // to trim the recipients' apps from our working set
17145            if (doTrim) {
17146                trimApplications();
17147                return;
17148            }
17149
17150        } finally {
17151            Binder.restoreCallingIdentity(origId);
17152        }
17153    }
17154
17155    void removeReceiverLocked(ReceiverList rl) {
17156        mRegisteredReceivers.remove(rl.receiver.asBinder());
17157        for (int i = rl.size() - 1; i >= 0; i--) {
17158            mReceiverResolver.removeFilter(rl.get(i));
17159        }
17160    }
17161
17162    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17163        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17164            ProcessRecord r = mLruProcesses.get(i);
17165            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17166                try {
17167                    r.thread.dispatchPackageBroadcast(cmd, packages);
17168                } catch (RemoteException ex) {
17169                }
17170            }
17171        }
17172    }
17173
17174    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17175            int callingUid, int[] users) {
17176        // TODO: come back and remove this assumption to triage all broadcasts
17177        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17178
17179        List<ResolveInfo> receivers = null;
17180        try {
17181            HashSet<ComponentName> singleUserReceivers = null;
17182            boolean scannedFirstReceivers = false;
17183            for (int user : users) {
17184                // Skip users that have Shell restrictions, with exception of always permitted
17185                // Shell broadcasts
17186                if (callingUid == Process.SHELL_UID
17187                        && mUserController.hasUserRestriction(
17188                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17189                        && !isPermittedShellBroadcast(intent)) {
17190                    continue;
17191                }
17192                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17193                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17194                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17195                    // If this is not the system user, we need to check for
17196                    // any receivers that should be filtered out.
17197                    for (int i=0; i<newReceivers.size(); i++) {
17198                        ResolveInfo ri = newReceivers.get(i);
17199                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17200                            newReceivers.remove(i);
17201                            i--;
17202                        }
17203                    }
17204                }
17205                if (newReceivers != null && newReceivers.size() == 0) {
17206                    newReceivers = null;
17207                }
17208                if (receivers == null) {
17209                    receivers = newReceivers;
17210                } else if (newReceivers != null) {
17211                    // We need to concatenate the additional receivers
17212                    // found with what we have do far.  This would be easy,
17213                    // but we also need to de-dup any receivers that are
17214                    // singleUser.
17215                    if (!scannedFirstReceivers) {
17216                        // Collect any single user receivers we had already retrieved.
17217                        scannedFirstReceivers = true;
17218                        for (int i=0; i<receivers.size(); i++) {
17219                            ResolveInfo ri = receivers.get(i);
17220                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17221                                ComponentName cn = new ComponentName(
17222                                        ri.activityInfo.packageName, ri.activityInfo.name);
17223                                if (singleUserReceivers == null) {
17224                                    singleUserReceivers = new HashSet<ComponentName>();
17225                                }
17226                                singleUserReceivers.add(cn);
17227                            }
17228                        }
17229                    }
17230                    // Add the new results to the existing results, tracking
17231                    // and de-dupping single user receivers.
17232                    for (int i=0; i<newReceivers.size(); i++) {
17233                        ResolveInfo ri = newReceivers.get(i);
17234                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17235                            ComponentName cn = new ComponentName(
17236                                    ri.activityInfo.packageName, ri.activityInfo.name);
17237                            if (singleUserReceivers == null) {
17238                                singleUserReceivers = new HashSet<ComponentName>();
17239                            }
17240                            if (!singleUserReceivers.contains(cn)) {
17241                                singleUserReceivers.add(cn);
17242                                receivers.add(ri);
17243                            }
17244                        } else {
17245                            receivers.add(ri);
17246                        }
17247                    }
17248                }
17249            }
17250        } catch (RemoteException ex) {
17251            // pm is in same process, this will never happen.
17252        }
17253        return receivers;
17254    }
17255
17256    private boolean isPermittedShellBroadcast(Intent intent) {
17257        // remote bugreport should always be allowed to be taken
17258        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17259    }
17260
17261    final int broadcastIntentLocked(ProcessRecord callerApp,
17262            String callerPackage, Intent intent, String resolvedType,
17263            IIntentReceiver resultTo, int resultCode, String resultData,
17264            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17265            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17266        intent = new Intent(intent);
17267
17268        // By default broadcasts do not go to stopped apps.
17269        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17270
17271        // If we have not finished booting, don't allow this to launch new processes.
17272        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17273            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17274        }
17275
17276        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17277                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17278                + " ordered=" + ordered + " userid=" + userId);
17279        if ((resultTo != null) && !ordered) {
17280            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17281        }
17282
17283        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17284                ALLOW_NON_FULL, "broadcast", callerPackage);
17285
17286        // Make sure that the user who is receiving this broadcast is running.
17287        // If not, we will just skip it. Make an exception for shutdown broadcasts
17288        // and upgrade steps.
17289
17290        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17291            if ((callingUid != Process.SYSTEM_UID
17292                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17293                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17294                Slog.w(TAG, "Skipping broadcast of " + intent
17295                        + ": user " + userId + " is stopped");
17296                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17297            }
17298        }
17299
17300        BroadcastOptions brOptions = null;
17301        if (bOptions != null) {
17302            brOptions = new BroadcastOptions(bOptions);
17303            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17304                // See if the caller is allowed to do this.  Note we are checking against
17305                // the actual real caller (not whoever provided the operation as say a
17306                // PendingIntent), because that who is actually supplied the arguments.
17307                if (checkComponentPermission(
17308                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17309                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17310                        != PackageManager.PERMISSION_GRANTED) {
17311                    String msg = "Permission Denial: " + intent.getAction()
17312                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17313                            + ", uid=" + callingUid + ")"
17314                            + " requires "
17315                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17316                    Slog.w(TAG, msg);
17317                    throw new SecurityException(msg);
17318                }
17319            }
17320        }
17321
17322        // Verify that protected broadcasts are only being sent by system code,
17323        // and that system code is only sending protected broadcasts.
17324        final String action = intent.getAction();
17325        final boolean isProtectedBroadcast;
17326        try {
17327            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17328        } catch (RemoteException e) {
17329            Slog.w(TAG, "Remote exception", e);
17330            return ActivityManager.BROADCAST_SUCCESS;
17331        }
17332
17333        final boolean isCallerSystem;
17334        switch (UserHandle.getAppId(callingUid)) {
17335            case Process.ROOT_UID:
17336            case Process.SYSTEM_UID:
17337            case Process.PHONE_UID:
17338            case Process.BLUETOOTH_UID:
17339            case Process.NFC_UID:
17340                isCallerSystem = true;
17341                break;
17342            default:
17343                isCallerSystem = (callerApp != null) && callerApp.persistent;
17344                break;
17345        }
17346
17347        if (isCallerSystem) {
17348            if (isProtectedBroadcast
17349                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17350                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17351                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17352                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17353                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17354                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17355                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17356                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17357                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)) {
17358                // Broadcast is either protected, or it's a public action that
17359                // we've relaxed, so it's fine for system internals to send.
17360            } else {
17361                // The vast majority of broadcasts sent from system internals
17362                // should be protected to avoid security holes, so yell loudly
17363                // to ensure we examine these cases.
17364                Log.wtf(TAG, "Sending non-protected broadcast " + action
17365                        + " from system", new Throwable());
17366            }
17367
17368        } else {
17369            if (isProtectedBroadcast) {
17370                String msg = "Permission Denial: not allowed to send broadcast "
17371                        + action + " from pid="
17372                        + callingPid + ", uid=" + callingUid;
17373                Slog.w(TAG, msg);
17374                throw new SecurityException(msg);
17375
17376            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17377                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17378                // Special case for compatibility: we don't want apps to send this,
17379                // but historically it has not been protected and apps may be using it
17380                // to poke their own app widget.  So, instead of making it protected,
17381                // just limit it to the caller.
17382                if (callerPackage == null) {
17383                    String msg = "Permission Denial: not allowed to send broadcast "
17384                            + action + " from unknown caller.";
17385                    Slog.w(TAG, msg);
17386                    throw new SecurityException(msg);
17387                } else if (intent.getComponent() != null) {
17388                    // They are good enough to send to an explicit component...  verify
17389                    // it is being sent to the calling app.
17390                    if (!intent.getComponent().getPackageName().equals(
17391                            callerPackage)) {
17392                        String msg = "Permission Denial: not allowed to send broadcast "
17393                                + action + " to "
17394                                + intent.getComponent().getPackageName() + " from "
17395                                + callerPackage;
17396                        Slog.w(TAG, msg);
17397                        throw new SecurityException(msg);
17398                    }
17399                } else {
17400                    // Limit broadcast to their own package.
17401                    intent.setPackage(callerPackage);
17402                }
17403            }
17404        }
17405
17406        if (action != null) {
17407            switch (action) {
17408                case Intent.ACTION_UID_REMOVED:
17409                case Intent.ACTION_PACKAGE_REMOVED:
17410                case Intent.ACTION_PACKAGE_CHANGED:
17411                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17412                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17413                case Intent.ACTION_PACKAGES_SUSPENDED:
17414                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17415                    // Handle special intents: if this broadcast is from the package
17416                    // manager about a package being removed, we need to remove all of
17417                    // its activities from the history stack.
17418                    if (checkComponentPermission(
17419                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17420                            callingPid, callingUid, -1, true)
17421                            != PackageManager.PERMISSION_GRANTED) {
17422                        String msg = "Permission Denial: " + intent.getAction()
17423                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17424                                + ", uid=" + callingUid + ")"
17425                                + " requires "
17426                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17427                        Slog.w(TAG, msg);
17428                        throw new SecurityException(msg);
17429                    }
17430                    switch (action) {
17431                        case Intent.ACTION_UID_REMOVED:
17432                            final Bundle intentExtras = intent.getExtras();
17433                            final int uid = intentExtras != null
17434                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17435                            if (uid >= 0) {
17436                                mBatteryStatsService.removeUid(uid);
17437                                mAppOpsService.uidRemoved(uid);
17438                            }
17439                            break;
17440                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17441                            // If resources are unavailable just force stop all those packages
17442                            // and flush the attribute cache as well.
17443                            String list[] =
17444                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17445                            if (list != null && list.length > 0) {
17446                                for (int i = 0; i < list.length; i++) {
17447                                    forceStopPackageLocked(list[i], -1, false, true, true,
17448                                            false, false, userId, "storage unmount");
17449                                }
17450                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17451                                sendPackageBroadcastLocked(
17452                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17453                                        userId);
17454                            }
17455                            break;
17456                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17457                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17458                            break;
17459                        case Intent.ACTION_PACKAGE_REMOVED:
17460                        case Intent.ACTION_PACKAGE_CHANGED:
17461                            Uri data = intent.getData();
17462                            String ssp;
17463                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17464                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17465                                final boolean replacing =
17466                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17467                                final boolean killProcess =
17468                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17469                                final boolean fullUninstall = removed && !replacing;
17470                                if (killProcess) {
17471                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17472                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17473                                            false, true, true, false, fullUninstall, userId,
17474                                            removed ? "pkg removed" : "pkg changed");
17475                                }
17476                                if (removed) {
17477                                    final int cmd = killProcess
17478                                            ? IApplicationThread.PACKAGE_REMOVED
17479                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17480                                    sendPackageBroadcastLocked(cmd,
17481                                            new String[] {ssp}, userId);
17482                                    if (fullUninstall) {
17483                                        mAppOpsService.packageRemoved(
17484                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17485
17486                                        // Remove all permissions granted from/to this package
17487                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17488
17489                                        removeTasksByPackageNameLocked(ssp, userId);
17490                                        mBatteryStatsService.notePackageUninstalled(ssp);
17491                                    }
17492                                } else {
17493                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17494                                            intent.getStringArrayExtra(
17495                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17496                                }
17497                            }
17498                            break;
17499                        case Intent.ACTION_PACKAGES_SUSPENDED:
17500                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17501                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17502                                    intent.getAction());
17503                            final String[] packageNames = intent.getStringArrayExtra(
17504                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17505                            final int userHandle = intent.getIntExtra(
17506                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17507
17508                            synchronized(ActivityManagerService.this) {
17509                                mRecentTasks.onPackagesSuspendedChanged(
17510                                        packageNames, suspended, userHandle);
17511                            }
17512                            break;
17513                    }
17514                    break;
17515                case Intent.ACTION_PACKAGE_REPLACED:
17516                {
17517                    final Uri data = intent.getData();
17518                    final String ssp;
17519                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17520                        final ApplicationInfo aInfo =
17521                                getPackageManagerInternalLocked().getApplicationInfo(
17522                                        ssp,
17523                                        userId);
17524                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17525                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17526                                new String[] {ssp}, userId);
17527                    }
17528                    break;
17529                }
17530                case Intent.ACTION_PACKAGE_ADDED:
17531                {
17532                    // Special case for adding a package: by default turn on compatibility mode.
17533                    Uri data = intent.getData();
17534                    String ssp;
17535                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17536                        final boolean replacing =
17537                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17538                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17539
17540                        try {
17541                            ApplicationInfo ai = AppGlobals.getPackageManager().
17542                                    getApplicationInfo(ssp, 0, 0);
17543                            mBatteryStatsService.notePackageInstalled(ssp,
17544                                    ai != null ? ai.versionCode : 0);
17545                        } catch (RemoteException e) {
17546                        }
17547                    }
17548                    break;
17549                }
17550                case Intent.ACTION_TIMEZONE_CHANGED:
17551                    // If this is the time zone changed action, queue up a message that will reset
17552                    // the timezone of all currently running processes. This message will get
17553                    // queued up before the broadcast happens.
17554                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17555                    break;
17556                case Intent.ACTION_TIME_CHANGED:
17557                    // If the user set the time, let all running processes know.
17558                    final int is24Hour =
17559                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17560                                    : 0;
17561                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17562                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17563                    synchronized (stats) {
17564                        stats.noteCurrentTimeChangedLocked();
17565                    }
17566                    break;
17567                case Intent.ACTION_CLEAR_DNS_CACHE:
17568                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17569                    break;
17570                case Proxy.PROXY_CHANGE_ACTION:
17571                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17572                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17573                    break;
17574                case android.hardware.Camera.ACTION_NEW_PICTURE:
17575                case android.hardware.Camera.ACTION_NEW_VIDEO:
17576                    // These broadcasts are no longer allowed by the system, since they can
17577                    // cause significant thrashing at a crictical point (using the camera).
17578                    // Apps should use JobScehduler to monitor for media provider changes.
17579                    Slog.w(TAG, action + " no longer allowed; dropping from "
17580                            + UserHandle.formatUid(callingUid));
17581                    // Lie; we don't want to crash the app.
17582                    return ActivityManager.BROADCAST_SUCCESS;
17583            }
17584        }
17585
17586        // Add to the sticky list if requested.
17587        if (sticky) {
17588            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17589                    callingPid, callingUid)
17590                    != PackageManager.PERMISSION_GRANTED) {
17591                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17592                        + callingPid + ", uid=" + callingUid
17593                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17594                Slog.w(TAG, msg);
17595                throw new SecurityException(msg);
17596            }
17597            if (requiredPermissions != null && requiredPermissions.length > 0) {
17598                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17599                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17600                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17601            }
17602            if (intent.getComponent() != null) {
17603                throw new SecurityException(
17604                        "Sticky broadcasts can't target a specific component");
17605            }
17606            // We use userId directly here, since the "all" target is maintained
17607            // as a separate set of sticky broadcasts.
17608            if (userId != UserHandle.USER_ALL) {
17609                // But first, if this is not a broadcast to all users, then
17610                // make sure it doesn't conflict with an existing broadcast to
17611                // all users.
17612                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17613                        UserHandle.USER_ALL);
17614                if (stickies != null) {
17615                    ArrayList<Intent> list = stickies.get(intent.getAction());
17616                    if (list != null) {
17617                        int N = list.size();
17618                        int i;
17619                        for (i=0; i<N; i++) {
17620                            if (intent.filterEquals(list.get(i))) {
17621                                throw new IllegalArgumentException(
17622                                        "Sticky broadcast " + intent + " for user "
17623                                        + userId + " conflicts with existing global broadcast");
17624                            }
17625                        }
17626                    }
17627                }
17628            }
17629            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17630            if (stickies == null) {
17631                stickies = new ArrayMap<>();
17632                mStickyBroadcasts.put(userId, stickies);
17633            }
17634            ArrayList<Intent> list = stickies.get(intent.getAction());
17635            if (list == null) {
17636                list = new ArrayList<>();
17637                stickies.put(intent.getAction(), list);
17638            }
17639            final int stickiesCount = list.size();
17640            int i;
17641            for (i = 0; i < stickiesCount; i++) {
17642                if (intent.filterEquals(list.get(i))) {
17643                    // This sticky already exists, replace it.
17644                    list.set(i, new Intent(intent));
17645                    break;
17646                }
17647            }
17648            if (i >= stickiesCount) {
17649                list.add(new Intent(intent));
17650            }
17651        }
17652
17653        int[] users;
17654        if (userId == UserHandle.USER_ALL) {
17655            // Caller wants broadcast to go to all started users.
17656            users = mUserController.getStartedUserArrayLocked();
17657        } else {
17658            // Caller wants broadcast to go to one specific user.
17659            users = new int[] {userId};
17660        }
17661
17662        // Figure out who all will receive this broadcast.
17663        List receivers = null;
17664        List<BroadcastFilter> registeredReceivers = null;
17665        // Need to resolve the intent to interested receivers...
17666        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17667                 == 0) {
17668            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17669        }
17670        if (intent.getComponent() == null) {
17671            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17672                // Query one target user at a time, excluding shell-restricted users
17673                for (int i = 0; i < users.length; i++) {
17674                    if (mUserController.hasUserRestriction(
17675                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17676                        continue;
17677                    }
17678                    List<BroadcastFilter> registeredReceiversForUser =
17679                            mReceiverResolver.queryIntent(intent,
17680                                    resolvedType, false, users[i]);
17681                    if (registeredReceivers == null) {
17682                        registeredReceivers = registeredReceiversForUser;
17683                    } else if (registeredReceiversForUser != null) {
17684                        registeredReceivers.addAll(registeredReceiversForUser);
17685                    }
17686                }
17687            } else {
17688                registeredReceivers = mReceiverResolver.queryIntent(intent,
17689                        resolvedType, false, userId);
17690            }
17691        }
17692
17693        final boolean replacePending =
17694                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17695
17696        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17697                + " replacePending=" + replacePending);
17698
17699        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17700        if (!ordered && NR > 0) {
17701            // If we are not serializing this broadcast, then send the
17702            // registered receivers separately so they don't wait for the
17703            // components to be launched.
17704            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17705            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17706                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17707                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17708                    resultExtras, ordered, sticky, false, userId);
17709            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17710            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17711            if (!replaced) {
17712                queue.enqueueParallelBroadcastLocked(r);
17713                queue.scheduleBroadcastsLocked();
17714            }
17715            registeredReceivers = null;
17716            NR = 0;
17717        }
17718
17719        // Merge into one list.
17720        int ir = 0;
17721        if (receivers != null) {
17722            // A special case for PACKAGE_ADDED: do not allow the package
17723            // being added to see this broadcast.  This prevents them from
17724            // using this as a back door to get run as soon as they are
17725            // installed.  Maybe in the future we want to have a special install
17726            // broadcast or such for apps, but we'd like to deliberately make
17727            // this decision.
17728            String skipPackages[] = null;
17729            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17730                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17731                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17732                Uri data = intent.getData();
17733                if (data != null) {
17734                    String pkgName = data.getSchemeSpecificPart();
17735                    if (pkgName != null) {
17736                        skipPackages = new String[] { pkgName };
17737                    }
17738                }
17739            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17740                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17741            }
17742            if (skipPackages != null && (skipPackages.length > 0)) {
17743                for (String skipPackage : skipPackages) {
17744                    if (skipPackage != null) {
17745                        int NT = receivers.size();
17746                        for (int it=0; it<NT; it++) {
17747                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17748                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17749                                receivers.remove(it);
17750                                it--;
17751                                NT--;
17752                            }
17753                        }
17754                    }
17755                }
17756            }
17757
17758            int NT = receivers != null ? receivers.size() : 0;
17759            int it = 0;
17760            ResolveInfo curt = null;
17761            BroadcastFilter curr = null;
17762            while (it < NT && ir < NR) {
17763                if (curt == null) {
17764                    curt = (ResolveInfo)receivers.get(it);
17765                }
17766                if (curr == null) {
17767                    curr = registeredReceivers.get(ir);
17768                }
17769                if (curr.getPriority() >= curt.priority) {
17770                    // Insert this broadcast record into the final list.
17771                    receivers.add(it, curr);
17772                    ir++;
17773                    curr = null;
17774                    it++;
17775                    NT++;
17776                } else {
17777                    // Skip to the next ResolveInfo in the final list.
17778                    it++;
17779                    curt = null;
17780                }
17781            }
17782        }
17783        while (ir < NR) {
17784            if (receivers == null) {
17785                receivers = new ArrayList();
17786            }
17787            receivers.add(registeredReceivers.get(ir));
17788            ir++;
17789        }
17790
17791        if ((receivers != null && receivers.size() > 0)
17792                || resultTo != null) {
17793            BroadcastQueue queue = broadcastQueueForIntent(intent);
17794            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17795                    callerPackage, callingPid, callingUid, resolvedType,
17796                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17797                    resultData, resultExtras, ordered, sticky, false, userId);
17798
17799            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17800                    + ": prev had " + queue.mOrderedBroadcasts.size());
17801            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17802                    "Enqueueing broadcast " + r.intent.getAction());
17803
17804            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17805            if (!replaced) {
17806                queue.enqueueOrderedBroadcastLocked(r);
17807                queue.scheduleBroadcastsLocked();
17808            }
17809        }
17810
17811        return ActivityManager.BROADCAST_SUCCESS;
17812    }
17813
17814    final Intent verifyBroadcastLocked(Intent intent) {
17815        // Refuse possible leaked file descriptors
17816        if (intent != null && intent.hasFileDescriptors() == true) {
17817            throw new IllegalArgumentException("File descriptors passed in Intent");
17818        }
17819
17820        int flags = intent.getFlags();
17821
17822        if (!mProcessesReady) {
17823            // if the caller really truly claims to know what they're doing, go
17824            // ahead and allow the broadcast without launching any receivers
17825            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17826                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17827            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17828                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17829                        + " before boot completion");
17830                throw new IllegalStateException("Cannot broadcast before boot completed");
17831            }
17832        }
17833
17834        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17835            throw new IllegalArgumentException(
17836                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17837        }
17838
17839        return intent;
17840    }
17841
17842    public final int broadcastIntent(IApplicationThread caller,
17843            Intent intent, String resolvedType, IIntentReceiver resultTo,
17844            int resultCode, String resultData, Bundle resultExtras,
17845            String[] requiredPermissions, int appOp, Bundle bOptions,
17846            boolean serialized, boolean sticky, int userId) {
17847        enforceNotIsolatedCaller("broadcastIntent");
17848        synchronized(this) {
17849            intent = verifyBroadcastLocked(intent);
17850
17851            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17852            final int callingPid = Binder.getCallingPid();
17853            final int callingUid = Binder.getCallingUid();
17854            final long origId = Binder.clearCallingIdentity();
17855            int res = broadcastIntentLocked(callerApp,
17856                    callerApp != null ? callerApp.info.packageName : null,
17857                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17858                    requiredPermissions, appOp, bOptions, serialized, sticky,
17859                    callingPid, callingUid, userId);
17860            Binder.restoreCallingIdentity(origId);
17861            return res;
17862        }
17863    }
17864
17865
17866    int broadcastIntentInPackage(String packageName, int uid,
17867            Intent intent, String resolvedType, IIntentReceiver resultTo,
17868            int resultCode, String resultData, Bundle resultExtras,
17869            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17870            int userId) {
17871        synchronized(this) {
17872            intent = verifyBroadcastLocked(intent);
17873
17874            final long origId = Binder.clearCallingIdentity();
17875            String[] requiredPermissions = requiredPermission == null ? null
17876                    : new String[] {requiredPermission};
17877            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17878                    resultTo, resultCode, resultData, resultExtras,
17879                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17880                    sticky, -1, uid, userId);
17881            Binder.restoreCallingIdentity(origId);
17882            return res;
17883        }
17884    }
17885
17886    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17887        // Refuse possible leaked file descriptors
17888        if (intent != null && intent.hasFileDescriptors() == true) {
17889            throw new IllegalArgumentException("File descriptors passed in Intent");
17890        }
17891
17892        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17893                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17894
17895        synchronized(this) {
17896            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17897                    != PackageManager.PERMISSION_GRANTED) {
17898                String msg = "Permission Denial: unbroadcastIntent() from pid="
17899                        + Binder.getCallingPid()
17900                        + ", uid=" + Binder.getCallingUid()
17901                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17902                Slog.w(TAG, msg);
17903                throw new SecurityException(msg);
17904            }
17905            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17906            if (stickies != null) {
17907                ArrayList<Intent> list = stickies.get(intent.getAction());
17908                if (list != null) {
17909                    int N = list.size();
17910                    int i;
17911                    for (i=0; i<N; i++) {
17912                        if (intent.filterEquals(list.get(i))) {
17913                            list.remove(i);
17914                            break;
17915                        }
17916                    }
17917                    if (list.size() <= 0) {
17918                        stickies.remove(intent.getAction());
17919                    }
17920                }
17921                if (stickies.size() <= 0) {
17922                    mStickyBroadcasts.remove(userId);
17923                }
17924            }
17925        }
17926    }
17927
17928    void backgroundServicesFinishedLocked(int userId) {
17929        for (BroadcastQueue queue : mBroadcastQueues) {
17930            queue.backgroundServicesFinishedLocked(userId);
17931        }
17932    }
17933
17934    public void finishReceiver(IBinder who, int resultCode, String resultData,
17935            Bundle resultExtras, boolean resultAbort, int flags) {
17936        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17937
17938        // Refuse possible leaked file descriptors
17939        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17940            throw new IllegalArgumentException("File descriptors passed in Bundle");
17941        }
17942
17943        final long origId = Binder.clearCallingIdentity();
17944        try {
17945            boolean doNext = false;
17946            BroadcastRecord r;
17947
17948            synchronized(this) {
17949                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17950                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17951                r = queue.getMatchingOrderedReceiver(who);
17952                if (r != null) {
17953                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17954                        resultData, resultExtras, resultAbort, true);
17955                }
17956            }
17957
17958            if (doNext) {
17959                r.queue.processNextBroadcast(false);
17960            }
17961            trimApplications();
17962        } finally {
17963            Binder.restoreCallingIdentity(origId);
17964        }
17965    }
17966
17967    // =========================================================
17968    // INSTRUMENTATION
17969    // =========================================================
17970
17971    public boolean startInstrumentation(ComponentName className,
17972            String profileFile, int flags, Bundle arguments,
17973            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17974            int userId, String abiOverride) {
17975        enforceNotIsolatedCaller("startInstrumentation");
17976        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17977                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17978        // Refuse possible leaked file descriptors
17979        if (arguments != null && arguments.hasFileDescriptors()) {
17980            throw new IllegalArgumentException("File descriptors passed in Bundle");
17981        }
17982
17983        synchronized(this) {
17984            InstrumentationInfo ii = null;
17985            ApplicationInfo ai = null;
17986            try {
17987                ii = mContext.getPackageManager().getInstrumentationInfo(
17988                    className, STOCK_PM_FLAGS);
17989                ai = AppGlobals.getPackageManager().getApplicationInfo(
17990                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17991            } catch (PackageManager.NameNotFoundException e) {
17992            } catch (RemoteException e) {
17993            }
17994            if (ii == null) {
17995                reportStartInstrumentationFailureLocked(watcher, className,
17996                        "Unable to find instrumentation info for: " + className);
17997                return false;
17998            }
17999            if (ai == null) {
18000                reportStartInstrumentationFailureLocked(watcher, className,
18001                        "Unable to find instrumentation target package: " + ii.targetPackage);
18002                return false;
18003            }
18004            if (!ai.hasCode()) {
18005                reportStartInstrumentationFailureLocked(watcher, className,
18006                        "Instrumentation target has no code: " + ii.targetPackage);
18007                return false;
18008            }
18009
18010            int match = mContext.getPackageManager().checkSignatures(
18011                    ii.targetPackage, ii.packageName);
18012            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18013                String msg = "Permission Denial: starting instrumentation "
18014                        + className + " from pid="
18015                        + Binder.getCallingPid()
18016                        + ", uid=" + Binder.getCallingPid()
18017                        + " not allowed because package " + ii.packageName
18018                        + " does not have a signature matching the target "
18019                        + ii.targetPackage;
18020                reportStartInstrumentationFailureLocked(watcher, className, msg);
18021                throw new SecurityException(msg);
18022            }
18023
18024            final long origId = Binder.clearCallingIdentity();
18025            // Instrumentation can kill and relaunch even persistent processes
18026            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18027                    "start instr");
18028            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18029            app.instrumentationClass = className;
18030            app.instrumentationInfo = ai;
18031            app.instrumentationProfileFile = profileFile;
18032            app.instrumentationArguments = arguments;
18033            app.instrumentationWatcher = watcher;
18034            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18035            app.instrumentationResultClass = className;
18036            Binder.restoreCallingIdentity(origId);
18037        }
18038
18039        return true;
18040    }
18041
18042    /**
18043     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18044     * error to the logs, but if somebody is watching, send the report there too.  This enables
18045     * the "am" command to report errors with more information.
18046     *
18047     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18048     * @param cn The component name of the instrumentation.
18049     * @param report The error report.
18050     */
18051    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18052            ComponentName cn, String report) {
18053        Slog.w(TAG, report);
18054        if (watcher != null) {
18055            Bundle results = new Bundle();
18056            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18057            results.putString("Error", report);
18058            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18059        }
18060    }
18061
18062    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18063        if (app.instrumentationWatcher != null) {
18064            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18065                    app.instrumentationClass, resultCode, results);
18066        }
18067
18068        // Can't call out of the system process with a lock held, so post a message.
18069        if (app.instrumentationUiAutomationConnection != null) {
18070            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18071                    app.instrumentationUiAutomationConnection).sendToTarget();
18072        }
18073
18074        app.instrumentationWatcher = null;
18075        app.instrumentationUiAutomationConnection = null;
18076        app.instrumentationClass = null;
18077        app.instrumentationInfo = null;
18078        app.instrumentationProfileFile = null;
18079        app.instrumentationArguments = null;
18080
18081        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18082                "finished inst");
18083    }
18084
18085    public void finishInstrumentation(IApplicationThread target,
18086            int resultCode, Bundle results) {
18087        int userId = UserHandle.getCallingUserId();
18088        // Refuse possible leaked file descriptors
18089        if (results != null && results.hasFileDescriptors()) {
18090            throw new IllegalArgumentException("File descriptors passed in Intent");
18091        }
18092
18093        synchronized(this) {
18094            ProcessRecord app = getRecordForAppLocked(target);
18095            if (app == null) {
18096                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18097                return;
18098            }
18099            final long origId = Binder.clearCallingIdentity();
18100            finishInstrumentationLocked(app, resultCode, results);
18101            Binder.restoreCallingIdentity(origId);
18102        }
18103    }
18104
18105    // =========================================================
18106    // CONFIGURATION
18107    // =========================================================
18108
18109    public ConfigurationInfo getDeviceConfigurationInfo() {
18110        ConfigurationInfo config = new ConfigurationInfo();
18111        synchronized (this) {
18112            config.reqTouchScreen = mConfiguration.touchscreen;
18113            config.reqKeyboardType = mConfiguration.keyboard;
18114            config.reqNavigation = mConfiguration.navigation;
18115            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18116                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18117                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18118            }
18119            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18120                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18121                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18122            }
18123            config.reqGlEsVersion = GL_ES_VERSION;
18124        }
18125        return config;
18126    }
18127
18128    ActivityStack getFocusedStack() {
18129        return mStackSupervisor.getFocusedStack();
18130    }
18131
18132    @Override
18133    public int getFocusedStackId() throws RemoteException {
18134        ActivityStack focusedStack = getFocusedStack();
18135        if (focusedStack != null) {
18136            return focusedStack.getStackId();
18137        }
18138        return -1;
18139    }
18140
18141    public Configuration getConfiguration() {
18142        Configuration ci;
18143        synchronized(this) {
18144            ci = new Configuration(mConfiguration);
18145            ci.userSetLocale = false;
18146        }
18147        return ci;
18148    }
18149
18150    @Override
18151    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18152        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18153        synchronized (this) {
18154            mSuppressResizeConfigChanges = suppress;
18155        }
18156    }
18157
18158    @Override
18159    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18160        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18161        if (fromStackId == HOME_STACK_ID) {
18162            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18163        }
18164        synchronized (this) {
18165            final long origId = Binder.clearCallingIdentity();
18166            try {
18167                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18168            } finally {
18169                Binder.restoreCallingIdentity(origId);
18170            }
18171        }
18172    }
18173
18174    @Override
18175    public void updatePersistentConfiguration(Configuration values) {
18176        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18177                "updateConfiguration()");
18178        enforceWriteSettingsPermission("updateConfiguration()");
18179        if (values == null) {
18180            throw new NullPointerException("Configuration must not be null");
18181        }
18182
18183        int userId = UserHandle.getCallingUserId();
18184
18185        synchronized(this) {
18186            final long origId = Binder.clearCallingIdentity();
18187            updateConfigurationLocked(values, null, false, true, userId);
18188            Binder.restoreCallingIdentity(origId);
18189        }
18190    }
18191
18192    private void updateFontScaleIfNeeded() {
18193        final int currentUserId;
18194        synchronized(this) {
18195            currentUserId = mUserController.getCurrentUserIdLocked();
18196        }
18197        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18198                FONT_SCALE, 1.0f, currentUserId);
18199        if (mConfiguration.fontScale != scaleFactor) {
18200            final Configuration configuration = mWindowManager.computeNewConfiguration();
18201            configuration.fontScale = scaleFactor;
18202            updatePersistentConfiguration(configuration);
18203        }
18204    }
18205
18206    private void enforceWriteSettingsPermission(String func) {
18207        int uid = Binder.getCallingUid();
18208        if (uid == Process.ROOT_UID) {
18209            return;
18210        }
18211
18212        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18213                Settings.getPackageNameForUid(mContext, uid), false)) {
18214            return;
18215        }
18216
18217        String msg = "Permission Denial: " + func + " from pid="
18218                + Binder.getCallingPid()
18219                + ", uid=" + uid
18220                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18221        Slog.w(TAG, msg);
18222        throw new SecurityException(msg);
18223    }
18224
18225    public void updateConfiguration(Configuration values) {
18226        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18227                "updateConfiguration()");
18228
18229        synchronized(this) {
18230            if (values == null && mWindowManager != null) {
18231                // sentinel: fetch the current configuration from the window manager
18232                values = mWindowManager.computeNewConfiguration();
18233            }
18234
18235            if (mWindowManager != null) {
18236                mProcessList.applyDisplaySize(mWindowManager);
18237            }
18238
18239            final long origId = Binder.clearCallingIdentity();
18240            if (values != null) {
18241                Settings.System.clearConfiguration(values);
18242            }
18243            updateConfigurationLocked(values, null, false);
18244            Binder.restoreCallingIdentity(origId);
18245        }
18246    }
18247
18248    void updateUserConfigurationLocked() {
18249        Configuration configuration = new Configuration(mConfiguration);
18250        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18251                mUserController.getCurrentUserIdLocked());
18252        updateConfigurationLocked(configuration, null, false);
18253    }
18254
18255    boolean updateConfigurationLocked(Configuration values,
18256            ActivityRecord starting, boolean initLocale) {
18257        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18258        return updateConfigurationLocked(values, starting, initLocale, false,
18259                UserHandle.USER_NULL);
18260    }
18261
18262    // To cache the list of supported system locales
18263    private String[] mSupportedSystemLocales = null;
18264
18265    /**
18266     * Do either or both things: (1) change the current configuration, and (2)
18267     * make sure the given activity is running with the (now) current
18268     * configuration.  Returns true if the activity has been left running, or
18269     * false if <var>starting</var> is being destroyed to match the new
18270     * configuration.
18271     *
18272     * @param userId is only used when persistent parameter is set to true to persist configuration
18273     *               for that particular user
18274     */
18275    private boolean updateConfigurationLocked(Configuration values,
18276            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18277        int changes = 0;
18278
18279        if (mWindowManager != null) {
18280            mWindowManager.deferSurfaceLayout();
18281        }
18282        if (values != null) {
18283            Configuration newConfig = new Configuration(mConfiguration);
18284            changes = newConfig.updateFrom(values);
18285            if (changes != 0) {
18286                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18287                        "Updating configuration to: " + values);
18288
18289                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18290
18291                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18292                    final Locale locale;
18293                    if (values.getLocales().size() == 1) {
18294                        // This is an optimization to avoid the JNI call when the result of
18295                        // getFirstMatch() does not depend on the supported locales.
18296                        locale = values.getLocales().get(0);
18297                    } else {
18298                        if (mSupportedSystemLocales == null) {
18299                            mSupportedSystemLocales =
18300                                    Resources.getSystem().getAssets().getLocales();
18301                        }
18302                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18303                    }
18304                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18305                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18306                            locale));
18307                }
18308
18309                mConfigurationSeq++;
18310                if (mConfigurationSeq <= 0) {
18311                    mConfigurationSeq = 1;
18312                }
18313                newConfig.seq = mConfigurationSeq;
18314                mConfiguration = newConfig;
18315                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18316                mUsageStatsService.reportConfigurationChange(newConfig,
18317                        mUserController.getCurrentUserIdLocked());
18318                //mUsageStatsService.noteStartConfig(newConfig);
18319
18320                final Configuration configCopy = new Configuration(mConfiguration);
18321
18322                // TODO: If our config changes, should we auto dismiss any currently
18323                // showing dialogs?
18324                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18325
18326                AttributeCache ac = AttributeCache.instance();
18327                if (ac != null) {
18328                    ac.updateConfiguration(configCopy);
18329                }
18330
18331                // Make sure all resources in our process are updated
18332                // right now, so that anyone who is going to retrieve
18333                // resource values after we return will be sure to get
18334                // the new ones.  This is especially important during
18335                // boot, where the first config change needs to guarantee
18336                // all resources have that config before following boot
18337                // code is executed.
18338                mSystemThread.applyConfigurationToResources(configCopy);
18339
18340                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18341                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18342                    msg.obj = new Configuration(configCopy);
18343                    msg.arg1 = userId;
18344                    mHandler.sendMessage(msg);
18345                }
18346
18347                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18348                if (isDensityChange) {
18349                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18350                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18351                }
18352
18353                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18354                    ProcessRecord app = mLruProcesses.get(i);
18355                    try {
18356                        if (app.thread != null) {
18357                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18358                                    + app.processName + " new config " + mConfiguration);
18359                            app.thread.scheduleConfigurationChanged(configCopy);
18360                        }
18361                    } catch (Exception e) {
18362                    }
18363                }
18364                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18365                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18366                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18367                        | Intent.FLAG_RECEIVER_FOREGROUND);
18368                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18369                        null, AppOpsManager.OP_NONE, null, false, false,
18370                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18371                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18372                    // Tell the shortcut manager that the system locale changed.  It needs to know
18373                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18374                    // we "push" from here, rather than having the service listen to the broadcast.
18375                    final ShortcutServiceInternal shortcutService =
18376                            LocalServices.getService(ShortcutServiceInternal.class);
18377                    if (shortcutService != null) {
18378                        shortcutService.onSystemLocaleChangedNoLock();
18379                    }
18380
18381                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18382                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18383                    if (!mProcessesReady) {
18384                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18385                    }
18386                    broadcastIntentLocked(null, null, intent,
18387                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18388                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18389                }
18390            }
18391            // Update the configuration with WM first and check if any of the stacks need to be
18392            // resized due to the configuration change. If so, resize the stacks now and do any
18393            // relaunches if necessary. This way we don't need to relaunch again below in
18394            // ensureActivityConfigurationLocked().
18395            if (mWindowManager != null) {
18396                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18397                if (resizedStacks != null) {
18398                    for (int stackId : resizedStacks) {
18399                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18400                        mStackSupervisor.resizeStackLocked(
18401                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18402                    }
18403                }
18404            }
18405        }
18406
18407        boolean kept = true;
18408        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18409        // mainStack is null during startup.
18410        if (mainStack != null) {
18411            if (changes != 0 && starting == null) {
18412                // If the configuration changed, and the caller is not already
18413                // in the process of starting an activity, then find the top
18414                // activity to check if its configuration needs to change.
18415                starting = mainStack.topRunningActivityLocked();
18416            }
18417
18418            if (starting != null) {
18419                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18420                // And we need to make sure at this point that all other activities
18421                // are made visible with the correct configuration.
18422                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18423                        !PRESERVE_WINDOWS);
18424            }
18425        }
18426        if (mWindowManager != null) {
18427            mWindowManager.continueSurfaceLayout();
18428        }
18429        return kept;
18430    }
18431
18432    /**
18433     * Decide based on the configuration whether we should shouw the ANR,
18434     * crash, etc dialogs.  The idea is that if there is no affordnace to
18435     * press the on-screen buttons, we shouldn't show the dialog.
18436     *
18437     * A thought: SystemUI might also want to get told about this, the Power
18438     * dialog / global actions also might want different behaviors.
18439     */
18440    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18441        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18442                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18443                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18444        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18445                                    == Configuration.UI_MODE_TYPE_CAR);
18446        return inputMethodExists && uiIsNotCarType && !inVrMode;
18447    }
18448
18449    @Override
18450    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18451        synchronized (this) {
18452            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18453            if (srec != null) {
18454                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18455            }
18456        }
18457        return false;
18458    }
18459
18460    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18461            Intent resultData) {
18462
18463        synchronized (this) {
18464            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18465            if (r != null) {
18466                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18467            }
18468            return false;
18469        }
18470    }
18471
18472    public int getLaunchedFromUid(IBinder activityToken) {
18473        ActivityRecord srec;
18474        synchronized (this) {
18475            srec = ActivityRecord.forTokenLocked(activityToken);
18476        }
18477        if (srec == null) {
18478            return -1;
18479        }
18480        return srec.launchedFromUid;
18481    }
18482
18483    public String getLaunchedFromPackage(IBinder activityToken) {
18484        ActivityRecord srec;
18485        synchronized (this) {
18486            srec = ActivityRecord.forTokenLocked(activityToken);
18487        }
18488        if (srec == null) {
18489            return null;
18490        }
18491        return srec.launchedFromPackage;
18492    }
18493
18494    // =========================================================
18495    // LIFETIME MANAGEMENT
18496    // =========================================================
18497
18498    // Returns which broadcast queue the app is the current [or imminent] receiver
18499    // on, or 'null' if the app is not an active broadcast recipient.
18500    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18501        BroadcastRecord r = app.curReceiver;
18502        if (r != null) {
18503            return r.queue;
18504        }
18505
18506        // It's not the current receiver, but it might be starting up to become one
18507        synchronized (this) {
18508            for (BroadcastQueue queue : mBroadcastQueues) {
18509                r = queue.mPendingBroadcast;
18510                if (r != null && r.curApp == app) {
18511                    // found it; report which queue it's in
18512                    return queue;
18513                }
18514            }
18515        }
18516
18517        return null;
18518    }
18519
18520    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18521            int targetUid, ComponentName targetComponent, String targetProcess) {
18522        if (!mTrackingAssociations) {
18523            return null;
18524        }
18525        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18526                = mAssociations.get(targetUid);
18527        if (components == null) {
18528            components = new ArrayMap<>();
18529            mAssociations.put(targetUid, components);
18530        }
18531        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18532        if (sourceUids == null) {
18533            sourceUids = new SparseArray<>();
18534            components.put(targetComponent, sourceUids);
18535        }
18536        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18537        if (sourceProcesses == null) {
18538            sourceProcesses = new ArrayMap<>();
18539            sourceUids.put(sourceUid, sourceProcesses);
18540        }
18541        Association ass = sourceProcesses.get(sourceProcess);
18542        if (ass == null) {
18543            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18544                    targetProcess);
18545            sourceProcesses.put(sourceProcess, ass);
18546        }
18547        ass.mCount++;
18548        ass.mNesting++;
18549        if (ass.mNesting == 1) {
18550            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18551            ass.mLastState = sourceState;
18552        }
18553        return ass;
18554    }
18555
18556    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18557            ComponentName targetComponent) {
18558        if (!mTrackingAssociations) {
18559            return;
18560        }
18561        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18562                = mAssociations.get(targetUid);
18563        if (components == null) {
18564            return;
18565        }
18566        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18567        if (sourceUids == null) {
18568            return;
18569        }
18570        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18571        if (sourceProcesses == null) {
18572            return;
18573        }
18574        Association ass = sourceProcesses.get(sourceProcess);
18575        if (ass == null || ass.mNesting <= 0) {
18576            return;
18577        }
18578        ass.mNesting--;
18579        if (ass.mNesting == 0) {
18580            long uptime = SystemClock.uptimeMillis();
18581            ass.mTime += uptime - ass.mStartTime;
18582            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18583                    += uptime - ass.mLastStateUptime;
18584            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18585        }
18586    }
18587
18588    private void noteUidProcessState(final int uid, final int state) {
18589        mBatteryStatsService.noteUidProcessState(uid, state);
18590        if (mTrackingAssociations) {
18591            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18592                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18593                        = mAssociations.valueAt(i1);
18594                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18595                    SparseArray<ArrayMap<String, Association>> sourceUids
18596                            = targetComponents.valueAt(i2);
18597                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18598                    if (sourceProcesses != null) {
18599                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18600                            Association ass = sourceProcesses.valueAt(i4);
18601                            if (ass.mNesting >= 1) {
18602                                // currently associated
18603                                long uptime = SystemClock.uptimeMillis();
18604                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18605                                        += uptime - ass.mLastStateUptime;
18606                                ass.mLastState = state;
18607                                ass.mLastStateUptime = uptime;
18608                            }
18609                        }
18610                    }
18611                }
18612            }
18613        }
18614    }
18615
18616    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18617            boolean doingAll, long now) {
18618        if (mAdjSeq == app.adjSeq) {
18619            // This adjustment has already been computed.
18620            return app.curRawAdj;
18621        }
18622
18623        if (app.thread == null) {
18624            app.adjSeq = mAdjSeq;
18625            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18626            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18627            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18628        }
18629
18630        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18631        app.adjSource = null;
18632        app.adjTarget = null;
18633        app.empty = false;
18634        app.cached = false;
18635
18636        final int activitiesSize = app.activities.size();
18637
18638        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18639            // The max adjustment doesn't allow this app to be anything
18640            // below foreground, so it is not worth doing work for it.
18641            app.adjType = "fixed";
18642            app.adjSeq = mAdjSeq;
18643            app.curRawAdj = app.maxAdj;
18644            app.foregroundActivities = false;
18645            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18646            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18647            // System processes can do UI, and when they do we want to have
18648            // them trim their memory after the user leaves the UI.  To
18649            // facilitate this, here we need to determine whether or not it
18650            // is currently showing UI.
18651            app.systemNoUi = true;
18652            if (app == TOP_APP) {
18653                app.systemNoUi = false;
18654                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18655                app.adjType = "pers-top-activity";
18656            } else if (activitiesSize > 0) {
18657                for (int j = 0; j < activitiesSize; j++) {
18658                    final ActivityRecord r = app.activities.get(j);
18659                    if (r.visible) {
18660                        app.systemNoUi = false;
18661                    }
18662                }
18663            }
18664            if (!app.systemNoUi) {
18665                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18666            }
18667            return (app.curAdj=app.maxAdj);
18668        }
18669
18670        app.systemNoUi = false;
18671
18672        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18673
18674        // Determine the importance of the process, starting with most
18675        // important to least, and assign an appropriate OOM adjustment.
18676        int adj;
18677        int schedGroup;
18678        int procState;
18679        boolean foregroundActivities = false;
18680        BroadcastQueue queue;
18681        if (app == TOP_APP) {
18682            // The last app on the list is the foreground app.
18683            adj = ProcessList.FOREGROUND_APP_ADJ;
18684            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18685            app.adjType = "top-activity";
18686            foregroundActivities = true;
18687            procState = PROCESS_STATE_CUR_TOP;
18688        } else if (app.instrumentationClass != null) {
18689            // Don't want to kill running instrumentation.
18690            adj = ProcessList.FOREGROUND_APP_ADJ;
18691            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18692            app.adjType = "instrumentation";
18693            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18694        } else if ((queue = isReceivingBroadcast(app)) != null) {
18695            // An app that is currently receiving a broadcast also
18696            // counts as being in the foreground for OOM killer purposes.
18697            // It's placed in a sched group based on the nature of the
18698            // broadcast as reflected by which queue it's active in.
18699            adj = ProcessList.FOREGROUND_APP_ADJ;
18700            schedGroup = (queue == mFgBroadcastQueue)
18701                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18702            app.adjType = "broadcast";
18703            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18704        } else if (app.executingServices.size() > 0) {
18705            // An app that is currently executing a service callback also
18706            // counts as being in the foreground.
18707            adj = ProcessList.FOREGROUND_APP_ADJ;
18708            schedGroup = app.execServicesFg ?
18709                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18710            app.adjType = "exec-service";
18711            procState = ActivityManager.PROCESS_STATE_SERVICE;
18712            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18713        } else {
18714            // As far as we know the process is empty.  We may change our mind later.
18715            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18716            // At this point we don't actually know the adjustment.  Use the cached adj
18717            // value that the caller wants us to.
18718            adj = cachedAdj;
18719            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18720            app.cached = true;
18721            app.empty = true;
18722            app.adjType = "cch-empty";
18723        }
18724
18725        // Examine all activities if not already foreground.
18726        if (!foregroundActivities && activitiesSize > 0) {
18727            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18728            for (int j = 0; j < activitiesSize; j++) {
18729                final ActivityRecord r = app.activities.get(j);
18730                if (r.app != app) {
18731                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18732                            + " instead of expected " + app);
18733                    if (r.app == null || (r.app.uid == app.uid)) {
18734                        // Only fix things up when they look sane
18735                        r.app = app;
18736                    } else {
18737                        continue;
18738                    }
18739                }
18740                if (r.visible) {
18741                    // App has a visible activity; only upgrade adjustment.
18742                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18743                        adj = ProcessList.VISIBLE_APP_ADJ;
18744                        app.adjType = "visible";
18745                    }
18746                    if (procState > PROCESS_STATE_CUR_TOP) {
18747                        procState = PROCESS_STATE_CUR_TOP;
18748                    }
18749                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18750                    app.cached = false;
18751                    app.empty = false;
18752                    foregroundActivities = true;
18753                    if (r.task != null && minLayer > 0) {
18754                        final int layer = r.task.mLayerRank;
18755                        if (layer >= 0 && minLayer > layer) {
18756                            minLayer = layer;
18757                        }
18758                    }
18759                    break;
18760                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18761                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18762                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18763                        app.adjType = "pausing";
18764                    }
18765                    if (procState > PROCESS_STATE_CUR_TOP) {
18766                        procState = PROCESS_STATE_CUR_TOP;
18767                    }
18768                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18769                    app.cached = false;
18770                    app.empty = false;
18771                    foregroundActivities = true;
18772                } else if (r.state == ActivityState.STOPPING) {
18773                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18774                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18775                        app.adjType = "stopping";
18776                    }
18777                    // For the process state, we will at this point consider the
18778                    // process to be cached.  It will be cached either as an activity
18779                    // or empty depending on whether the activity is finishing.  We do
18780                    // this so that we can treat the process as cached for purposes of
18781                    // memory trimming (determing current memory level, trim command to
18782                    // send to process) since there can be an arbitrary number of stopping
18783                    // processes and they should soon all go into the cached state.
18784                    if (!r.finishing) {
18785                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18786                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18787                        }
18788                    }
18789                    app.cached = false;
18790                    app.empty = false;
18791                    foregroundActivities = true;
18792                } else {
18793                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18794                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18795                        app.adjType = "cch-act";
18796                    }
18797                }
18798            }
18799            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18800                adj += minLayer;
18801            }
18802        }
18803
18804        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18805                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18806            if (app.foregroundServices) {
18807                // The user is aware of this app, so make it visible.
18808                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18809                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18810                app.cached = false;
18811                app.adjType = "fg-service";
18812                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18813            } else if (app.forcingToForeground != null) {
18814                // The user is aware of this app, so make it visible.
18815                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18816                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18817                app.cached = false;
18818                app.adjType = "force-fg";
18819                app.adjSource = app.forcingToForeground;
18820                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18821            }
18822        }
18823
18824        if (app == mHeavyWeightProcess) {
18825            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18826                // We don't want to kill the current heavy-weight process.
18827                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18828                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18829                app.cached = false;
18830                app.adjType = "heavy";
18831            }
18832            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18833                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18834            }
18835        }
18836
18837        if (app == mHomeProcess) {
18838            if (adj > ProcessList.HOME_APP_ADJ) {
18839                // This process is hosting what we currently consider to be the
18840                // home app, so we don't want to let it go into the background.
18841                adj = ProcessList.HOME_APP_ADJ;
18842                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18843                app.cached = false;
18844                app.adjType = "home";
18845            }
18846            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18847                procState = ActivityManager.PROCESS_STATE_HOME;
18848            }
18849        }
18850
18851        if (app == mPreviousProcess && app.activities.size() > 0) {
18852            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18853                // This was the previous process that showed UI to the user.
18854                // We want to try to keep it around more aggressively, to give
18855                // a good experience around switching between two apps.
18856                adj = ProcessList.PREVIOUS_APP_ADJ;
18857                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18858                app.cached = false;
18859                app.adjType = "previous";
18860            }
18861            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18862                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18863            }
18864        }
18865
18866        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18867                + " reason=" + app.adjType);
18868
18869        // By default, we use the computed adjustment.  It may be changed if
18870        // there are applications dependent on our services or providers, but
18871        // this gives us a baseline and makes sure we don't get into an
18872        // infinite recursion.
18873        app.adjSeq = mAdjSeq;
18874        app.curRawAdj = adj;
18875        app.hasStartedServices = false;
18876
18877        if (mBackupTarget != null && app == mBackupTarget.app) {
18878            // If possible we want to avoid killing apps while they're being backed up
18879            if (adj > ProcessList.BACKUP_APP_ADJ) {
18880                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18881                adj = ProcessList.BACKUP_APP_ADJ;
18882                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18883                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18884                }
18885                app.adjType = "backup";
18886                app.cached = false;
18887            }
18888            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18889                procState = ActivityManager.PROCESS_STATE_BACKUP;
18890            }
18891        }
18892
18893        boolean mayBeTop = false;
18894
18895        for (int is = app.services.size()-1;
18896                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18897                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18898                        || procState > ActivityManager.PROCESS_STATE_TOP);
18899                is--) {
18900            ServiceRecord s = app.services.valueAt(is);
18901            if (s.startRequested) {
18902                app.hasStartedServices = true;
18903                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18904                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18905                }
18906                if (app.hasShownUi && app != mHomeProcess) {
18907                    // If this process has shown some UI, let it immediately
18908                    // go to the LRU list because it may be pretty heavy with
18909                    // UI stuff.  We'll tag it with a label just to help
18910                    // debug and understand what is going on.
18911                    if (adj > ProcessList.SERVICE_ADJ) {
18912                        app.adjType = "cch-started-ui-services";
18913                    }
18914                } else {
18915                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18916                        // This service has seen some activity within
18917                        // recent memory, so we will keep its process ahead
18918                        // of the background processes.
18919                        if (adj > ProcessList.SERVICE_ADJ) {
18920                            adj = ProcessList.SERVICE_ADJ;
18921                            app.adjType = "started-services";
18922                            app.cached = false;
18923                        }
18924                    }
18925                    // If we have let the service slide into the background
18926                    // state, still have some text describing what it is doing
18927                    // even though the service no longer has an impact.
18928                    if (adj > ProcessList.SERVICE_ADJ) {
18929                        app.adjType = "cch-started-services";
18930                    }
18931                }
18932            }
18933            for (int conni = s.connections.size()-1;
18934                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18935                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18936                            || procState > ActivityManager.PROCESS_STATE_TOP);
18937                    conni--) {
18938                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18939                for (int i = 0;
18940                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18941                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18942                                || procState > ActivityManager.PROCESS_STATE_TOP);
18943                        i++) {
18944                    // XXX should compute this based on the max of
18945                    // all connected clients.
18946                    ConnectionRecord cr = clist.get(i);
18947                    if (cr.binding.client == app) {
18948                        // Binding to ourself is not interesting.
18949                        continue;
18950                    }
18951                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18952                        ProcessRecord client = cr.binding.client;
18953                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18954                                TOP_APP, doingAll, now);
18955                        int clientProcState = client.curProcState;
18956                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18957                            // If the other app is cached for any reason, for purposes here
18958                            // we are going to consider it empty.  The specific cached state
18959                            // doesn't propagate except under certain conditions.
18960                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18961                        }
18962                        String adjType = null;
18963                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18964                            // Not doing bind OOM management, so treat
18965                            // this guy more like a started service.
18966                            if (app.hasShownUi && app != mHomeProcess) {
18967                                // If this process has shown some UI, let it immediately
18968                                // go to the LRU list because it may be pretty heavy with
18969                                // UI stuff.  We'll tag it with a label just to help
18970                                // debug and understand what is going on.
18971                                if (adj > clientAdj) {
18972                                    adjType = "cch-bound-ui-services";
18973                                }
18974                                app.cached = false;
18975                                clientAdj = adj;
18976                                clientProcState = procState;
18977                            } else {
18978                                if (now >= (s.lastActivity
18979                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18980                                    // This service has not seen activity within
18981                                    // recent memory, so allow it to drop to the
18982                                    // LRU list if there is no other reason to keep
18983                                    // it around.  We'll also tag it with a label just
18984                                    // to help debug and undertand what is going on.
18985                                    if (adj > clientAdj) {
18986                                        adjType = "cch-bound-services";
18987                                    }
18988                                    clientAdj = adj;
18989                                }
18990                            }
18991                        }
18992                        if (adj > clientAdj) {
18993                            // If this process has recently shown UI, and
18994                            // the process that is binding to it is less
18995                            // important than being visible, then we don't
18996                            // care about the binding as much as we care
18997                            // about letting this process get into the LRU
18998                            // list to be killed and restarted if needed for
18999                            // memory.
19000                            if (app.hasShownUi && app != mHomeProcess
19001                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19002                                adjType = "cch-bound-ui-services";
19003                            } else {
19004                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19005                                        |Context.BIND_IMPORTANT)) != 0) {
19006                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19007                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19008                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19009                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19010                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19011                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19012                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19013                                    adj = clientAdj;
19014                                } else {
19015                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19016                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19017                                    }
19018                                }
19019                                if (!client.cached) {
19020                                    app.cached = false;
19021                                }
19022                                adjType = "service";
19023                            }
19024                        }
19025                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19026                            // This will treat important bound services identically to
19027                            // the top app, which may behave differently than generic
19028                            // foreground work.
19029                            if (client.curSchedGroup > schedGroup) {
19030                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19031                                    schedGroup = client.curSchedGroup;
19032                                } else {
19033                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19034                                }
19035                            }
19036                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19037                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19038                                    // Special handling of clients who are in the top state.
19039                                    // We *may* want to consider this process to be in the
19040                                    // top state as well, but only if there is not another
19041                                    // reason for it to be running.  Being on the top is a
19042                                    // special state, meaning you are specifically running
19043                                    // for the current top app.  If the process is already
19044                                    // running in the background for some other reason, it
19045                                    // is more important to continue considering it to be
19046                                    // in the background state.
19047                                    mayBeTop = true;
19048                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19049                                } else {
19050                                    // Special handling for above-top states (persistent
19051                                    // processes).  These should not bring the current process
19052                                    // into the top state, since they are not on top.  Instead
19053                                    // give them the best state after that.
19054                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19055                                        clientProcState =
19056                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19057                                    } else if (mWakefulness
19058                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19059                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19060                                                    != 0) {
19061                                        clientProcState =
19062                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19063                                    } else {
19064                                        clientProcState =
19065                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19066                                    }
19067                                }
19068                            }
19069                        } else {
19070                            if (clientProcState <
19071                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19072                                clientProcState =
19073                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19074                            }
19075                        }
19076                        if (procState > clientProcState) {
19077                            procState = clientProcState;
19078                        }
19079                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19080                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19081                            app.pendingUiClean = true;
19082                        }
19083                        if (adjType != null) {
19084                            app.adjType = adjType;
19085                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19086                                    .REASON_SERVICE_IN_USE;
19087                            app.adjSource = cr.binding.client;
19088                            app.adjSourceProcState = clientProcState;
19089                            app.adjTarget = s.name;
19090                        }
19091                    }
19092                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19093                        app.treatLikeActivity = true;
19094                    }
19095                    final ActivityRecord a = cr.activity;
19096                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19097                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19098                            (a.visible || a.state == ActivityState.RESUMED ||
19099                             a.state == ActivityState.PAUSING)) {
19100                            adj = ProcessList.FOREGROUND_APP_ADJ;
19101                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19102                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19103                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19104                                } else {
19105                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19106                                }
19107                            }
19108                            app.cached = false;
19109                            app.adjType = "service";
19110                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19111                                    .REASON_SERVICE_IN_USE;
19112                            app.adjSource = a;
19113                            app.adjSourceProcState = procState;
19114                            app.adjTarget = s.name;
19115                        }
19116                    }
19117                }
19118            }
19119        }
19120
19121        for (int provi = app.pubProviders.size()-1;
19122                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19123                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19124                        || procState > ActivityManager.PROCESS_STATE_TOP);
19125                provi--) {
19126            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19127            for (int i = cpr.connections.size()-1;
19128                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19129                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19130                            || procState > ActivityManager.PROCESS_STATE_TOP);
19131                    i--) {
19132                ContentProviderConnection conn = cpr.connections.get(i);
19133                ProcessRecord client = conn.client;
19134                if (client == app) {
19135                    // Being our own client is not interesting.
19136                    continue;
19137                }
19138                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19139                int clientProcState = client.curProcState;
19140                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19141                    // If the other app is cached for any reason, for purposes here
19142                    // we are going to consider it empty.
19143                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19144                }
19145                if (adj > clientAdj) {
19146                    if (app.hasShownUi && app != mHomeProcess
19147                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19148                        app.adjType = "cch-ui-provider";
19149                    } else {
19150                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19151                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19152                        app.adjType = "provider";
19153                    }
19154                    app.cached &= client.cached;
19155                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19156                            .REASON_PROVIDER_IN_USE;
19157                    app.adjSource = client;
19158                    app.adjSourceProcState = clientProcState;
19159                    app.adjTarget = cpr.name;
19160                }
19161                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19162                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19163                        // Special handling of clients who are in the top state.
19164                        // We *may* want to consider this process to be in the
19165                        // top state as well, but only if there is not another
19166                        // reason for it to be running.  Being on the top is a
19167                        // special state, meaning you are specifically running
19168                        // for the current top app.  If the process is already
19169                        // running in the background for some other reason, it
19170                        // is more important to continue considering it to be
19171                        // in the background state.
19172                        mayBeTop = true;
19173                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19174                    } else {
19175                        // Special handling for above-top states (persistent
19176                        // processes).  These should not bring the current process
19177                        // into the top state, since they are not on top.  Instead
19178                        // give them the best state after that.
19179                        clientProcState =
19180                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19181                    }
19182                }
19183                if (procState > clientProcState) {
19184                    procState = clientProcState;
19185                }
19186                if (client.curSchedGroup > schedGroup) {
19187                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19188                }
19189            }
19190            // If the provider has external (non-framework) process
19191            // dependencies, ensure that its adjustment is at least
19192            // FOREGROUND_APP_ADJ.
19193            if (cpr.hasExternalProcessHandles()) {
19194                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19195                    adj = ProcessList.FOREGROUND_APP_ADJ;
19196                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19197                    app.cached = false;
19198                    app.adjType = "provider";
19199                    app.adjTarget = cpr.name;
19200                }
19201                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19202                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19203                }
19204            }
19205        }
19206
19207        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19208            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19209                adj = ProcessList.PREVIOUS_APP_ADJ;
19210                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19211                app.cached = false;
19212                app.adjType = "provider";
19213            }
19214            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19215                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19216            }
19217        }
19218
19219        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19220            // A client of one of our services or providers is in the top state.  We
19221            // *may* want to be in the top state, but not if we are already running in
19222            // the background for some other reason.  For the decision here, we are going
19223            // to pick out a few specific states that we want to remain in when a client
19224            // is top (states that tend to be longer-term) and otherwise allow it to go
19225            // to the top state.
19226            switch (procState) {
19227                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19228                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19229                case ActivityManager.PROCESS_STATE_SERVICE:
19230                    // These all are longer-term states, so pull them up to the top
19231                    // of the background states, but not all the way to the top state.
19232                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19233                    break;
19234                default:
19235                    // Otherwise, top is a better choice, so take it.
19236                    procState = ActivityManager.PROCESS_STATE_TOP;
19237                    break;
19238            }
19239        }
19240
19241        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19242            if (app.hasClientActivities) {
19243                // This is a cached process, but with client activities.  Mark it so.
19244                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19245                app.adjType = "cch-client-act";
19246            } else if (app.treatLikeActivity) {
19247                // This is a cached process, but somebody wants us to treat it like it has
19248                // an activity, okay!
19249                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19250                app.adjType = "cch-as-act";
19251            }
19252        }
19253
19254        if (adj == ProcessList.SERVICE_ADJ) {
19255            if (doingAll) {
19256                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19257                mNewNumServiceProcs++;
19258                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19259                if (!app.serviceb) {
19260                    // This service isn't far enough down on the LRU list to
19261                    // normally be a B service, but if we are low on RAM and it
19262                    // is large we want to force it down since we would prefer to
19263                    // keep launcher over it.
19264                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19265                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19266                        app.serviceHighRam = true;
19267                        app.serviceb = true;
19268                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19269                    } else {
19270                        mNewNumAServiceProcs++;
19271                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19272                    }
19273                } else {
19274                    app.serviceHighRam = false;
19275                }
19276            }
19277            if (app.serviceb) {
19278                adj = ProcessList.SERVICE_B_ADJ;
19279            }
19280        }
19281
19282        app.curRawAdj = adj;
19283
19284        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19285        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19286        if (adj > app.maxAdj) {
19287            adj = app.maxAdj;
19288            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19289                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19290            }
19291        }
19292
19293        // Do final modification to adj.  Everything we do between here and applying
19294        // the final setAdj must be done in this function, because we will also use
19295        // it when computing the final cached adj later.  Note that we don't need to
19296        // worry about this for max adj above, since max adj will always be used to
19297        // keep it out of the cached vaues.
19298        app.curAdj = app.modifyRawOomAdj(adj);
19299        app.curSchedGroup = schedGroup;
19300        app.curProcState = procState;
19301        app.foregroundActivities = foregroundActivities;
19302
19303        return app.curRawAdj;
19304    }
19305
19306    /**
19307     * Record new PSS sample for a process.
19308     */
19309    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19310            long now) {
19311        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19312                swapPss * 1024);
19313        proc.lastPssTime = now;
19314        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19315        if (DEBUG_PSS) Slog.d(TAG_PSS,
19316                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19317                + " state=" + ProcessList.makeProcStateString(procState));
19318        if (proc.initialIdlePss == 0) {
19319            proc.initialIdlePss = pss;
19320        }
19321        proc.lastPss = pss;
19322        proc.lastSwapPss = swapPss;
19323        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19324            proc.lastCachedPss = pss;
19325            proc.lastCachedSwapPss = swapPss;
19326        }
19327
19328        final SparseArray<Pair<Long, String>> watchUids
19329                = mMemWatchProcesses.getMap().get(proc.processName);
19330        Long check = null;
19331        if (watchUids != null) {
19332            Pair<Long, String> val = watchUids.get(proc.uid);
19333            if (val == null) {
19334                val = watchUids.get(0);
19335            }
19336            if (val != null) {
19337                check = val.first;
19338            }
19339        }
19340        if (check != null) {
19341            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19342                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19343                if (!isDebuggable) {
19344                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19345                        isDebuggable = true;
19346                    }
19347                }
19348                if (isDebuggable) {
19349                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19350                    final ProcessRecord myProc = proc;
19351                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19352                    mMemWatchDumpProcName = proc.processName;
19353                    mMemWatchDumpFile = heapdumpFile.toString();
19354                    mMemWatchDumpPid = proc.pid;
19355                    mMemWatchDumpUid = proc.uid;
19356                    BackgroundThread.getHandler().post(new Runnable() {
19357                        @Override
19358                        public void run() {
19359                            revokeUriPermission(ActivityThread.currentActivityThread()
19360                                            .getApplicationThread(),
19361                                    DumpHeapActivity.JAVA_URI,
19362                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19363                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19364                                    UserHandle.myUserId());
19365                            ParcelFileDescriptor fd = null;
19366                            try {
19367                                heapdumpFile.delete();
19368                                fd = ParcelFileDescriptor.open(heapdumpFile,
19369                                        ParcelFileDescriptor.MODE_CREATE |
19370                                                ParcelFileDescriptor.MODE_TRUNCATE |
19371                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19372                                                ParcelFileDescriptor.MODE_APPEND);
19373                                IApplicationThread thread = myProc.thread;
19374                                if (thread != null) {
19375                                    try {
19376                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19377                                                "Requesting dump heap from "
19378                                                + myProc + " to " + heapdumpFile);
19379                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19380                                    } catch (RemoteException e) {
19381                                    }
19382                                }
19383                            } catch (FileNotFoundException e) {
19384                                e.printStackTrace();
19385                            } finally {
19386                                if (fd != null) {
19387                                    try {
19388                                        fd.close();
19389                                    } catch (IOException e) {
19390                                    }
19391                                }
19392                            }
19393                        }
19394                    });
19395                } else {
19396                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19397                            + ", but debugging not enabled");
19398                }
19399            }
19400        }
19401    }
19402
19403    /**
19404     * Schedule PSS collection of a process.
19405     */
19406    void requestPssLocked(ProcessRecord proc, int procState) {
19407        if (mPendingPssProcesses.contains(proc)) {
19408            return;
19409        }
19410        if (mPendingPssProcesses.size() == 0) {
19411            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19412        }
19413        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19414        proc.pssProcState = procState;
19415        mPendingPssProcesses.add(proc);
19416    }
19417
19418    /**
19419     * Schedule PSS collection of all processes.
19420     */
19421    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19422        if (!always) {
19423            if (now < (mLastFullPssTime +
19424                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19425                return;
19426            }
19427        }
19428        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19429        mLastFullPssTime = now;
19430        mFullPssPending = true;
19431        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19432        mPendingPssProcesses.clear();
19433        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19434            ProcessRecord app = mLruProcesses.get(i);
19435            if (app.thread == null
19436                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19437                continue;
19438            }
19439            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19440                app.pssProcState = app.setProcState;
19441                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19442                        mTestPssMode, isSleeping(), now);
19443                mPendingPssProcesses.add(app);
19444            }
19445        }
19446        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19447    }
19448
19449    public void setTestPssMode(boolean enabled) {
19450        synchronized (this) {
19451            mTestPssMode = enabled;
19452            if (enabled) {
19453                // Whenever we enable the mode, we want to take a snapshot all of current
19454                // process mem use.
19455                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19456            }
19457        }
19458    }
19459
19460    /**
19461     * Ask a given process to GC right now.
19462     */
19463    final void performAppGcLocked(ProcessRecord app) {
19464        try {
19465            app.lastRequestedGc = SystemClock.uptimeMillis();
19466            if (app.thread != null) {
19467                if (app.reportLowMemory) {
19468                    app.reportLowMemory = false;
19469                    app.thread.scheduleLowMemory();
19470                } else {
19471                    app.thread.processInBackground();
19472                }
19473            }
19474        } catch (Exception e) {
19475            // whatever.
19476        }
19477    }
19478
19479    /**
19480     * Returns true if things are idle enough to perform GCs.
19481     */
19482    private final boolean canGcNowLocked() {
19483        boolean processingBroadcasts = false;
19484        for (BroadcastQueue q : mBroadcastQueues) {
19485            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19486                processingBroadcasts = true;
19487            }
19488        }
19489        return !processingBroadcasts
19490                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19491    }
19492
19493    /**
19494     * Perform GCs on all processes that are waiting for it, but only
19495     * if things are idle.
19496     */
19497    final void performAppGcsLocked() {
19498        final int N = mProcessesToGc.size();
19499        if (N <= 0) {
19500            return;
19501        }
19502        if (canGcNowLocked()) {
19503            while (mProcessesToGc.size() > 0) {
19504                ProcessRecord proc = mProcessesToGc.remove(0);
19505                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19506                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19507                            <= SystemClock.uptimeMillis()) {
19508                        // To avoid spamming the system, we will GC processes one
19509                        // at a time, waiting a few seconds between each.
19510                        performAppGcLocked(proc);
19511                        scheduleAppGcsLocked();
19512                        return;
19513                    } else {
19514                        // It hasn't been long enough since we last GCed this
19515                        // process...  put it in the list to wait for its time.
19516                        addProcessToGcListLocked(proc);
19517                        break;
19518                    }
19519                }
19520            }
19521
19522            scheduleAppGcsLocked();
19523        }
19524    }
19525
19526    /**
19527     * If all looks good, perform GCs on all processes waiting for them.
19528     */
19529    final void performAppGcsIfAppropriateLocked() {
19530        if (canGcNowLocked()) {
19531            performAppGcsLocked();
19532            return;
19533        }
19534        // Still not idle, wait some more.
19535        scheduleAppGcsLocked();
19536    }
19537
19538    /**
19539     * Schedule the execution of all pending app GCs.
19540     */
19541    final void scheduleAppGcsLocked() {
19542        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19543
19544        if (mProcessesToGc.size() > 0) {
19545            // Schedule a GC for the time to the next process.
19546            ProcessRecord proc = mProcessesToGc.get(0);
19547            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19548
19549            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19550            long now = SystemClock.uptimeMillis();
19551            if (when < (now+GC_TIMEOUT)) {
19552                when = now + GC_TIMEOUT;
19553            }
19554            mHandler.sendMessageAtTime(msg, when);
19555        }
19556    }
19557
19558    /**
19559     * Add a process to the array of processes waiting to be GCed.  Keeps the
19560     * list in sorted order by the last GC time.  The process can't already be
19561     * on the list.
19562     */
19563    final void addProcessToGcListLocked(ProcessRecord proc) {
19564        boolean added = false;
19565        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19566            if (mProcessesToGc.get(i).lastRequestedGc <
19567                    proc.lastRequestedGc) {
19568                added = true;
19569                mProcessesToGc.add(i+1, proc);
19570                break;
19571            }
19572        }
19573        if (!added) {
19574            mProcessesToGc.add(0, proc);
19575        }
19576    }
19577
19578    /**
19579     * Set up to ask a process to GC itself.  This will either do it
19580     * immediately, or put it on the list of processes to gc the next
19581     * time things are idle.
19582     */
19583    final void scheduleAppGcLocked(ProcessRecord app) {
19584        long now = SystemClock.uptimeMillis();
19585        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19586            return;
19587        }
19588        if (!mProcessesToGc.contains(app)) {
19589            addProcessToGcListLocked(app);
19590            scheduleAppGcsLocked();
19591        }
19592    }
19593
19594    final void checkExcessivePowerUsageLocked(boolean doKills) {
19595        updateCpuStatsNow();
19596
19597        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19598        boolean doWakeKills = doKills;
19599        boolean doCpuKills = doKills;
19600        if (mLastPowerCheckRealtime == 0) {
19601            doWakeKills = false;
19602        }
19603        if (mLastPowerCheckUptime == 0) {
19604            doCpuKills = false;
19605        }
19606        if (stats.isScreenOn()) {
19607            doWakeKills = false;
19608        }
19609        final long curRealtime = SystemClock.elapsedRealtime();
19610        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19611        final long curUptime = SystemClock.uptimeMillis();
19612        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19613        mLastPowerCheckRealtime = curRealtime;
19614        mLastPowerCheckUptime = curUptime;
19615        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19616            doWakeKills = false;
19617        }
19618        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19619            doCpuKills = false;
19620        }
19621        int i = mLruProcesses.size();
19622        while (i > 0) {
19623            i--;
19624            ProcessRecord app = mLruProcesses.get(i);
19625            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19626                long wtime;
19627                synchronized (stats) {
19628                    wtime = stats.getProcessWakeTime(app.info.uid,
19629                            app.pid, curRealtime);
19630                }
19631                long wtimeUsed = wtime - app.lastWakeTime;
19632                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19633                if (DEBUG_POWER) {
19634                    StringBuilder sb = new StringBuilder(128);
19635                    sb.append("Wake for ");
19636                    app.toShortString(sb);
19637                    sb.append(": over ");
19638                    TimeUtils.formatDuration(realtimeSince, sb);
19639                    sb.append(" used ");
19640                    TimeUtils.formatDuration(wtimeUsed, sb);
19641                    sb.append(" (");
19642                    sb.append((wtimeUsed*100)/realtimeSince);
19643                    sb.append("%)");
19644                    Slog.i(TAG_POWER, sb.toString());
19645                    sb.setLength(0);
19646                    sb.append("CPU for ");
19647                    app.toShortString(sb);
19648                    sb.append(": over ");
19649                    TimeUtils.formatDuration(uptimeSince, sb);
19650                    sb.append(" used ");
19651                    TimeUtils.formatDuration(cputimeUsed, sb);
19652                    sb.append(" (");
19653                    sb.append((cputimeUsed*100)/uptimeSince);
19654                    sb.append("%)");
19655                    Slog.i(TAG_POWER, sb.toString());
19656                }
19657                // If a process has held a wake lock for more
19658                // than 50% of the time during this period,
19659                // that sounds bad.  Kill!
19660                if (doWakeKills && realtimeSince > 0
19661                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19662                    synchronized (stats) {
19663                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19664                                realtimeSince, wtimeUsed);
19665                    }
19666                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19667                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19668                } else if (doCpuKills && uptimeSince > 0
19669                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19670                    synchronized (stats) {
19671                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19672                                uptimeSince, cputimeUsed);
19673                    }
19674                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19675                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19676                } else {
19677                    app.lastWakeTime = wtime;
19678                    app.lastCpuTime = app.curCpuTime;
19679                }
19680            }
19681        }
19682    }
19683
19684    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19685            long nowElapsed) {
19686        boolean success = true;
19687
19688        if (app.curRawAdj != app.setRawAdj) {
19689            app.setRawAdj = app.curRawAdj;
19690        }
19691
19692        int changes = 0;
19693
19694        if (app.curAdj != app.setAdj) {
19695            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19696            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19697                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19698                    + app.adjType);
19699            app.setAdj = app.curAdj;
19700        }
19701
19702        if (app.setSchedGroup != app.curSchedGroup) {
19703            app.setSchedGroup = app.curSchedGroup;
19704            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19705                    "Setting sched group of " + app.processName
19706                    + " to " + app.curSchedGroup);
19707            if (app.waitingToKill != null && app.curReceiver == null
19708                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19709                app.kill(app.waitingToKill, true);
19710                success = false;
19711            } else {
19712                int processGroup;
19713                switch (app.curSchedGroup) {
19714                    case ProcessList.SCHED_GROUP_BACKGROUND:
19715                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19716                        break;
19717                    case ProcessList.SCHED_GROUP_TOP_APP:
19718                        processGroup = Process.THREAD_GROUP_TOP_APP;
19719                        break;
19720                    default:
19721                        processGroup = Process.THREAD_GROUP_DEFAULT;
19722                        break;
19723                }
19724                if (true) {
19725                    long oldId = Binder.clearCallingIdentity();
19726                    try {
19727                        Process.setProcessGroup(app.pid, processGroup);
19728                    } catch (Exception e) {
19729                        Slog.w(TAG, "Failed setting process group of " + app.pid
19730                                + " to " + app.curSchedGroup);
19731                        e.printStackTrace();
19732                    } finally {
19733                        Binder.restoreCallingIdentity(oldId);
19734                    }
19735                } else {
19736                    if (app.thread != null) {
19737                        try {
19738                            app.thread.setSchedulingGroup(processGroup);
19739                        } catch (RemoteException e) {
19740                        }
19741                    }
19742                }
19743            }
19744        }
19745        if (app.repForegroundActivities != app.foregroundActivities) {
19746            app.repForegroundActivities = app.foregroundActivities;
19747            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19748        }
19749        if (app.repProcState != app.curProcState) {
19750            app.repProcState = app.curProcState;
19751            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19752            if (app.thread != null) {
19753                try {
19754                    if (false) {
19755                        //RuntimeException h = new RuntimeException("here");
19756                        Slog.i(TAG, "Sending new process state " + app.repProcState
19757                                + " to " + app /*, h*/);
19758                    }
19759                    app.thread.setProcessState(app.repProcState);
19760                } catch (RemoteException e) {
19761                }
19762            }
19763        }
19764        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19765                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19766            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19767                // Experimental code to more aggressively collect pss while
19768                // running test...  the problem is that this tends to collect
19769                // the data right when a process is transitioning between process
19770                // states, which well tend to give noisy data.
19771                long start = SystemClock.uptimeMillis();
19772                long pss = Debug.getPss(app.pid, mTmpLong, null);
19773                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19774                mPendingPssProcesses.remove(app);
19775                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19776                        + " to " + app.curProcState + ": "
19777                        + (SystemClock.uptimeMillis()-start) + "ms");
19778            }
19779            app.lastStateTime = now;
19780            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19781                    mTestPssMode, isSleeping(), now);
19782            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19783                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19784                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19785                    + (app.nextPssTime-now) + ": " + app);
19786        } else {
19787            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19788                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19789                    mTestPssMode)))) {
19790                requestPssLocked(app, app.setProcState);
19791                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19792                        mTestPssMode, isSleeping(), now);
19793            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19794                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19795        }
19796        if (app.setProcState != app.curProcState) {
19797            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19798                    "Proc state change of " + app.processName
19799                            + " to " + app.curProcState);
19800            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19801            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19802            if (setImportant && !curImportant) {
19803                // This app is no longer something we consider important enough to allow to
19804                // use arbitrary amounts of battery power.  Note
19805                // its current wake lock time to later know to kill it if
19806                // it is not behaving well.
19807                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19808                synchronized (stats) {
19809                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19810                            app.pid, nowElapsed);
19811                }
19812                app.lastCpuTime = app.curCpuTime;
19813
19814            }
19815            // Inform UsageStats of important process state change
19816            // Must be called before updating setProcState
19817            maybeUpdateUsageStatsLocked(app, nowElapsed);
19818
19819            app.setProcState = app.curProcState;
19820            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19821                app.notCachedSinceIdle = false;
19822            }
19823            if (!doingAll) {
19824                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19825            } else {
19826                app.procStateChanged = true;
19827            }
19828        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19829                > USAGE_STATS_INTERACTION_INTERVAL) {
19830            // For apps that sit around for a long time in the interactive state, we need
19831            // to report this at least once a day so they don't go idle.
19832            maybeUpdateUsageStatsLocked(app, nowElapsed);
19833        }
19834
19835        if (changes != 0) {
19836            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19837                    "Changes in " + app + ": " + changes);
19838            int i = mPendingProcessChanges.size()-1;
19839            ProcessChangeItem item = null;
19840            while (i >= 0) {
19841                item = mPendingProcessChanges.get(i);
19842                if (item.pid == app.pid) {
19843                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19844                            "Re-using existing item: " + item);
19845                    break;
19846                }
19847                i--;
19848            }
19849            if (i < 0) {
19850                // No existing item in pending changes; need a new one.
19851                final int NA = mAvailProcessChanges.size();
19852                if (NA > 0) {
19853                    item = mAvailProcessChanges.remove(NA-1);
19854                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19855                            "Retrieving available item: " + item);
19856                } else {
19857                    item = new ProcessChangeItem();
19858                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19859                            "Allocating new item: " + item);
19860                }
19861                item.changes = 0;
19862                item.pid = app.pid;
19863                item.uid = app.info.uid;
19864                if (mPendingProcessChanges.size() == 0) {
19865                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19866                            "*** Enqueueing dispatch processes changed!");
19867                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19868                }
19869                mPendingProcessChanges.add(item);
19870            }
19871            item.changes |= changes;
19872            item.processState = app.repProcState;
19873            item.foregroundActivities = app.repForegroundActivities;
19874            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19875                    "Item " + Integer.toHexString(System.identityHashCode(item))
19876                    + " " + app.toShortString() + ": changes=" + item.changes
19877                    + " procState=" + item.processState
19878                    + " foreground=" + item.foregroundActivities
19879                    + " type=" + app.adjType + " source=" + app.adjSource
19880                    + " target=" + app.adjTarget);
19881        }
19882
19883        return success;
19884    }
19885
19886    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19887        final UidRecord.ChangeItem pendingChange;
19888        if (uidRec == null || uidRec.pendingChange == null) {
19889            if (mPendingUidChanges.size() == 0) {
19890                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19891                        "*** Enqueueing dispatch uid changed!");
19892                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19893            }
19894            final int NA = mAvailUidChanges.size();
19895            if (NA > 0) {
19896                pendingChange = mAvailUidChanges.remove(NA-1);
19897                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19898                        "Retrieving available item: " + pendingChange);
19899            } else {
19900                pendingChange = new UidRecord.ChangeItem();
19901                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19902                        "Allocating new item: " + pendingChange);
19903            }
19904            if (uidRec != null) {
19905                uidRec.pendingChange = pendingChange;
19906                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19907                    // If this uid is going away, and we haven't yet reported it is gone,
19908                    // then do so now.
19909                    change = UidRecord.CHANGE_GONE_IDLE;
19910                }
19911            } else if (uid < 0) {
19912                throw new IllegalArgumentException("No UidRecord or uid");
19913            }
19914            pendingChange.uidRecord = uidRec;
19915            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19916            mPendingUidChanges.add(pendingChange);
19917        } else {
19918            pendingChange = uidRec.pendingChange;
19919            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19920                change = UidRecord.CHANGE_GONE_IDLE;
19921            }
19922        }
19923        pendingChange.change = change;
19924        pendingChange.processState = uidRec != null
19925                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19926    }
19927
19928    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19929            String authority) {
19930        if (app == null) return;
19931        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19932            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19933            if (userState == null) return;
19934            final long now = SystemClock.elapsedRealtime();
19935            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19936            if (lastReported == null || lastReported < now - 60 * 1000L) {
19937                mUsageStatsService.reportContentProviderUsage(
19938                        authority, providerPkgName, app.userId);
19939                userState.mProviderLastReportedFg.put(authority, now);
19940            }
19941        }
19942    }
19943
19944    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19945        if (DEBUG_USAGE_STATS) {
19946            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19947                    + "] state changes: old = " + app.setProcState + ", new = "
19948                    + app.curProcState);
19949        }
19950        if (mUsageStatsService == null) {
19951            return;
19952        }
19953        boolean isInteraction;
19954        // To avoid some abuse patterns, we are going to be careful about what we consider
19955        // to be an app interaction.  Being the top activity doesn't count while the display
19956        // is sleeping, nor do short foreground services.
19957        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19958            isInteraction = true;
19959            app.fgInteractionTime = 0;
19960        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19961            if (app.fgInteractionTime == 0) {
19962                app.fgInteractionTime = nowElapsed;
19963                isInteraction = false;
19964            } else {
19965                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19966            }
19967        } else {
19968            isInteraction = app.curProcState
19969                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19970            app.fgInteractionTime = 0;
19971        }
19972        if (isInteraction && (!app.reportedInteraction
19973                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19974            app.interactionEventTime = nowElapsed;
19975            String[] packages = app.getPackageList();
19976            if (packages != null) {
19977                for (int i = 0; i < packages.length; i++) {
19978                    mUsageStatsService.reportEvent(packages[i], app.userId,
19979                            UsageEvents.Event.SYSTEM_INTERACTION);
19980                }
19981            }
19982        }
19983        app.reportedInteraction = isInteraction;
19984        if (!isInteraction) {
19985            app.interactionEventTime = 0;
19986        }
19987    }
19988
19989    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19990        if (proc.thread != null) {
19991            if (proc.baseProcessTracker != null) {
19992                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19993            }
19994        }
19995    }
19996
19997    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19998            ProcessRecord TOP_APP, boolean doingAll, long now) {
19999        if (app.thread == null) {
20000            return false;
20001        }
20002
20003        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20004
20005        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20006    }
20007
20008    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20009            boolean oomAdj) {
20010        if (isForeground != proc.foregroundServices) {
20011            proc.foregroundServices = isForeground;
20012            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20013                    proc.info.uid);
20014            if (isForeground) {
20015                if (curProcs == null) {
20016                    curProcs = new ArrayList<ProcessRecord>();
20017                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20018                }
20019                if (!curProcs.contains(proc)) {
20020                    curProcs.add(proc);
20021                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20022                            proc.info.packageName, proc.info.uid);
20023                }
20024            } else {
20025                if (curProcs != null) {
20026                    if (curProcs.remove(proc)) {
20027                        mBatteryStatsService.noteEvent(
20028                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20029                                proc.info.packageName, proc.info.uid);
20030                        if (curProcs.size() <= 0) {
20031                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20032                        }
20033                    }
20034                }
20035            }
20036            if (oomAdj) {
20037                updateOomAdjLocked();
20038            }
20039        }
20040    }
20041
20042    private final ActivityRecord resumedAppLocked() {
20043        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20044        String pkg;
20045        int uid;
20046        if (act != null) {
20047            pkg = act.packageName;
20048            uid = act.info.applicationInfo.uid;
20049        } else {
20050            pkg = null;
20051            uid = -1;
20052        }
20053        // Has the UID or resumed package name changed?
20054        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20055                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20056            if (mCurResumedPackage != null) {
20057                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20058                        mCurResumedPackage, mCurResumedUid);
20059            }
20060            mCurResumedPackage = pkg;
20061            mCurResumedUid = uid;
20062            if (mCurResumedPackage != null) {
20063                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20064                        mCurResumedPackage, mCurResumedUid);
20065            }
20066        }
20067        return act;
20068    }
20069
20070    final boolean updateOomAdjLocked(ProcessRecord app) {
20071        final ActivityRecord TOP_ACT = resumedAppLocked();
20072        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20073        final boolean wasCached = app.cached;
20074
20075        mAdjSeq++;
20076
20077        // This is the desired cached adjusment we want to tell it to use.
20078        // If our app is currently cached, we know it, and that is it.  Otherwise,
20079        // we don't know it yet, and it needs to now be cached we will then
20080        // need to do a complete oom adj.
20081        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20082                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20083        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20084                SystemClock.uptimeMillis());
20085        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20086            // Changed to/from cached state, so apps after it in the LRU
20087            // list may also be changed.
20088            updateOomAdjLocked();
20089        }
20090        return success;
20091    }
20092
20093    final void updateOomAdjLocked() {
20094        final ActivityRecord TOP_ACT = resumedAppLocked();
20095        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20096        final long now = SystemClock.uptimeMillis();
20097        final long nowElapsed = SystemClock.elapsedRealtime();
20098        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20099        final int N = mLruProcesses.size();
20100
20101        if (false) {
20102            RuntimeException e = new RuntimeException();
20103            e.fillInStackTrace();
20104            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20105        }
20106
20107        // Reset state in all uid records.
20108        for (int i=mActiveUids.size()-1; i>=0; i--) {
20109            final UidRecord uidRec = mActiveUids.valueAt(i);
20110            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20111                    "Starting update of " + uidRec);
20112            uidRec.reset();
20113        }
20114
20115        mStackSupervisor.rankTaskLayersIfNeeded();
20116
20117        mAdjSeq++;
20118        mNewNumServiceProcs = 0;
20119        mNewNumAServiceProcs = 0;
20120
20121        final int emptyProcessLimit;
20122        final int cachedProcessLimit;
20123        if (mProcessLimit <= 0) {
20124            emptyProcessLimit = cachedProcessLimit = 0;
20125        } else if (mProcessLimit == 1) {
20126            emptyProcessLimit = 1;
20127            cachedProcessLimit = 0;
20128        } else {
20129            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20130            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20131        }
20132
20133        // Let's determine how many processes we have running vs.
20134        // how many slots we have for background processes; we may want
20135        // to put multiple processes in a slot of there are enough of
20136        // them.
20137        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20138                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20139        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20140        if (numEmptyProcs > cachedProcessLimit) {
20141            // If there are more empty processes than our limit on cached
20142            // processes, then use the cached process limit for the factor.
20143            // This ensures that the really old empty processes get pushed
20144            // down to the bottom, so if we are running low on memory we will
20145            // have a better chance at keeping around more cached processes
20146            // instead of a gazillion empty processes.
20147            numEmptyProcs = cachedProcessLimit;
20148        }
20149        int emptyFactor = numEmptyProcs/numSlots;
20150        if (emptyFactor < 1) emptyFactor = 1;
20151        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20152        if (cachedFactor < 1) cachedFactor = 1;
20153        int stepCached = 0;
20154        int stepEmpty = 0;
20155        int numCached = 0;
20156        int numEmpty = 0;
20157        int numTrimming = 0;
20158
20159        mNumNonCachedProcs = 0;
20160        mNumCachedHiddenProcs = 0;
20161
20162        // First update the OOM adjustment for each of the
20163        // application processes based on their current state.
20164        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20165        int nextCachedAdj = curCachedAdj+1;
20166        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20167        int nextEmptyAdj = curEmptyAdj+2;
20168        for (int i=N-1; i>=0; i--) {
20169            ProcessRecord app = mLruProcesses.get(i);
20170            if (!app.killedByAm && app.thread != null) {
20171                app.procStateChanged = false;
20172                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20173
20174                // If we haven't yet assigned the final cached adj
20175                // to the process, do that now.
20176                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20177                    switch (app.curProcState) {
20178                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20179                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20180                            // This process is a cached process holding activities...
20181                            // assign it the next cached value for that type, and then
20182                            // step that cached level.
20183                            app.curRawAdj = curCachedAdj;
20184                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20185                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20186                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20187                                    + ")");
20188                            if (curCachedAdj != nextCachedAdj) {
20189                                stepCached++;
20190                                if (stepCached >= cachedFactor) {
20191                                    stepCached = 0;
20192                                    curCachedAdj = nextCachedAdj;
20193                                    nextCachedAdj += 2;
20194                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20195                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20196                                    }
20197                                }
20198                            }
20199                            break;
20200                        default:
20201                            // For everything else, assign next empty cached process
20202                            // level and bump that up.  Note that this means that
20203                            // long-running services that have dropped down to the
20204                            // cached level will be treated as empty (since their process
20205                            // state is still as a service), which is what we want.
20206                            app.curRawAdj = curEmptyAdj;
20207                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20208                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20209                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20210                                    + ")");
20211                            if (curEmptyAdj != nextEmptyAdj) {
20212                                stepEmpty++;
20213                                if (stepEmpty >= emptyFactor) {
20214                                    stepEmpty = 0;
20215                                    curEmptyAdj = nextEmptyAdj;
20216                                    nextEmptyAdj += 2;
20217                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20218                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20219                                    }
20220                                }
20221                            }
20222                            break;
20223                    }
20224                }
20225
20226                applyOomAdjLocked(app, true, now, nowElapsed);
20227
20228                // Count the number of process types.
20229                switch (app.curProcState) {
20230                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20231                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20232                        mNumCachedHiddenProcs++;
20233                        numCached++;
20234                        if (numCached > cachedProcessLimit) {
20235                            app.kill("cached #" + numCached, true);
20236                        }
20237                        break;
20238                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20239                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20240                                && app.lastActivityTime < oldTime) {
20241                            app.kill("empty for "
20242                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20243                                    / 1000) + "s", true);
20244                        } else {
20245                            numEmpty++;
20246                            if (numEmpty > emptyProcessLimit) {
20247                                app.kill("empty #" + numEmpty, true);
20248                            }
20249                        }
20250                        break;
20251                    default:
20252                        mNumNonCachedProcs++;
20253                        break;
20254                }
20255
20256                if (app.isolated && app.services.size() <= 0) {
20257                    // If this is an isolated process, and there are no
20258                    // services running in it, then the process is no longer
20259                    // needed.  We agressively kill these because we can by
20260                    // definition not re-use the same process again, and it is
20261                    // good to avoid having whatever code was running in them
20262                    // left sitting around after no longer needed.
20263                    app.kill("isolated not needed", true);
20264                } else {
20265                    // Keeping this process, update its uid.
20266                    final UidRecord uidRec = app.uidRecord;
20267                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20268                        uidRec.curProcState = app.curProcState;
20269                    }
20270                }
20271
20272                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20273                        && !app.killedByAm) {
20274                    numTrimming++;
20275                }
20276            }
20277        }
20278
20279        mNumServiceProcs = mNewNumServiceProcs;
20280
20281        // Now determine the memory trimming level of background processes.
20282        // Unfortunately we need to start at the back of the list to do this
20283        // properly.  We only do this if the number of background apps we
20284        // are managing to keep around is less than half the maximum we desire;
20285        // if we are keeping a good number around, we'll let them use whatever
20286        // memory they want.
20287        final int numCachedAndEmpty = numCached + numEmpty;
20288        int memFactor;
20289        if (numCached <= ProcessList.TRIM_CACHED_APPS
20290                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20291            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20292                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20293            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20294                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20295            } else {
20296                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20297            }
20298        } else {
20299            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20300        }
20301        // We always allow the memory level to go up (better).  We only allow it to go
20302        // down if we are in a state where that is allowed, *and* the total number of processes
20303        // has gone down since last time.
20304        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20305                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20306                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20307        if (memFactor > mLastMemoryLevel) {
20308            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20309                memFactor = mLastMemoryLevel;
20310                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20311            }
20312        }
20313        if (memFactor != mLastMemoryLevel) {
20314            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20315        }
20316        mLastMemoryLevel = memFactor;
20317        mLastNumProcesses = mLruProcesses.size();
20318        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20319        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20320        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20321            if (mLowRamStartTime == 0) {
20322                mLowRamStartTime = now;
20323            }
20324            int step = 0;
20325            int fgTrimLevel;
20326            switch (memFactor) {
20327                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20328                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20329                    break;
20330                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20331                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20332                    break;
20333                default:
20334                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20335                    break;
20336            }
20337            int factor = numTrimming/3;
20338            int minFactor = 2;
20339            if (mHomeProcess != null) minFactor++;
20340            if (mPreviousProcess != null) minFactor++;
20341            if (factor < minFactor) factor = minFactor;
20342            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20343            for (int i=N-1; i>=0; i--) {
20344                ProcessRecord app = mLruProcesses.get(i);
20345                if (allChanged || app.procStateChanged) {
20346                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20347                    app.procStateChanged = false;
20348                }
20349                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20350                        && !app.killedByAm) {
20351                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20352                        try {
20353                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20354                                    "Trimming memory of " + app.processName + " to " + curLevel);
20355                            app.thread.scheduleTrimMemory(curLevel);
20356                        } catch (RemoteException e) {
20357                        }
20358                        if (false) {
20359                            // For now we won't do this; our memory trimming seems
20360                            // to be good enough at this point that destroying
20361                            // activities causes more harm than good.
20362                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20363                                    && app != mHomeProcess && app != mPreviousProcess) {
20364                                // Need to do this on its own message because the stack may not
20365                                // be in a consistent state at this point.
20366                                // For these apps we will also finish their activities
20367                                // to help them free memory.
20368                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20369                            }
20370                        }
20371                    }
20372                    app.trimMemoryLevel = curLevel;
20373                    step++;
20374                    if (step >= factor) {
20375                        step = 0;
20376                        switch (curLevel) {
20377                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20378                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20379                                break;
20380                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20381                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20382                                break;
20383                        }
20384                    }
20385                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20386                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20387                            && app.thread != null) {
20388                        try {
20389                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20390                                    "Trimming memory of heavy-weight " + app.processName
20391                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20392                            app.thread.scheduleTrimMemory(
20393                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20394                        } catch (RemoteException e) {
20395                        }
20396                    }
20397                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20398                } else {
20399                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20400                            || app.systemNoUi) && app.pendingUiClean) {
20401                        // If this application is now in the background and it
20402                        // had done UI, then give it the special trim level to
20403                        // have it free UI resources.
20404                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20405                        if (app.trimMemoryLevel < level && app.thread != null) {
20406                            try {
20407                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20408                                        "Trimming memory of bg-ui " + app.processName
20409                                        + " to " + level);
20410                                app.thread.scheduleTrimMemory(level);
20411                            } catch (RemoteException e) {
20412                            }
20413                        }
20414                        app.pendingUiClean = false;
20415                    }
20416                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20417                        try {
20418                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20419                                    "Trimming memory of fg " + app.processName
20420                                    + " to " + fgTrimLevel);
20421                            app.thread.scheduleTrimMemory(fgTrimLevel);
20422                        } catch (RemoteException e) {
20423                        }
20424                    }
20425                    app.trimMemoryLevel = fgTrimLevel;
20426                }
20427            }
20428        } else {
20429            if (mLowRamStartTime != 0) {
20430                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20431                mLowRamStartTime = 0;
20432            }
20433            for (int i=N-1; i>=0; i--) {
20434                ProcessRecord app = mLruProcesses.get(i);
20435                if (allChanged || app.procStateChanged) {
20436                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20437                    app.procStateChanged = false;
20438                }
20439                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20440                        || app.systemNoUi) && app.pendingUiClean) {
20441                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20442                            && app.thread != null) {
20443                        try {
20444                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20445                                    "Trimming memory of ui hidden " + app.processName
20446                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20447                            app.thread.scheduleTrimMemory(
20448                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20449                        } catch (RemoteException e) {
20450                        }
20451                    }
20452                    app.pendingUiClean = false;
20453                }
20454                app.trimMemoryLevel = 0;
20455            }
20456        }
20457
20458        if (mAlwaysFinishActivities) {
20459            // Need to do this on its own message because the stack may not
20460            // be in a consistent state at this point.
20461            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20462        }
20463
20464        if (allChanged) {
20465            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20466        }
20467
20468        // Update from any uid changes.
20469        for (int i=mActiveUids.size()-1; i>=0; i--) {
20470            final UidRecord uidRec = mActiveUids.valueAt(i);
20471            int uidChange = UidRecord.CHANGE_PROCSTATE;
20472            if (uidRec.setProcState != uidRec.curProcState) {
20473                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20474                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20475                        + " to " + uidRec.curProcState);
20476                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20477                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20478                        uidRec.lastBackgroundTime = nowElapsed;
20479                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20480                            // Note: the background settle time is in elapsed realtime, while
20481                            // the handler time base is uptime.  All this means is that we may
20482                            // stop background uids later than we had intended, but that only
20483                            // happens because the device was sleeping so we are okay anyway.
20484                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20485                        }
20486                    }
20487                } else {
20488                    if (uidRec.idle) {
20489                        uidChange = UidRecord.CHANGE_ACTIVE;
20490                        uidRec.idle = false;
20491                    }
20492                    uidRec.lastBackgroundTime = 0;
20493                }
20494                uidRec.setProcState = uidRec.curProcState;
20495                enqueueUidChangeLocked(uidRec, -1, uidChange);
20496                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20497            }
20498        }
20499
20500        if (mProcessStats.shouldWriteNowLocked(now)) {
20501            mHandler.post(new Runnable() {
20502                @Override public void run() {
20503                    synchronized (ActivityManagerService.this) {
20504                        mProcessStats.writeStateAsyncLocked();
20505                    }
20506                }
20507            });
20508        }
20509
20510        if (DEBUG_OOM_ADJ) {
20511            final long duration = SystemClock.uptimeMillis() - now;
20512            if (false) {
20513                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20514                        new RuntimeException("here").fillInStackTrace());
20515            } else {
20516                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20517            }
20518        }
20519    }
20520
20521    final void idleUids() {
20522        synchronized (this) {
20523            final long nowElapsed = SystemClock.elapsedRealtime();
20524            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20525            long nextTime = 0;
20526            for (int i=mActiveUids.size()-1; i>=0; i--) {
20527                final UidRecord uidRec = mActiveUids.valueAt(i);
20528                final long bgTime = uidRec.lastBackgroundTime;
20529                if (bgTime > 0 && !uidRec.idle) {
20530                    if (bgTime <= maxBgTime) {
20531                        uidRec.idle = true;
20532                        doStopUidLocked(uidRec.uid, uidRec);
20533                    } else {
20534                        if (nextTime == 0 || nextTime > bgTime) {
20535                            nextTime = bgTime;
20536                        }
20537                    }
20538                }
20539            }
20540            if (nextTime > 0) {
20541                mHandler.removeMessages(IDLE_UIDS_MSG);
20542                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20543                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20544            }
20545        }
20546    }
20547
20548    final void runInBackgroundDisabled(int uid) {
20549        synchronized (this) {
20550            UidRecord uidRec = mActiveUids.get(uid);
20551            if (uidRec != null) {
20552                // This uid is actually running...  should it be considered background now?
20553                if (uidRec.idle) {
20554                    doStopUidLocked(uidRec.uid, uidRec);
20555                }
20556            } else {
20557                // This uid isn't actually running...  still send a report about it being "stopped".
20558                doStopUidLocked(uid, null);
20559            }
20560        }
20561    }
20562
20563    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20564        mServices.stopInBackgroundLocked(uid);
20565        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20566    }
20567
20568    final void trimApplications() {
20569        synchronized (this) {
20570            int i;
20571
20572            // First remove any unused application processes whose package
20573            // has been removed.
20574            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20575                final ProcessRecord app = mRemovedProcesses.get(i);
20576                if (app.activities.size() == 0
20577                        && app.curReceiver == null && app.services.size() == 0) {
20578                    Slog.i(
20579                        TAG, "Exiting empty application process "
20580                        + app.toShortString() + " ("
20581                        + (app.thread != null ? app.thread.asBinder() : null)
20582                        + ")\n");
20583                    if (app.pid > 0 && app.pid != MY_PID) {
20584                        app.kill("empty", false);
20585                    } else {
20586                        try {
20587                            app.thread.scheduleExit();
20588                        } catch (Exception e) {
20589                            // Ignore exceptions.
20590                        }
20591                    }
20592                    cleanUpApplicationRecordLocked(app, false, true, -1);
20593                    mRemovedProcesses.remove(i);
20594
20595                    if (app.persistent) {
20596                        addAppLocked(app.info, false, null /* ABI override */);
20597                    }
20598                }
20599            }
20600
20601            // Now update the oom adj for all processes.
20602            updateOomAdjLocked();
20603        }
20604    }
20605
20606    /** This method sends the specified signal to each of the persistent apps */
20607    public void signalPersistentProcesses(int sig) throws RemoteException {
20608        if (sig != Process.SIGNAL_USR1) {
20609            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20610        }
20611
20612        synchronized (this) {
20613            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20614                    != PackageManager.PERMISSION_GRANTED) {
20615                throw new SecurityException("Requires permission "
20616                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20617            }
20618
20619            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20620                ProcessRecord r = mLruProcesses.get(i);
20621                if (r.thread != null && r.persistent) {
20622                    Process.sendSignal(r.pid, sig);
20623                }
20624            }
20625        }
20626    }
20627
20628    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20629        if (proc == null || proc == mProfileProc) {
20630            proc = mProfileProc;
20631            profileType = mProfileType;
20632            clearProfilerLocked();
20633        }
20634        if (proc == null) {
20635            return;
20636        }
20637        try {
20638            proc.thread.profilerControl(false, null, profileType);
20639        } catch (RemoteException e) {
20640            throw new IllegalStateException("Process disappeared");
20641        }
20642    }
20643
20644    private void clearProfilerLocked() {
20645        if (mProfileFd != null) {
20646            try {
20647                mProfileFd.close();
20648            } catch (IOException e) {
20649            }
20650        }
20651        mProfileApp = null;
20652        mProfileProc = null;
20653        mProfileFile = null;
20654        mProfileType = 0;
20655        mAutoStopProfiler = false;
20656        mSamplingInterval = 0;
20657    }
20658
20659    public boolean profileControl(String process, int userId, boolean start,
20660            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20661
20662        try {
20663            synchronized (this) {
20664                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20665                // its own permission.
20666                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20667                        != PackageManager.PERMISSION_GRANTED) {
20668                    throw new SecurityException("Requires permission "
20669                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20670                }
20671
20672                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20673                    throw new IllegalArgumentException("null profile info or fd");
20674                }
20675
20676                ProcessRecord proc = null;
20677                if (process != null) {
20678                    proc = findProcessLocked(process, userId, "profileControl");
20679                }
20680
20681                if (start && (proc == null || proc.thread == null)) {
20682                    throw new IllegalArgumentException("Unknown process: " + process);
20683                }
20684
20685                if (start) {
20686                    stopProfilerLocked(null, 0);
20687                    setProfileApp(proc.info, proc.processName, profilerInfo);
20688                    mProfileProc = proc;
20689                    mProfileType = profileType;
20690                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20691                    try {
20692                        fd = fd.dup();
20693                    } catch (IOException e) {
20694                        fd = null;
20695                    }
20696                    profilerInfo.profileFd = fd;
20697                    proc.thread.profilerControl(start, profilerInfo, profileType);
20698                    fd = null;
20699                    mProfileFd = null;
20700                } else {
20701                    stopProfilerLocked(proc, profileType);
20702                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20703                        try {
20704                            profilerInfo.profileFd.close();
20705                        } catch (IOException e) {
20706                        }
20707                    }
20708                }
20709
20710                return true;
20711            }
20712        } catch (RemoteException e) {
20713            throw new IllegalStateException("Process disappeared");
20714        } finally {
20715            if (profilerInfo != null && profilerInfo.profileFd != null) {
20716                try {
20717                    profilerInfo.profileFd.close();
20718                } catch (IOException e) {
20719                }
20720            }
20721        }
20722    }
20723
20724    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20725        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20726                userId, true, ALLOW_FULL_ONLY, callName, null);
20727        ProcessRecord proc = null;
20728        try {
20729            int pid = Integer.parseInt(process);
20730            synchronized (mPidsSelfLocked) {
20731                proc = mPidsSelfLocked.get(pid);
20732            }
20733        } catch (NumberFormatException e) {
20734        }
20735
20736        if (proc == null) {
20737            ArrayMap<String, SparseArray<ProcessRecord>> all
20738                    = mProcessNames.getMap();
20739            SparseArray<ProcessRecord> procs = all.get(process);
20740            if (procs != null && procs.size() > 0) {
20741                proc = procs.valueAt(0);
20742                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20743                    for (int i=1; i<procs.size(); i++) {
20744                        ProcessRecord thisProc = procs.valueAt(i);
20745                        if (thisProc.userId == userId) {
20746                            proc = thisProc;
20747                            break;
20748                        }
20749                    }
20750                }
20751            }
20752        }
20753
20754        return proc;
20755    }
20756
20757    public boolean dumpHeap(String process, int userId, boolean managed,
20758            String path, ParcelFileDescriptor fd) throws RemoteException {
20759
20760        try {
20761            synchronized (this) {
20762                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20763                // its own permission (same as profileControl).
20764                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20765                        != PackageManager.PERMISSION_GRANTED) {
20766                    throw new SecurityException("Requires permission "
20767                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20768                }
20769
20770                if (fd == null) {
20771                    throw new IllegalArgumentException("null fd");
20772                }
20773
20774                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20775                if (proc == null || proc.thread == null) {
20776                    throw new IllegalArgumentException("Unknown process: " + process);
20777                }
20778
20779                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20780                if (!isDebuggable) {
20781                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20782                        throw new SecurityException("Process not debuggable: " + proc);
20783                    }
20784                }
20785
20786                proc.thread.dumpHeap(managed, path, fd);
20787                fd = null;
20788                return true;
20789            }
20790        } catch (RemoteException e) {
20791            throw new IllegalStateException("Process disappeared");
20792        } finally {
20793            if (fd != null) {
20794                try {
20795                    fd.close();
20796                } catch (IOException e) {
20797                }
20798            }
20799        }
20800    }
20801
20802    @Override
20803    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20804            String reportPackage) {
20805        if (processName != null) {
20806            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20807                    "setDumpHeapDebugLimit()");
20808        } else {
20809            synchronized (mPidsSelfLocked) {
20810                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20811                if (proc == null) {
20812                    throw new SecurityException("No process found for calling pid "
20813                            + Binder.getCallingPid());
20814                }
20815                if (!Build.IS_DEBUGGABLE
20816                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20817                    throw new SecurityException("Not running a debuggable build");
20818                }
20819                processName = proc.processName;
20820                uid = proc.uid;
20821                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20822                    throw new SecurityException("Package " + reportPackage + " is not running in "
20823                            + proc);
20824                }
20825            }
20826        }
20827        synchronized (this) {
20828            if (maxMemSize > 0) {
20829                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20830            } else {
20831                if (uid != 0) {
20832                    mMemWatchProcesses.remove(processName, uid);
20833                } else {
20834                    mMemWatchProcesses.getMap().remove(processName);
20835                }
20836            }
20837        }
20838    }
20839
20840    @Override
20841    public void dumpHeapFinished(String path) {
20842        synchronized (this) {
20843            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20844                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20845                        + " does not match last pid " + mMemWatchDumpPid);
20846                return;
20847            }
20848            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20849                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20850                        + " does not match last path " + mMemWatchDumpFile);
20851                return;
20852            }
20853            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20854            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20855        }
20856    }
20857
20858    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20859    public void monitor() {
20860        synchronized (this) { }
20861    }
20862
20863    void onCoreSettingsChange(Bundle settings) {
20864        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20865            ProcessRecord processRecord = mLruProcesses.get(i);
20866            try {
20867                if (processRecord.thread != null) {
20868                    processRecord.thread.setCoreSettings(settings);
20869                }
20870            } catch (RemoteException re) {
20871                /* ignore */
20872            }
20873        }
20874    }
20875
20876    // Multi-user methods
20877
20878    /**
20879     * Start user, if its not already running, but don't bring it to foreground.
20880     */
20881    @Override
20882    public boolean startUserInBackground(final int userId) {
20883        return mUserController.startUser(userId, /* foreground */ false);
20884    }
20885
20886    @Override
20887    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20888        return mUserController.unlockUser(userId, token, secret, listener);
20889    }
20890
20891    @Override
20892    public boolean switchUser(final int targetUserId) {
20893        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20894        UserInfo currentUserInfo;
20895        UserInfo targetUserInfo;
20896        synchronized (this) {
20897            int currentUserId = mUserController.getCurrentUserIdLocked();
20898            currentUserInfo = mUserController.getUserInfo(currentUserId);
20899            targetUserInfo = mUserController.getUserInfo(targetUserId);
20900            if (targetUserInfo == null) {
20901                Slog.w(TAG, "No user info for user #" + targetUserId);
20902                return false;
20903            }
20904            if (!targetUserInfo.supportsSwitchTo()) {
20905                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20906                return false;
20907            }
20908            if (targetUserInfo.isManagedProfile()) {
20909                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20910                return false;
20911            }
20912            mUserController.setTargetUserIdLocked(targetUserId);
20913        }
20914        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20915        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20916        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20917        return true;
20918    }
20919
20920    void scheduleStartProfilesLocked() {
20921        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20922            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20923                    DateUtils.SECOND_IN_MILLIS);
20924        }
20925    }
20926
20927    @Override
20928    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20929        return mUserController.stopUser(userId, force, callback);
20930    }
20931
20932    @Override
20933    public UserInfo getCurrentUser() {
20934        return mUserController.getCurrentUser();
20935    }
20936
20937    @Override
20938    public boolean isUserRunning(int userId, int flags) {
20939        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20940                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20941            String msg = "Permission Denial: isUserRunning() from pid="
20942                    + Binder.getCallingPid()
20943                    + ", uid=" + Binder.getCallingUid()
20944                    + " requires " + INTERACT_ACROSS_USERS;
20945            Slog.w(TAG, msg);
20946            throw new SecurityException(msg);
20947        }
20948        synchronized (this) {
20949            return mUserController.isUserRunningLocked(userId, flags);
20950        }
20951    }
20952
20953    @Override
20954    public int[] getRunningUserIds() {
20955        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20956                != PackageManager.PERMISSION_GRANTED) {
20957            String msg = "Permission Denial: isUserRunning() from pid="
20958                    + Binder.getCallingPid()
20959                    + ", uid=" + Binder.getCallingUid()
20960                    + " requires " + INTERACT_ACROSS_USERS;
20961            Slog.w(TAG, msg);
20962            throw new SecurityException(msg);
20963        }
20964        synchronized (this) {
20965            return mUserController.getStartedUserArrayLocked();
20966        }
20967    }
20968
20969    @Override
20970    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20971        mUserController.registerUserSwitchObserver(observer);
20972    }
20973
20974    @Override
20975    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20976        mUserController.unregisterUserSwitchObserver(observer);
20977    }
20978
20979    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20980        if (info == null) return null;
20981        ApplicationInfo newInfo = new ApplicationInfo(info);
20982        newInfo.initForUser(userId);
20983        return newInfo;
20984    }
20985
20986    public boolean isUserStopped(int userId) {
20987        synchronized (this) {
20988            return mUserController.getStartedUserStateLocked(userId) == null;
20989        }
20990    }
20991
20992    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20993        if (aInfo == null
20994                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20995            return aInfo;
20996        }
20997
20998        ActivityInfo info = new ActivityInfo(aInfo);
20999        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21000        return info;
21001    }
21002
21003    private boolean processSanityChecksLocked(ProcessRecord process) {
21004        if (process == null || process.thread == null) {
21005            return false;
21006        }
21007
21008        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21009        if (!isDebuggable) {
21010            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21011                return false;
21012            }
21013        }
21014
21015        return true;
21016    }
21017
21018    public boolean startBinderTracking() throws RemoteException {
21019        synchronized (this) {
21020            mBinderTransactionTrackingEnabled = true;
21021            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21022            // permission (same as profileControl).
21023            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21024                    != PackageManager.PERMISSION_GRANTED) {
21025                throw new SecurityException("Requires permission "
21026                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21027            }
21028
21029            for (int i = 0; i < mLruProcesses.size(); i++) {
21030                ProcessRecord process = mLruProcesses.get(i);
21031                if (!processSanityChecksLocked(process)) {
21032                    continue;
21033                }
21034                try {
21035                    process.thread.startBinderTracking();
21036                } catch (RemoteException e) {
21037                    Log.v(TAG, "Process disappared");
21038                }
21039            }
21040            return true;
21041        }
21042    }
21043
21044    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21045        try {
21046            synchronized (this) {
21047                mBinderTransactionTrackingEnabled = false;
21048                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21049                // permission (same as profileControl).
21050                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21051                        != PackageManager.PERMISSION_GRANTED) {
21052                    throw new SecurityException("Requires permission "
21053                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21054                }
21055
21056                if (fd == null) {
21057                    throw new IllegalArgumentException("null fd");
21058                }
21059
21060                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21061                pw.println("Binder transaction traces for all processes.\n");
21062                for (ProcessRecord process : mLruProcesses) {
21063                    if (!processSanityChecksLocked(process)) {
21064                        continue;
21065                    }
21066
21067                    pw.println("Traces for process: " + process.processName);
21068                    pw.flush();
21069                    try {
21070                        TransferPipe tp = new TransferPipe();
21071                        try {
21072                            process.thread.stopBinderTrackingAndDump(
21073                                    tp.getWriteFd().getFileDescriptor());
21074                            tp.go(fd.getFileDescriptor());
21075                        } finally {
21076                            tp.kill();
21077                        }
21078                    } catch (IOException e) {
21079                        pw.println("Failure while dumping IPC traces from " + process +
21080                                ".  Exception: " + e);
21081                        pw.flush();
21082                    } catch (RemoteException e) {
21083                        pw.println("Got a RemoteException while dumping IPC traces from " +
21084                                process + ".  Exception: " + e);
21085                        pw.flush();
21086                    }
21087                }
21088                fd = null;
21089                return true;
21090            }
21091        } finally {
21092            if (fd != null) {
21093                try {
21094                    fd.close();
21095                } catch (IOException e) {
21096                }
21097            }
21098        }
21099    }
21100
21101    private final class LocalService extends ActivityManagerInternal {
21102        @Override
21103        public void onWakefulnessChanged(int wakefulness) {
21104            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21105        }
21106
21107        @Override
21108        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21109                String processName, String abiOverride, int uid, Runnable crashHandler) {
21110            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21111                    processName, abiOverride, uid, crashHandler);
21112        }
21113
21114        @Override
21115        public SleepToken acquireSleepToken(String tag) {
21116            Preconditions.checkNotNull(tag);
21117
21118            synchronized (ActivityManagerService.this) {
21119                SleepTokenImpl token = new SleepTokenImpl(tag);
21120                mSleepTokens.add(token);
21121                updateSleepIfNeededLocked();
21122                applyVrModeIfNeededLocked(mFocusedActivity, false);
21123                return token;
21124            }
21125        }
21126
21127        @Override
21128        public ComponentName getHomeActivityForUser(int userId) {
21129            synchronized (ActivityManagerService.this) {
21130                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21131                return homeActivity == null ? null : homeActivity.realActivity;
21132            }
21133        }
21134
21135        @Override
21136        public void onUserRemoved(int userId) {
21137            synchronized (ActivityManagerService.this) {
21138                ActivityManagerService.this.onUserStoppedLocked(userId);
21139            }
21140        }
21141
21142        @Override
21143        public void onLocalVoiceInteractionStarted(IBinder activity,
21144                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21145            synchronized (ActivityManagerService.this) {
21146                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21147                        voiceSession, voiceInteractor);
21148            }
21149        }
21150
21151        @Override
21152        public void notifyStartingWindowDrawn() {
21153            synchronized (ActivityManagerService.this) {
21154                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21155            }
21156        }
21157
21158        @Override
21159        public void notifyAppTransitionStarting(int reason) {
21160            synchronized (ActivityManagerService.this) {
21161                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21162            }
21163        }
21164
21165        @Override
21166        public void notifyAppTransitionFinished() {
21167            synchronized (ActivityManagerService.this) {
21168                mStackSupervisor.notifyAppTransitionDone();
21169            }
21170        }
21171
21172        @Override
21173        public void notifyAppTransitionCancelled() {
21174            synchronized (ActivityManagerService.this) {
21175                mStackSupervisor.notifyAppTransitionDone();
21176            }
21177        }
21178
21179        @Override
21180        public List<IBinder> getTopVisibleActivities() {
21181            synchronized (ActivityManagerService.this) {
21182                return mStackSupervisor.getTopVisibleActivities();
21183            }
21184        }
21185
21186        @Override
21187        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21188            synchronized (ActivityManagerService.this) {
21189                mStackSupervisor.setDockedStackMinimized(minimized);
21190            }
21191        }
21192
21193        @Override
21194        public void killForegroundAppsForUser(int userHandle) {
21195            synchronized (ActivityManagerService.this) {
21196                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21197                final int NP = mProcessNames.getMap().size();
21198                for (int ip = 0; ip < NP; ip++) {
21199                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21200                    final int NA = apps.size();
21201                    for (int ia = 0; ia < NA; ia++) {
21202                        final ProcessRecord app = apps.valueAt(ia);
21203                        if (app.persistent) {
21204                            // We don't kill persistent processes.
21205                            continue;
21206                        }
21207                        if (app.removed) {
21208                            procs.add(app);
21209                        } else if (app.userId == userHandle && app.foregroundActivities) {
21210                            app.removed = true;
21211                            procs.add(app);
21212                        }
21213                    }
21214                }
21215
21216                final int N = procs.size();
21217                for (int i = 0; i < N; i++) {
21218                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21219                }
21220            }
21221        }
21222    }
21223
21224    private final class SleepTokenImpl extends SleepToken {
21225        private final String mTag;
21226        private final long mAcquireTime;
21227
21228        public SleepTokenImpl(String tag) {
21229            mTag = tag;
21230            mAcquireTime = SystemClock.uptimeMillis();
21231        }
21232
21233        @Override
21234        public void release() {
21235            synchronized (ActivityManagerService.this) {
21236                if (mSleepTokens.remove(this)) {
21237                    updateSleepIfNeededLocked();
21238                }
21239            }
21240        }
21241
21242        @Override
21243        public String toString() {
21244            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21245        }
21246    }
21247
21248    /**
21249     * An implementation of IAppTask, that allows an app to manage its own tasks via
21250     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21251     * only the process that calls getAppTasks() can call the AppTask methods.
21252     */
21253    class AppTaskImpl extends IAppTask.Stub {
21254        private int mTaskId;
21255        private int mCallingUid;
21256
21257        public AppTaskImpl(int taskId, int callingUid) {
21258            mTaskId = taskId;
21259            mCallingUid = callingUid;
21260        }
21261
21262        private void checkCaller() {
21263            if (mCallingUid != Binder.getCallingUid()) {
21264                throw new SecurityException("Caller " + mCallingUid
21265                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21266            }
21267        }
21268
21269        @Override
21270        public void finishAndRemoveTask() {
21271            checkCaller();
21272
21273            synchronized (ActivityManagerService.this) {
21274                long origId = Binder.clearCallingIdentity();
21275                try {
21276                    // We remove the task from recents to preserve backwards
21277                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21278                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21279                    }
21280                } finally {
21281                    Binder.restoreCallingIdentity(origId);
21282                }
21283            }
21284        }
21285
21286        @Override
21287        public ActivityManager.RecentTaskInfo getTaskInfo() {
21288            checkCaller();
21289
21290            synchronized (ActivityManagerService.this) {
21291                long origId = Binder.clearCallingIdentity();
21292                try {
21293                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21294                    if (tr == null) {
21295                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21296                    }
21297                    return createRecentTaskInfoFromTaskRecord(tr);
21298                } finally {
21299                    Binder.restoreCallingIdentity(origId);
21300                }
21301            }
21302        }
21303
21304        @Override
21305        public void moveToFront() {
21306            checkCaller();
21307            // Will bring task to front if it already has a root activity.
21308            final long origId = Binder.clearCallingIdentity();
21309            try {
21310                synchronized (this) {
21311                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21312                }
21313            } finally {
21314                Binder.restoreCallingIdentity(origId);
21315            }
21316        }
21317
21318        @Override
21319        public int startActivity(IBinder whoThread, String callingPackage,
21320                Intent intent, String resolvedType, Bundle bOptions) {
21321            checkCaller();
21322
21323            int callingUser = UserHandle.getCallingUserId();
21324            TaskRecord tr;
21325            IApplicationThread appThread;
21326            synchronized (ActivityManagerService.this) {
21327                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21328                if (tr == null) {
21329                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21330                }
21331                appThread = ApplicationThreadNative.asInterface(whoThread);
21332                if (appThread == null) {
21333                    throw new IllegalArgumentException("Bad app thread " + appThread);
21334                }
21335            }
21336            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21337                    resolvedType, null, null, null, null, 0, 0, null, null,
21338                    null, bOptions, false, callingUser, null, tr);
21339        }
21340
21341        @Override
21342        public void setExcludeFromRecents(boolean exclude) {
21343            checkCaller();
21344
21345            synchronized (ActivityManagerService.this) {
21346                long origId = Binder.clearCallingIdentity();
21347                try {
21348                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21349                    if (tr == null) {
21350                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21351                    }
21352                    Intent intent = tr.getBaseIntent();
21353                    if (exclude) {
21354                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21355                    } else {
21356                        intent.setFlags(intent.getFlags()
21357                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21358                    }
21359                } finally {
21360                    Binder.restoreCallingIdentity(origId);
21361                }
21362            }
21363        }
21364    }
21365
21366    /**
21367     * Kill processes for the user with id userId and that depend on the package named packageName
21368     */
21369    @Override
21370    public void killPackageDependents(String packageName, int userId) {
21371        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21372        if (packageName == null) {
21373            throw new NullPointerException(
21374                    "Cannot kill the dependents of a package without its name.");
21375        }
21376
21377        long callingId = Binder.clearCallingIdentity();
21378        IPackageManager pm = AppGlobals.getPackageManager();
21379        int pkgUid = -1;
21380        try {
21381            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21382        } catch (RemoteException e) {
21383        }
21384        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21385            throw new IllegalArgumentException(
21386                    "Cannot kill dependents of non-existing package " + packageName);
21387        }
21388        try {
21389            synchronized(this) {
21390                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21391                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21392                        "dep: " + packageName);
21393            }
21394        } finally {
21395            Binder.restoreCallingIdentity(callingId);
21396        }
21397    }
21398}
21399