ActivityManagerService.java revision 0c4e6a8da3405f742e5cef8afdf579d58b6f1246
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.google.android.collect.Lists;
20import com.google.android.collect.Maps;
21import com.android.internal.R;
22import com.android.internal.annotations.GuardedBy;
23import com.android.internal.app.AssistUtils;
24import com.android.internal.app.DumpHeapActivity;
25import com.android.internal.app.IAppOpsCallback;
26import com.android.internal.app.IAppOpsService;
27import com.android.internal.app.IVoiceInteractor;
28import com.android.internal.app.ProcessMap;
29import com.android.internal.app.SystemUserHomeActivity;
30import com.android.internal.app.procstats.ProcessStats;
31import com.android.internal.os.BackgroundThread;
32import com.android.internal.os.BatteryStatsImpl;
33import com.android.internal.os.IResultReceiver;
34import com.android.internal.os.ProcessCpuTracker;
35import com.android.internal.os.TransferPipe;
36import com.android.internal.os.Zygote;
37import com.android.internal.os.InstallerConnection.InstallerException;
38import com.android.internal.util.ArrayUtils;
39import com.android.internal.util.FastPrintWriter;
40import com.android.internal.util.FastXmlSerializer;
41import com.android.internal.util.MemInfoReader;
42import com.android.internal.util.Preconditions;
43import com.android.internal.util.ProgressReporter;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.KeyguardManager;
101import android.app.Notification;
102import android.app.NotificationManager;
103import android.app.PendingIntent;
104import android.app.ProfilerInfo;
105import android.app.admin.DevicePolicyManager;
106import android.app.admin.DevicePolicyManagerInternal;
107import android.app.assist.AssistContent;
108import android.app.assist.AssistStructure;
109import android.app.backup.IBackupManager;
110import android.app.usage.UsageEvents;
111import android.app.usage.UsageStatsManagerInternal;
112import android.appwidget.AppWidgetManager;
113import android.content.ActivityNotFoundException;
114import android.content.BroadcastReceiver;
115import android.content.ClipData;
116import android.content.ComponentCallbacks2;
117import android.content.ComponentName;
118import android.content.ContentProvider;
119import android.content.ContentResolver;
120import android.content.Context;
121import android.content.DialogInterface;
122import android.content.IContentProvider;
123import android.content.IIntentReceiver;
124import android.content.IIntentSender;
125import android.content.Intent;
126import android.content.IntentFilter;
127import android.content.IntentSender;
128import android.content.pm.ActivityInfo;
129import android.content.pm.ApplicationInfo;
130import android.content.pm.ConfigurationInfo;
131import android.content.pm.IPackageDataObserver;
132import android.content.pm.IPackageManager;
133import android.content.pm.InstrumentationInfo;
134import android.content.pm.PackageInfo;
135import android.content.pm.PackageManager;
136import android.content.pm.PackageManager.NameNotFoundException;
137import android.content.pm.PackageManagerInternal;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.PathPermission;
140import android.content.pm.PermissionInfo;
141import android.content.pm.ProviderInfo;
142import android.content.pm.ResolveInfo;
143import android.content.pm.ServiceInfo;
144import android.content.pm.ShortcutServiceInternal;
145import android.content.pm.UserInfo;
146import android.content.res.CompatibilityInfo;
147import android.content.res.Configuration;
148import android.content.res.Resources;
149import android.database.ContentObserver;
150import android.graphics.Bitmap;
151import android.graphics.Point;
152import android.graphics.Rect;
153import android.location.LocationManager;
154import android.net.Proxy;
155import android.net.ProxyInfo;
156import android.net.Uri;
157import android.os.BatteryStats;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IProcessInfoService;
171import android.os.IProgressListener;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.PersistableBundle;
177import android.os.PowerManager;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.ResultReceiver;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.Trace;
188import android.os.TransactionTooLargeException;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.os.WorkSource;
193import android.os.storage.IMountService;
194import android.os.storage.MountServiceInternal;
195import android.os.storage.StorageManager;
196import android.provider.Settings;
197import android.service.voice.IVoiceInteractionSession;
198import android.service.voice.VoiceInteractionManagerInternal;
199import android.service.voice.VoiceInteractionSession;
200import android.text.format.DateUtils;
201import android.text.format.Time;
202import android.util.ArrayMap;
203import android.util.ArraySet;
204import android.util.AtomicFile;
205import android.util.DebugUtils;
206import android.util.EventLog;
207import android.util.LocaleList;
208import android.util.Log;
209import android.util.Pair;
210import android.util.PrintWriterPrinter;
211import android.util.Slog;
212import android.util.SparseArray;
213import android.util.TimeUtils;
214import android.util.Xml;
215import android.view.Display;
216import android.view.Gravity;
217import android.view.LayoutInflater;
218import android.view.View;
219import android.view.WindowManager;
220
221import java.io.File;
222import java.io.FileDescriptor;
223import java.io.FileInputStream;
224import java.io.FileNotFoundException;
225import java.io.FileOutputStream;
226import java.io.IOException;
227import java.io.InputStreamReader;
228import java.io.PrintWriter;
229import java.io.StringWriter;
230import java.lang.ref.WeakReference;
231import java.nio.charset.StandardCharsets;
232import java.util.ArrayList;
233import java.util.Arrays;
234import java.util.Collections;
235import java.util.Comparator;
236import java.util.HashMap;
237import java.util.HashSet;
238import java.util.Iterator;
239import java.util.List;
240import java.util.Locale;
241import java.util.Map;
242import java.util.Set;
243import java.util.concurrent.atomic.AtomicBoolean;
244import java.util.concurrent.atomic.AtomicLong;
245
246import dalvik.system.VMRuntime;
247
248import libcore.io.IoUtils;
249import libcore.util.EmptyArray;
250
251import static android.Manifest.permission.INTERACT_ACROSS_USERS;
252import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
253import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
254import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
255import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
256import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
257import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
258import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
259import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
260import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.HOME_STACK_ID;
262import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
263import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
264import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
265import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
266import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
267import static android.content.pm.PackageManager.GET_PROVIDERS;
268import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
269import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
270import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
271import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
272import static android.content.pm.PackageManager.PERMISSION_GRANTED;
273import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
274import static android.provider.Settings.Global.DEBUG_APP;
275import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
276import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
277import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
278import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
279import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
280import static android.provider.Settings.System.FONT_SCALE;
281import static com.android.internal.util.XmlUtils.readBooleanAttribute;
282import static com.android.internal.util.XmlUtils.readIntAttribute;
283import static com.android.internal.util.XmlUtils.readLongAttribute;
284import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
285import static com.android.internal.util.XmlUtils.writeIntAttribute;
286import static com.android.internal.util.XmlUtils.writeLongAttribute;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
343import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
344import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
345import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
346import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
347import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
348import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
349import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
350import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
351import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
352import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
353import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
354import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
355import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
356import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
357import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
358import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
359import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
360import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
361import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
362import static org.xmlpull.v1.XmlPullParser.START_TAG;
363
364public final class ActivityManagerService extends ActivityManagerNative
365        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
366
367    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
368    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
369    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
370    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
371    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
372    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
373    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
374    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
375    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
376    private static final String TAG_LRU = TAG + POSTFIX_LRU;
377    private static final String TAG_MU = TAG + POSTFIX_MU;
378    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
379    private static final String TAG_POWER = TAG + POSTFIX_POWER;
380    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
381    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
382    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
383    private static final String TAG_PSS = TAG + POSTFIX_PSS;
384    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
385    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
386    private static final String TAG_STACK = TAG + POSTFIX_STACK;
387    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
388    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
389    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
390    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
391    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
392
393    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
394    // here so that while the job scheduler can depend on AMS, the other way around
395    // need not be the case.
396    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
397
398    /** Control over CPU and battery monitoring */
399    // write battery stats every 30 minutes.
400    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
401    static final boolean MONITOR_CPU_USAGE = true;
402    // don't sample cpu less than every 5 seconds.
403    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
404    // wait possibly forever for next cpu sample.
405    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
406    static final boolean MONITOR_THREAD_CPU_USAGE = false;
407
408    // The flags that are set for all calls we make to the package manager.
409    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
410
411    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
412
413    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
414
415    // Amount of time after a call to stopAppSwitches() during which we will
416    // prevent further untrusted switches from happening.
417    static final long APP_SWITCH_DELAY_TIME = 5*1000;
418
419    // How long we wait for a launched process to attach to the activity manager
420    // before we decide it's never going to come up for real.
421    static final int PROC_START_TIMEOUT = 10*1000;
422    // How long we wait for an attached process to publish its content providers
423    // before we decide it must be hung.
424    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
425
426    // How long we will retain processes hosting content providers in the "last activity"
427    // state before allowing them to drop down to the regular cached LRU list.  This is
428    // to avoid thrashing of provider processes under low memory situations.
429    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
430
431    // How long we wait for a launched process to attach to the activity manager
432    // before we decide it's never going to come up for real, when the process was
433    // started with a wrapper for instrumentation (such as Valgrind) because it
434    // could take much longer than usual.
435    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
436
437    // How long to wait after going idle before forcing apps to GC.
438    static final int GC_TIMEOUT = 5*1000;
439
440    // The minimum amount of time between successive GC requests for a process.
441    static final int GC_MIN_INTERVAL = 60*1000;
442
443    // The minimum amount of time between successive PSS requests for a process.
444    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
445
446    // The minimum amount of time between successive PSS requests for a process
447    // when the request is due to the memory state being lowered.
448    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
449
450    // The rate at which we check for apps using excessive power -- 15 mins.
451    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
452
453    // The minimum sample duration we will allow before deciding we have
454    // enough data on wake locks to start killing things.
455    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
456
457    // The minimum sample duration we will allow before deciding we have
458    // enough data on CPU usage to start killing things.
459    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
460
461    // How long we allow a receiver to run before giving up on it.
462    static final int BROADCAST_FG_TIMEOUT = 10*1000;
463    static final int BROADCAST_BG_TIMEOUT = 60*1000;
464
465    // How long we wait until we timeout on key dispatching.
466    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
467
468    // How long we wait until we timeout on key dispatching during instrumentation.
469    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
470
471    // This is the amount of time an app needs to be running a foreground service before
472    // we will consider it to be doing interaction for usage stats.
473    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
474
475    // Maximum amount of time we will allow to elapse before re-reporting usage stats
476    // interaction with foreground processes.
477    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
478
479    // This is the amount of time we allow an app to settle after it goes into the background,
480    // before we start restricting what it can do.
481    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
482
483    // How long to wait in getAssistContextExtras for the activity and foreground services
484    // to respond with the result.
485    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
486
487    // How long top wait when going through the modern assist (which doesn't need to block
488    // on getting this result before starting to launch its UI).
489    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
490
491    // Maximum number of persisted Uri grants a package is allowed
492    static final int MAX_PERSISTED_URI_GRANTS = 128;
493
494    static final int MY_PID = Process.myPid();
495
496    static final String[] EMPTY_STRING_ARRAY = new String[0];
497
498    // How many bytes to write into the dropbox log before truncating
499    static final int DROPBOX_MAX_SIZE = 256 * 1024;
500
501    // Access modes for handleIncomingUser.
502    static final int ALLOW_NON_FULL = 0;
503    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
504    static final int ALLOW_FULL_ONLY = 2;
505
506    // Delay in notifying task stack change listeners (in millis)
507    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
508
509    // Necessary ApplicationInfo flags to mark an app as persistent
510    private static final int PERSISTENT_MASK =
511            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
512
513    // Intent sent when remote bugreport collection has been completed
514    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
515            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
516
517    // Delay to disable app launch boost
518    static final int APP_BOOST_MESSAGE_DELAY = 3000;
519    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
520    static final int APP_BOOST_TIMEOUT = 2500;
521
522    // Used to indicate that a task is removed it should also be removed from recents.
523    private static final boolean REMOVE_FROM_RECENTS = true;
524    // Used to indicate that an app transition should be animated.
525    static final boolean ANIMATE = true;
526
527    // Determines whether to take full screen screenshots
528    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
529    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
530
531    private static native int nativeMigrateToBoost();
532    private static native int nativeMigrateFromBoost();
533    private boolean mIsBoosted = false;
534    private long mBoostStartTime = 0;
535
536    /** All system services */
537    SystemServiceManager mSystemServiceManager;
538
539    private Installer mInstaller;
540
541    /** Run all ActivityStacks through this */
542    final ActivityStackSupervisor mStackSupervisor;
543
544    final ActivityStarter mActivityStarter;
545
546    /** Task stack change listeners. */
547    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
548            new RemoteCallbackList<ITaskStackListener>();
549
550    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
551
552    public IntentFirewall mIntentFirewall;
553
554    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
555    // default actuion automatically.  Important for devices without direct input
556    // devices.
557    private boolean mShowDialogs = true;
558    private boolean mInVrMode = false;
559
560    BroadcastQueue mFgBroadcastQueue;
561    BroadcastQueue mBgBroadcastQueue;
562    // Convenient for easy iteration over the queues. Foreground is first
563    // so that dispatch of foreground broadcasts gets precedence.
564    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
565
566    BroadcastQueue broadcastQueueForIntent(Intent intent) {
567        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
568        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
569                "Broadcast intent " + intent + " on "
570                + (isFg ? "foreground" : "background") + " queue");
571        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
572    }
573
574    /**
575     * Activity we have told the window manager to have key focus.
576     */
577    ActivityRecord mFocusedActivity = null;
578
579    /**
580     * User id of the last activity mFocusedActivity was set to.
581     */
582    private int mLastFocusedUserId;
583
584    /**
585     * If non-null, we are tracking the time the user spends in the currently focused app.
586     */
587    private AppTimeTracker mCurAppTimeTracker;
588
589    /**
590     * List of intents that were used to start the most recent tasks.
591     */
592    final RecentTasks mRecentTasks;
593
594    /**
595     * For addAppTask: cached of the last activity component that was added.
596     */
597    ComponentName mLastAddedTaskComponent;
598
599    /**
600     * For addAppTask: cached of the last activity uid that was added.
601     */
602    int mLastAddedTaskUid;
603
604    /**
605     * For addAppTask: cached of the last ActivityInfo that was added.
606     */
607    ActivityInfo mLastAddedTaskActivity;
608
609    /**
610     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
611     */
612    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
613
614    /**
615     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
616     */
617    String mDeviceOwnerName;
618
619    final UserController mUserController;
620
621    final AppErrors mAppErrors;
622
623    boolean mDoingSetFocusedActivity;
624
625    public boolean canShowErrorDialogs() {
626        return mShowDialogs && !mSleeping && !mShuttingDown;
627    }
628
629    public class PendingAssistExtras extends Binder implements Runnable {
630        public final ActivityRecord activity;
631        public final Bundle extras;
632        public final Intent intent;
633        public final String hint;
634        public final IResultReceiver receiver;
635        public final int userHandle;
636        public boolean haveResult = false;
637        public Bundle result = null;
638        public AssistStructure structure = null;
639        public AssistContent content = null;
640        public Bundle receiverExtras;
641
642        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
643                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
644            activity = _activity;
645            extras = _extras;
646            intent = _intent;
647            hint = _hint;
648            receiver = _receiver;
649            receiverExtras = _receiverExtras;
650            userHandle = _userHandle;
651        }
652        @Override
653        public void run() {
654            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
655            synchronized (this) {
656                haveResult = true;
657                notifyAll();
658            }
659            pendingAssistExtrasTimedOut(this);
660        }
661    }
662
663    final ArrayList<PendingAssistExtras> mPendingAssistExtras
664            = new ArrayList<PendingAssistExtras>();
665
666    /**
667     * Process management.
668     */
669    final ProcessList mProcessList = new ProcessList();
670
671    /**
672     * All of the applications we currently have running organized by name.
673     * The keys are strings of the application package name (as
674     * returned by the package manager), and the keys are ApplicationRecord
675     * objects.
676     */
677    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
678
679    /**
680     * Tracking long-term execution of processes to look for abuse and other
681     * bad app behavior.
682     */
683    final ProcessStatsService mProcessStats;
684
685    /**
686     * The currently running isolated processes.
687     */
688    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
689
690    /**
691     * Counter for assigning isolated process uids, to avoid frequently reusing the
692     * same ones.
693     */
694    int mNextIsolatedProcessUid = 0;
695
696    /**
697     * The currently running heavy-weight process, if any.
698     */
699    ProcessRecord mHeavyWeightProcess = null;
700
701    /**
702     * All of the processes we currently have running organized by pid.
703     * The keys are the pid running the application.
704     *
705     * <p>NOTE: This object is protected by its own lock, NOT the global
706     * activity manager lock!
707     */
708    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
709
710    /**
711     * All of the processes that have been forced to be foreground.  The key
712     * is the pid of the caller who requested it (we hold a death
713     * link on it).
714     */
715    abstract class ForegroundToken implements IBinder.DeathRecipient {
716        int pid;
717        IBinder token;
718    }
719    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
720
721    /**
722     * List of records for processes that someone had tried to start before the
723     * system was ready.  We don't start them at that point, but ensure they
724     * are started by the time booting is complete.
725     */
726    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
727
728    /**
729     * List of persistent applications that are in the process
730     * of being started.
731     */
732    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
733
734    /**
735     * Processes that are being forcibly torn down.
736     */
737    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
738
739    /**
740     * List of running applications, sorted by recent usage.
741     * The first entry in the list is the least recently used.
742     */
743    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
744
745    /**
746     * Where in mLruProcesses that the processes hosting activities start.
747     */
748    int mLruProcessActivityStart = 0;
749
750    /**
751     * Where in mLruProcesses that the processes hosting services start.
752     * This is after (lower index) than mLruProcessesActivityStart.
753     */
754    int mLruProcessServiceStart = 0;
755
756    /**
757     * List of processes that should gc as soon as things are idle.
758     */
759    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
760
761    /**
762     * Processes we want to collect PSS data from.
763     */
764    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
765
766    private boolean mBinderTransactionTrackingEnabled = false;
767
768    /**
769     * Last time we requested PSS data of all processes.
770     */
771    long mLastFullPssTime = SystemClock.uptimeMillis();
772
773    /**
774     * If set, the next time we collect PSS data we should do a full collection
775     * with data from native processes and the kernel.
776     */
777    boolean mFullPssPending = false;
778
779    /**
780     * This is the process holding what we currently consider to be
781     * the "home" activity.
782     */
783    ProcessRecord mHomeProcess;
784
785    /**
786     * This is the process holding the activity the user last visited that
787     * is in a different process from the one they are currently in.
788     */
789    ProcessRecord mPreviousProcess;
790
791    /**
792     * The time at which the previous process was last visible.
793     */
794    long mPreviousProcessVisibleTime;
795
796    /**
797     * Track all uids that have actively running processes.
798     */
799    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
800
801    /**
802     * This is for verifying the UID report flow.
803     */
804    static final boolean VALIDATE_UID_STATES = true;
805    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
806
807    /**
808     * Packages that the user has asked to have run in screen size
809     * compatibility mode instead of filling the screen.
810     */
811    final CompatModePackages mCompatModePackages;
812
813    /**
814     * Set of IntentSenderRecord objects that are currently active.
815     */
816    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
817            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
818
819    /**
820     * Fingerprints (hashCode()) of stack traces that we've
821     * already logged DropBox entries for.  Guarded by itself.  If
822     * something (rogue user app) forces this over
823     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
824     */
825    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
826    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
827
828    /**
829     * Strict Mode background batched logging state.
830     *
831     * The string buffer is guarded by itself, and its lock is also
832     * used to determine if another batched write is already
833     * in-flight.
834     */
835    private final StringBuilder mStrictModeBuffer = new StringBuilder();
836
837    /**
838     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
839     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
840     */
841    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
842
843    /**
844     * Resolver for broadcast intents to registered receivers.
845     * Holds BroadcastFilter (subclass of IntentFilter).
846     */
847    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
848            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
849        @Override
850        protected boolean allowFilterResult(
851                BroadcastFilter filter, List<BroadcastFilter> dest) {
852            IBinder target = filter.receiverList.receiver.asBinder();
853            for (int i = dest.size() - 1; i >= 0; i--) {
854                if (dest.get(i).receiverList.receiver.asBinder() == target) {
855                    return false;
856                }
857            }
858            return true;
859        }
860
861        @Override
862        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
863            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
864                    || userId == filter.owningUserId) {
865                return super.newResult(filter, match, userId);
866            }
867            return null;
868        }
869
870        @Override
871        protected BroadcastFilter[] newArray(int size) {
872            return new BroadcastFilter[size];
873        }
874
875        @Override
876        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
877            return packageName.equals(filter.packageName);
878        }
879    };
880
881    /**
882     * State of all active sticky broadcasts per user.  Keys are the action of the
883     * sticky Intent, values are an ArrayList of all broadcasted intents with
884     * that action (which should usually be one).  The SparseArray is keyed
885     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
886     * for stickies that are sent to all users.
887     */
888    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
889            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
890
891    final ActiveServices mServices;
892
893    final static class Association {
894        final int mSourceUid;
895        final String mSourceProcess;
896        final int mTargetUid;
897        final ComponentName mTargetComponent;
898        final String mTargetProcess;
899
900        int mCount;
901        long mTime;
902
903        int mNesting;
904        long mStartTime;
905
906        // states of the source process when the bind occurred.
907        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
908        long mLastStateUptime;
909        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
910                - ActivityManager.MIN_PROCESS_STATE+1];
911
912        Association(int sourceUid, String sourceProcess, int targetUid,
913                ComponentName targetComponent, String targetProcess) {
914            mSourceUid = sourceUid;
915            mSourceProcess = sourceProcess;
916            mTargetUid = targetUid;
917            mTargetComponent = targetComponent;
918            mTargetProcess = targetProcess;
919        }
920    }
921
922    /**
923     * When service association tracking is enabled, this is all of the associations we
924     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
925     * -> association data.
926     */
927    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
928            mAssociations = new SparseArray<>();
929    boolean mTrackingAssociations;
930
931    /**
932     * Backup/restore process management
933     */
934    String mBackupAppName = null;
935    BackupRecord mBackupTarget = null;
936
937    final ProviderMap mProviderMap;
938
939    /**
940     * List of content providers who have clients waiting for them.  The
941     * application is currently being launched and the provider will be
942     * removed from this list once it is published.
943     */
944    final ArrayList<ContentProviderRecord> mLaunchingProviders
945            = new ArrayList<ContentProviderRecord>();
946
947    /**
948     * File storing persisted {@link #mGrantedUriPermissions}.
949     */
950    private final AtomicFile mGrantFile;
951
952    /** XML constants used in {@link #mGrantFile} */
953    private static final String TAG_URI_GRANTS = "uri-grants";
954    private static final String TAG_URI_GRANT = "uri-grant";
955    private static final String ATTR_USER_HANDLE = "userHandle";
956    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
957    private static final String ATTR_TARGET_USER_ID = "targetUserId";
958    private static final String ATTR_SOURCE_PKG = "sourcePkg";
959    private static final String ATTR_TARGET_PKG = "targetPkg";
960    private static final String ATTR_URI = "uri";
961    private static final String ATTR_MODE_FLAGS = "modeFlags";
962    private static final String ATTR_CREATED_TIME = "createdTime";
963    private static final String ATTR_PREFIX = "prefix";
964
965    /**
966     * Global set of specific {@link Uri} permissions that have been granted.
967     * This optimized lookup structure maps from {@link UriPermission#targetUid}
968     * to {@link UriPermission#uri} to {@link UriPermission}.
969     */
970    @GuardedBy("this")
971    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
972            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
973
974    public static class GrantUri {
975        public final int sourceUserId;
976        public final Uri uri;
977        public boolean prefix;
978
979        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
980            this.sourceUserId = sourceUserId;
981            this.uri = uri;
982            this.prefix = prefix;
983        }
984
985        @Override
986        public int hashCode() {
987            int hashCode = 1;
988            hashCode = 31 * hashCode + sourceUserId;
989            hashCode = 31 * hashCode + uri.hashCode();
990            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
991            return hashCode;
992        }
993
994        @Override
995        public boolean equals(Object o) {
996            if (o instanceof GrantUri) {
997                GrantUri other = (GrantUri) o;
998                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
999                        && prefix == other.prefix;
1000            }
1001            return false;
1002        }
1003
1004        @Override
1005        public String toString() {
1006            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1007            if (prefix) result += " [prefix]";
1008            return result;
1009        }
1010
1011        public String toSafeString() {
1012            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1013            if (prefix) result += " [prefix]";
1014            return result;
1015        }
1016
1017        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1018            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1019                    ContentProvider.getUriWithoutUserId(uri), false);
1020        }
1021    }
1022
1023    CoreSettingsObserver mCoreSettingsObserver;
1024
1025    FontScaleSettingObserver mFontScaleSettingObserver;
1026
1027    private final class FontScaleSettingObserver extends ContentObserver {
1028        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1029
1030        public FontScaleSettingObserver() {
1031            super(mHandler);
1032            ContentResolver resolver = mContext.getContentResolver();
1033            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1034        }
1035
1036        @Override
1037        public void onChange(boolean selfChange, Uri uri) {
1038            if (mFontScaleUri.equals(uri)) {
1039                updateFontScaleIfNeeded();
1040            }
1041        }
1042    }
1043
1044    /**
1045     * Thread-local storage used to carry caller permissions over through
1046     * indirect content-provider access.
1047     */
1048    private class Identity {
1049        public final IBinder token;
1050        public final int pid;
1051        public final int uid;
1052
1053        Identity(IBinder _token, int _pid, int _uid) {
1054            token = _token;
1055            pid = _pid;
1056            uid = _uid;
1057        }
1058    }
1059
1060    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1061
1062    /**
1063     * All information we have collected about the runtime performance of
1064     * any user id that can impact battery performance.
1065     */
1066    final BatteryStatsService mBatteryStatsService;
1067
1068    /**
1069     * Information about component usage
1070     */
1071    UsageStatsManagerInternal mUsageStatsService;
1072
1073    /**
1074     * Access to DeviceIdleController service.
1075     */
1076    DeviceIdleController.LocalService mLocalDeviceIdleController;
1077
1078    /**
1079     * Information about and control over application operations
1080     */
1081    final AppOpsService mAppOpsService;
1082
1083    /**
1084     * Current configuration information.  HistoryRecord objects are given
1085     * a reference to this object to indicate which configuration they are
1086     * currently running in, so this object must be kept immutable.
1087     */
1088    Configuration mConfiguration = new Configuration();
1089
1090    /**
1091     * Current sequencing integer of the configuration, for skipping old
1092     * configurations.
1093     */
1094    int mConfigurationSeq = 0;
1095
1096    boolean mSuppressResizeConfigChanges = false;
1097
1098    /**
1099     * Hardware-reported OpenGLES version.
1100     */
1101    final int GL_ES_VERSION;
1102
1103    /**
1104     * List of initialization arguments to pass to all processes when binding applications to them.
1105     * For example, references to the commonly used services.
1106     */
1107    HashMap<String, IBinder> mAppBindArgs;
1108
1109    /**
1110     * Temporary to avoid allocations.  Protected by main lock.
1111     */
1112    final StringBuilder mStringBuilder = new StringBuilder(256);
1113
1114    /**
1115     * Used to control how we initialize the service.
1116     */
1117    ComponentName mTopComponent;
1118    String mTopAction = Intent.ACTION_MAIN;
1119    String mTopData;
1120
1121    volatile boolean mProcessesReady = false;
1122    volatile boolean mSystemReady = false;
1123    volatile boolean mOnBattery = false;
1124    volatile int mFactoryTest;
1125
1126    @GuardedBy("this") boolean mBooting = false;
1127    @GuardedBy("this") boolean mCallFinishBooting = false;
1128    @GuardedBy("this") boolean mBootAnimationComplete = false;
1129    @GuardedBy("this") boolean mLaunchWarningShown = false;
1130    @GuardedBy("this") boolean mCheckedForSetup = false;
1131
1132    Context mContext;
1133
1134    /**
1135     * The time at which we will allow normal application switches again,
1136     * after a call to {@link #stopAppSwitches()}.
1137     */
1138    long mAppSwitchesAllowedTime;
1139
1140    /**
1141     * This is set to true after the first switch after mAppSwitchesAllowedTime
1142     * is set; any switches after that will clear the time.
1143     */
1144    boolean mDidAppSwitch;
1145
1146    /**
1147     * Last time (in realtime) at which we checked for power usage.
1148     */
1149    long mLastPowerCheckRealtime;
1150
1151    /**
1152     * Last time (in uptime) at which we checked for power usage.
1153     */
1154    long mLastPowerCheckUptime;
1155
1156    /**
1157     * Set while we are wanting to sleep, to prevent any
1158     * activities from being started/resumed.
1159     */
1160    private boolean mSleeping = false;
1161
1162    /**
1163     * The process state used for processes that are running the top activities.
1164     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1165     */
1166    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1167
1168    /**
1169     * Set while we are running a voice interaction.  This overrides
1170     * sleeping while it is active.
1171     */
1172    private IVoiceInteractionSession mRunningVoice;
1173
1174    /**
1175     * For some direct access we need to power manager.
1176     */
1177    PowerManagerInternal mLocalPowerManager;
1178
1179    /**
1180     * We want to hold a wake lock while running a voice interaction session, since
1181     * this may happen with the screen off and we need to keep the CPU running to
1182     * be able to continue to interact with the user.
1183     */
1184    PowerManager.WakeLock mVoiceWakeLock;
1185
1186    /**
1187     * State of external calls telling us if the device is awake or asleep.
1188     */
1189    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1190
1191    /**
1192     * A list of tokens that cause the top activity to be put to sleep.
1193     * They are used by components that may hide and block interaction with underlying
1194     * activities.
1195     */
1196    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1197
1198    static final int LOCK_SCREEN_HIDDEN = 0;
1199    static final int LOCK_SCREEN_LEAVING = 1;
1200    static final int LOCK_SCREEN_SHOWN = 2;
1201    /**
1202     * State of external call telling us if the lock screen is shown.
1203     */
1204    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1205
1206    /**
1207     * Set if we are shutting down the system, similar to sleeping.
1208     */
1209    boolean mShuttingDown = false;
1210
1211    /**
1212     * Current sequence id for oom_adj computation traversal.
1213     */
1214    int mAdjSeq = 0;
1215
1216    /**
1217     * Current sequence id for process LRU updating.
1218     */
1219    int mLruSeq = 0;
1220
1221    /**
1222     * Keep track of the non-cached/empty process we last found, to help
1223     * determine how to distribute cached/empty processes next time.
1224     */
1225    int mNumNonCachedProcs = 0;
1226
1227    /**
1228     * Keep track of the number of cached hidden procs, to balance oom adj
1229     * distribution between those and empty procs.
1230     */
1231    int mNumCachedHiddenProcs = 0;
1232
1233    /**
1234     * Keep track of the number of service processes we last found, to
1235     * determine on the next iteration which should be B services.
1236     */
1237    int mNumServiceProcs = 0;
1238    int mNewNumAServiceProcs = 0;
1239    int mNewNumServiceProcs = 0;
1240
1241    /**
1242     * Allow the current computed overall memory level of the system to go down?
1243     * This is set to false when we are killing processes for reasons other than
1244     * memory management, so that the now smaller process list will not be taken as
1245     * an indication that memory is tighter.
1246     */
1247    boolean mAllowLowerMemLevel = false;
1248
1249    /**
1250     * The last computed memory level, for holding when we are in a state that
1251     * processes are going away for other reasons.
1252     */
1253    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1254
1255    /**
1256     * The last total number of process we have, to determine if changes actually look
1257     * like a shrinking number of process due to lower RAM.
1258     */
1259    int mLastNumProcesses;
1260
1261    /**
1262     * The uptime of the last time we performed idle maintenance.
1263     */
1264    long mLastIdleTime = SystemClock.uptimeMillis();
1265
1266    /**
1267     * Total time spent with RAM that has been added in the past since the last idle time.
1268     */
1269    long mLowRamTimeSinceLastIdle = 0;
1270
1271    /**
1272     * If RAM is currently low, when that horrible situation started.
1273     */
1274    long mLowRamStartTime = 0;
1275
1276    /**
1277     * For reporting to battery stats the current top application.
1278     */
1279    private String mCurResumedPackage = null;
1280    private int mCurResumedUid = -1;
1281
1282    /**
1283     * For reporting to battery stats the apps currently running foreground
1284     * service.  The ProcessMap is package/uid tuples; each of these contain
1285     * an array of the currently foreground processes.
1286     */
1287    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1288            = new ProcessMap<ArrayList<ProcessRecord>>();
1289
1290    /**
1291     * This is set if we had to do a delayed dexopt of an app before launching
1292     * it, to increase the ANR timeouts in that case.
1293     */
1294    boolean mDidDexOpt;
1295
1296    /**
1297     * Set if the systemServer made a call to enterSafeMode.
1298     */
1299    boolean mSafeMode;
1300
1301    /**
1302     * If true, we are running under a test environment so will sample PSS from processes
1303     * much more rapidly to try to collect better data when the tests are rapidly
1304     * running through apps.
1305     */
1306    boolean mTestPssMode = false;
1307
1308    String mDebugApp = null;
1309    boolean mWaitForDebugger = false;
1310    boolean mDebugTransient = false;
1311    String mOrigDebugApp = null;
1312    boolean mOrigWaitForDebugger = false;
1313    boolean mAlwaysFinishActivities = false;
1314    boolean mLenientBackgroundCheck = false;
1315    boolean mForceResizableActivities;
1316    boolean mSupportsMultiWindow;
1317    boolean mSupportsFreeformWindowManagement;
1318    boolean mSupportsPictureInPicture;
1319    Rect mDefaultPinnedStackBounds;
1320    IActivityController mController = null;
1321    boolean mControllerIsAMonkey = false;
1322    String mProfileApp = null;
1323    ProcessRecord mProfileProc = null;
1324    String mProfileFile;
1325    ParcelFileDescriptor mProfileFd;
1326    int mSamplingInterval = 0;
1327    boolean mAutoStopProfiler = false;
1328    int mProfileType = 0;
1329    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1330    String mMemWatchDumpProcName;
1331    String mMemWatchDumpFile;
1332    int mMemWatchDumpPid;
1333    int mMemWatchDumpUid;
1334    String mTrackAllocationApp = null;
1335    String mNativeDebuggingApp = null;
1336
1337    final long[] mTmpLong = new long[2];
1338
1339    static final class ProcessChangeItem {
1340        static final int CHANGE_ACTIVITIES = 1<<0;
1341        static final int CHANGE_PROCESS_STATE = 1<<1;
1342        int changes;
1343        int uid;
1344        int pid;
1345        int processState;
1346        boolean foregroundActivities;
1347    }
1348
1349    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1350    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1351
1352    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1353    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1354
1355    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1356    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1357
1358    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1359    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1360
1361    /**
1362     * Runtime CPU use collection thread.  This object's lock is used to
1363     * perform synchronization with the thread (notifying it to run).
1364     */
1365    final Thread mProcessCpuThread;
1366
1367    /**
1368     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1369     * Must acquire this object's lock when accessing it.
1370     * NOTE: this lock will be held while doing long operations (trawling
1371     * through all processes in /proc), so it should never be acquired by
1372     * any critical paths such as when holding the main activity manager lock.
1373     */
1374    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1375            MONITOR_THREAD_CPU_USAGE);
1376    final AtomicLong mLastCpuTime = new AtomicLong(0);
1377    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1378
1379    long mLastWriteTime = 0;
1380
1381    /**
1382     * Used to retain an update lock when the foreground activity is in
1383     * immersive mode.
1384     */
1385    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1386
1387    /**
1388     * Set to true after the system has finished booting.
1389     */
1390    boolean mBooted = false;
1391
1392    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1393    int mProcessLimitOverride = -1;
1394
1395    WindowManagerService mWindowManager;
1396    final ActivityThread mSystemThread;
1397
1398    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1399        final ProcessRecord mApp;
1400        final int mPid;
1401        final IApplicationThread mAppThread;
1402
1403        AppDeathRecipient(ProcessRecord app, int pid,
1404                IApplicationThread thread) {
1405            if (DEBUG_ALL) Slog.v(
1406                TAG, "New death recipient " + this
1407                + " for thread " + thread.asBinder());
1408            mApp = app;
1409            mPid = pid;
1410            mAppThread = thread;
1411        }
1412
1413        @Override
1414        public void binderDied() {
1415            if (DEBUG_ALL) Slog.v(
1416                TAG, "Death received in " + this
1417                + " for thread " + mAppThread.asBinder());
1418            synchronized(ActivityManagerService.this) {
1419                appDiedLocked(mApp, mPid, mAppThread, true);
1420            }
1421        }
1422    }
1423
1424    static final int SHOW_ERROR_UI_MSG = 1;
1425    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1426    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1427    static final int UPDATE_CONFIGURATION_MSG = 4;
1428    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1429    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1430    static final int SERVICE_TIMEOUT_MSG = 12;
1431    static final int UPDATE_TIME_ZONE = 13;
1432    static final int SHOW_UID_ERROR_UI_MSG = 14;
1433    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1434    static final int PROC_START_TIMEOUT_MSG = 20;
1435    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1436    static final int KILL_APPLICATION_MSG = 22;
1437    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1438    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1439    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1440    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1441    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1442    static final int CLEAR_DNS_CACHE_MSG = 28;
1443    static final int UPDATE_HTTP_PROXY_MSG = 29;
1444    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1445    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1446    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1447    static final int REPORT_MEM_USAGE_MSG = 33;
1448    static final int REPORT_USER_SWITCH_MSG = 34;
1449    static final int CONTINUE_USER_SWITCH_MSG = 35;
1450    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1451    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1452    static final int PERSIST_URI_GRANTS_MSG = 38;
1453    static final int REQUEST_ALL_PSS_MSG = 39;
1454    static final int START_PROFILES_MSG = 40;
1455    static final int UPDATE_TIME = 41;
1456    static final int SYSTEM_USER_START_MSG = 42;
1457    static final int SYSTEM_USER_CURRENT_MSG = 43;
1458    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1459    static final int FINISH_BOOTING_MSG = 45;
1460    static final int START_USER_SWITCH_UI_MSG = 46;
1461    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1462    static final int DISMISS_DIALOG_UI_MSG = 48;
1463    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1464    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1465    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1466    static final int DELETE_DUMPHEAP_MSG = 52;
1467    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1468    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1469    static final int REPORT_TIME_TRACKER_MSG = 55;
1470    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1471    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1472    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1473    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1474    static final int IDLE_UIDS_MSG = 60;
1475    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1476    static final int LOG_STACK_STATE = 62;
1477    static final int VR_MODE_CHANGE_MSG = 63;
1478    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1479    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1480    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1481    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1482    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1483    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1484
1485    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1486    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1487    static final int FIRST_COMPAT_MODE_MSG = 300;
1488    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1489
1490    static ServiceThread sKillThread = null;
1491    static KillHandler sKillHandler = null;
1492
1493    CompatModeDialog mCompatModeDialog;
1494    long mLastMemUsageReportTime = 0;
1495
1496    /**
1497     * Flag whether the current user is a "monkey", i.e. whether
1498     * the UI is driven by a UI automation tool.
1499     */
1500    private boolean mUserIsMonkey;
1501
1502    /** Flag whether the device has a Recents UI */
1503    boolean mHasRecents;
1504
1505    /** The dimensions of the thumbnails in the Recents UI. */
1506    int mThumbnailWidth;
1507    int mThumbnailHeight;
1508    float mFullscreenThumbnailScale;
1509
1510    final ServiceThread mHandlerThread;
1511    final MainHandler mHandler;
1512    final UiHandler mUiHandler;
1513
1514    PackageManagerInternal mPackageManagerInt;
1515
1516    // VoiceInteraction session ID that changes for each new request except when
1517    // being called for multiwindow assist in a single session.
1518    private int mViSessionId = 1000;
1519
1520    final class KillHandler extends Handler {
1521        static final int KILL_PROCESS_GROUP_MSG = 4000;
1522
1523        public KillHandler(Looper looper) {
1524            super(looper, null, true);
1525        }
1526
1527        @Override
1528        public void handleMessage(Message msg) {
1529            switch (msg.what) {
1530                case KILL_PROCESS_GROUP_MSG:
1531                {
1532                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1533                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1534                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1535                }
1536                break;
1537
1538                default:
1539                    super.handleMessage(msg);
1540            }
1541        }
1542    }
1543
1544    final class UiHandler extends Handler {
1545        public UiHandler() {
1546            super(com.android.server.UiThread.get().getLooper(), null, true);
1547        }
1548
1549        @Override
1550        public void handleMessage(Message msg) {
1551            switch (msg.what) {
1552            case SHOW_ERROR_UI_MSG: {
1553                mAppErrors.handleShowAppErrorUi(msg);
1554                ensureBootCompleted();
1555            } break;
1556            case SHOW_NOT_RESPONDING_UI_MSG: {
1557                mAppErrors.handleShowAnrUi(msg);
1558                ensureBootCompleted();
1559            } break;
1560            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1561                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1562                synchronized (ActivityManagerService.this) {
1563                    ProcessRecord proc = (ProcessRecord) data.get("app");
1564                    if (proc == null) {
1565                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1566                        break;
1567                    }
1568                    if (proc.crashDialog != null) {
1569                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1570                        return;
1571                    }
1572                    AppErrorResult res = (AppErrorResult) data.get("result");
1573                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1574                        Dialog d = new StrictModeViolationDialog(mContext,
1575                                ActivityManagerService.this, res, proc);
1576                        d.show();
1577                        proc.crashDialog = d;
1578                    } else {
1579                        // The device is asleep, so just pretend that the user
1580                        // saw a crash dialog and hit "force quit".
1581                        res.set(0);
1582                    }
1583                }
1584                ensureBootCompleted();
1585            } break;
1586            case SHOW_FACTORY_ERROR_UI_MSG: {
1587                Dialog d = new FactoryErrorDialog(
1588                    mContext, msg.getData().getCharSequence("msg"));
1589                d.show();
1590                ensureBootCompleted();
1591            } break;
1592            case WAIT_FOR_DEBUGGER_UI_MSG: {
1593                synchronized (ActivityManagerService.this) {
1594                    ProcessRecord app = (ProcessRecord)msg.obj;
1595                    if (msg.arg1 != 0) {
1596                        if (!app.waitedForDebugger) {
1597                            Dialog d = new AppWaitingForDebuggerDialog(
1598                                    ActivityManagerService.this,
1599                                    mContext, app);
1600                            app.waitDialog = d;
1601                            app.waitedForDebugger = true;
1602                            d.show();
1603                        }
1604                    } else {
1605                        if (app.waitDialog != null) {
1606                            app.waitDialog.dismiss();
1607                            app.waitDialog = null;
1608                        }
1609                    }
1610                }
1611            } break;
1612            case SHOW_UID_ERROR_UI_MSG: {
1613                if (mShowDialogs) {
1614                    AlertDialog d = new BaseErrorDialog(mContext);
1615                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1616                    d.setCancelable(false);
1617                    d.setTitle(mContext.getText(R.string.android_system_label));
1618                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1619                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1620                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1621                    d.show();
1622                }
1623            } break;
1624            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1625                if (mShowDialogs) {
1626                    AlertDialog d = new BaseErrorDialog(mContext);
1627                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1628                    d.setCancelable(false);
1629                    d.setTitle(mContext.getText(R.string.android_system_label));
1630                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1631                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1632                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1633                    d.show();
1634                }
1635            } break;
1636            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1637                synchronized (ActivityManagerService.this) {
1638                    ActivityRecord ar = (ActivityRecord) msg.obj;
1639                    if (mCompatModeDialog != null) {
1640                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1641                                ar.info.applicationInfo.packageName)) {
1642                            return;
1643                        }
1644                        mCompatModeDialog.dismiss();
1645                        mCompatModeDialog = null;
1646                    }
1647                    if (ar != null && false) {
1648                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1649                                ar.packageName)) {
1650                            int mode = mCompatModePackages.computeCompatModeLocked(
1651                                    ar.info.applicationInfo);
1652                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1653                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1654                                mCompatModeDialog = new CompatModeDialog(
1655                                        ActivityManagerService.this, mContext,
1656                                        ar.info.applicationInfo);
1657                                mCompatModeDialog.show();
1658                            }
1659                        }
1660                    }
1661                }
1662                break;
1663            }
1664            case START_USER_SWITCH_UI_MSG: {
1665                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1666                break;
1667            }
1668            case DISMISS_DIALOG_UI_MSG: {
1669                final Dialog d = (Dialog) msg.obj;
1670                d.dismiss();
1671                break;
1672            }
1673            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1674                dispatchProcessesChanged();
1675                break;
1676            }
1677            case DISPATCH_PROCESS_DIED_UI_MSG: {
1678                final int pid = msg.arg1;
1679                final int uid = msg.arg2;
1680                dispatchProcessDied(pid, uid);
1681                break;
1682            }
1683            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1684                dispatchUidsChanged();
1685            } break;
1686            }
1687        }
1688    }
1689
1690    final class MainHandler extends Handler {
1691        public MainHandler(Looper looper) {
1692            super(looper, null, true);
1693        }
1694
1695        @Override
1696        public void handleMessage(Message msg) {
1697            switch (msg.what) {
1698            case UPDATE_CONFIGURATION_MSG: {
1699                final ContentResolver resolver = mContext.getContentResolver();
1700                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1701                        msg.arg1);
1702            } break;
1703            case GC_BACKGROUND_PROCESSES_MSG: {
1704                synchronized (ActivityManagerService.this) {
1705                    performAppGcsIfAppropriateLocked();
1706                }
1707            } break;
1708            case SERVICE_TIMEOUT_MSG: {
1709                if (mDidDexOpt) {
1710                    mDidDexOpt = false;
1711                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1712                    nmsg.obj = msg.obj;
1713                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1714                    return;
1715                }
1716                mServices.serviceTimeout((ProcessRecord)msg.obj);
1717            } break;
1718            case UPDATE_TIME_ZONE: {
1719                synchronized (ActivityManagerService.this) {
1720                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1721                        ProcessRecord r = mLruProcesses.get(i);
1722                        if (r.thread != null) {
1723                            try {
1724                                r.thread.updateTimeZone();
1725                            } catch (RemoteException ex) {
1726                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1727                            }
1728                        }
1729                    }
1730                }
1731            } break;
1732            case CLEAR_DNS_CACHE_MSG: {
1733                synchronized (ActivityManagerService.this) {
1734                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1735                        ProcessRecord r = mLruProcesses.get(i);
1736                        if (r.thread != null) {
1737                            try {
1738                                r.thread.clearDnsCache();
1739                            } catch (RemoteException ex) {
1740                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1741                            }
1742                        }
1743                    }
1744                }
1745            } break;
1746            case UPDATE_HTTP_PROXY_MSG: {
1747                ProxyInfo proxy = (ProxyInfo)msg.obj;
1748                String host = "";
1749                String port = "";
1750                String exclList = "";
1751                Uri pacFileUrl = Uri.EMPTY;
1752                if (proxy != null) {
1753                    host = proxy.getHost();
1754                    port = Integer.toString(proxy.getPort());
1755                    exclList = proxy.getExclusionListAsString();
1756                    pacFileUrl = proxy.getPacFileUrl();
1757                }
1758                synchronized (ActivityManagerService.this) {
1759                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1760                        ProcessRecord r = mLruProcesses.get(i);
1761                        if (r.thread != null) {
1762                            try {
1763                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1764                            } catch (RemoteException ex) {
1765                                Slog.w(TAG, "Failed to update http proxy for: " +
1766                                        r.info.processName);
1767                            }
1768                        }
1769                    }
1770                }
1771            } break;
1772            case PROC_START_TIMEOUT_MSG: {
1773                if (mDidDexOpt) {
1774                    mDidDexOpt = false;
1775                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1776                    nmsg.obj = msg.obj;
1777                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1778                    return;
1779                }
1780                ProcessRecord app = (ProcessRecord)msg.obj;
1781                synchronized (ActivityManagerService.this) {
1782                    processStartTimedOutLocked(app);
1783                }
1784            } break;
1785            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1786                ProcessRecord app = (ProcessRecord)msg.obj;
1787                synchronized (ActivityManagerService.this) {
1788                    processContentProviderPublishTimedOutLocked(app);
1789                }
1790            } break;
1791            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1792                synchronized (ActivityManagerService.this) {
1793                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1794                }
1795            } break;
1796            case KILL_APPLICATION_MSG: {
1797                synchronized (ActivityManagerService.this) {
1798                    int appid = msg.arg1;
1799                    boolean restart = (msg.arg2 == 1);
1800                    Bundle bundle = (Bundle)msg.obj;
1801                    String pkg = bundle.getString("pkg");
1802                    String reason = bundle.getString("reason");
1803                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1804                            false, UserHandle.USER_ALL, reason);
1805                }
1806            } break;
1807            case FINALIZE_PENDING_INTENT_MSG: {
1808                ((PendingIntentRecord)msg.obj).completeFinalize();
1809            } break;
1810            case POST_HEAVY_NOTIFICATION_MSG: {
1811                INotificationManager inm = NotificationManager.getService();
1812                if (inm == null) {
1813                    return;
1814                }
1815
1816                ActivityRecord root = (ActivityRecord)msg.obj;
1817                ProcessRecord process = root.app;
1818                if (process == null) {
1819                    return;
1820                }
1821
1822                try {
1823                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1824                    String text = mContext.getString(R.string.heavy_weight_notification,
1825                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1826                    Notification notification = new Notification.Builder(context)
1827                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1828                            .setWhen(0)
1829                            .setOngoing(true)
1830                            .setTicker(text)
1831                            .setColor(mContext.getColor(
1832                                    com.android.internal.R.color.system_notification_accent_color))
1833                            .setContentTitle(text)
1834                            .setContentText(
1835                                    mContext.getText(R.string.heavy_weight_notification_detail))
1836                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1837                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1838                                    new UserHandle(root.userId)))
1839                            .build();
1840                    try {
1841                        int[] outId = new int[1];
1842                        inm.enqueueNotificationWithTag("android", "android", null,
1843                                R.string.heavy_weight_notification,
1844                                notification, outId, root.userId);
1845                    } catch (RuntimeException e) {
1846                        Slog.w(ActivityManagerService.TAG,
1847                                "Error showing notification for heavy-weight app", e);
1848                    } catch (RemoteException e) {
1849                    }
1850                } catch (NameNotFoundException e) {
1851                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1852                }
1853            } break;
1854            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1855                INotificationManager inm = NotificationManager.getService();
1856                if (inm == null) {
1857                    return;
1858                }
1859                try {
1860                    inm.cancelNotificationWithTag("android", null,
1861                            R.string.heavy_weight_notification,  msg.arg1);
1862                } catch (RuntimeException e) {
1863                    Slog.w(ActivityManagerService.TAG,
1864                            "Error canceling notification for service", e);
1865                } catch (RemoteException e) {
1866                }
1867            } break;
1868            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1869                synchronized (ActivityManagerService.this) {
1870                    checkExcessivePowerUsageLocked(true);
1871                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1872                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1873                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1874                }
1875            } break;
1876            case REPORT_MEM_USAGE_MSG: {
1877                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1878                Thread thread = new Thread() {
1879                    @Override public void run() {
1880                        reportMemUsage(memInfos);
1881                    }
1882                };
1883                thread.start();
1884                break;
1885            }
1886            case REPORT_USER_SWITCH_MSG: {
1887                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1888                break;
1889            }
1890            case CONTINUE_USER_SWITCH_MSG: {
1891                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1892                break;
1893            }
1894            case USER_SWITCH_TIMEOUT_MSG: {
1895                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1896                break;
1897            }
1898            case IMMERSIVE_MODE_LOCK_MSG: {
1899                final boolean nextState = (msg.arg1 != 0);
1900                if (mUpdateLock.isHeld() != nextState) {
1901                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1902                            "Applying new update lock state '" + nextState
1903                            + "' for " + (ActivityRecord)msg.obj);
1904                    if (nextState) {
1905                        mUpdateLock.acquire();
1906                    } else {
1907                        mUpdateLock.release();
1908                    }
1909                }
1910                break;
1911            }
1912            case PERSIST_URI_GRANTS_MSG: {
1913                writeGrantedUriPermissions();
1914                break;
1915            }
1916            case REQUEST_ALL_PSS_MSG: {
1917                synchronized (ActivityManagerService.this) {
1918                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1919                }
1920                break;
1921            }
1922            case START_PROFILES_MSG: {
1923                synchronized (ActivityManagerService.this) {
1924                    mUserController.startProfilesLocked();
1925                }
1926                break;
1927            }
1928            case UPDATE_TIME: {
1929                synchronized (ActivityManagerService.this) {
1930                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1931                        ProcessRecord r = mLruProcesses.get(i);
1932                        if (r.thread != null) {
1933                            try {
1934                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1935                            } catch (RemoteException ex) {
1936                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1937                            }
1938                        }
1939                    }
1940                }
1941                break;
1942            }
1943            case SYSTEM_USER_START_MSG: {
1944                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1945                        Integer.toString(msg.arg1), msg.arg1);
1946                mSystemServiceManager.startUser(msg.arg1);
1947                break;
1948            }
1949            case SYSTEM_USER_UNLOCK_MSG: {
1950                final int userId = msg.arg1;
1951                mSystemServiceManager.unlockUser(userId);
1952                synchronized (ActivityManagerService.this) {
1953                    mRecentTasks.loadUserRecentsLocked(userId);
1954                }
1955                if (userId == UserHandle.USER_SYSTEM) {
1956                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1957                }
1958                installEncryptionUnawareProviders(userId);
1959                mUserController.finishUserUnlocked((UserState) msg.obj);
1960                break;
1961            }
1962            case SYSTEM_USER_CURRENT_MSG: {
1963                mBatteryStatsService.noteEvent(
1964                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1965                        Integer.toString(msg.arg2), msg.arg2);
1966                mBatteryStatsService.noteEvent(
1967                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1968                        Integer.toString(msg.arg1), msg.arg1);
1969                mSystemServiceManager.switchUser(msg.arg1);
1970                break;
1971            }
1972            case ENTER_ANIMATION_COMPLETE_MSG: {
1973                synchronized (ActivityManagerService.this) {
1974                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1975                    if (r != null && r.app != null && r.app.thread != null) {
1976                        try {
1977                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1978                        } catch (RemoteException e) {
1979                        }
1980                    }
1981                }
1982                break;
1983            }
1984            case FINISH_BOOTING_MSG: {
1985                if (msg.arg1 != 0) {
1986                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1987                    finishBooting();
1988                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1989                }
1990                if (msg.arg2 != 0) {
1991                    enableScreenAfterBoot();
1992                }
1993                break;
1994            }
1995            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1996                try {
1997                    Locale l = (Locale) msg.obj;
1998                    IBinder service = ServiceManager.getService("mount");
1999                    IMountService mountService = IMountService.Stub.asInterface(service);
2000                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2001                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2002                } catch (RemoteException e) {
2003                    Log.e(TAG, "Error storing locale for decryption UI", e);
2004                }
2005                break;
2006            }
2007            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2008                synchronized (ActivityManagerService.this) {
2009                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2010                        try {
2011                            // Make a one-way callback to the listener
2012                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2013                        } catch (RemoteException e){
2014                            // Handled by the RemoteCallbackList
2015                        }
2016                    }
2017                    mTaskStackListeners.finishBroadcast();
2018                }
2019                break;
2020            }
2021            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2022                synchronized (ActivityManagerService.this) {
2023                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2024                        try {
2025                            // Make a one-way callback to the listener
2026                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2027                        } catch (RemoteException e){
2028                            // Handled by the RemoteCallbackList
2029                        }
2030                    }
2031                    mTaskStackListeners.finishBroadcast();
2032                }
2033                break;
2034            }
2035            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2036                synchronized (ActivityManagerService.this) {
2037                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2038                        try {
2039                            // Make a one-way callback to the listener
2040                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2041                        } catch (RemoteException e){
2042                            // Handled by the RemoteCallbackList
2043                        }
2044                    }
2045                    mTaskStackListeners.finishBroadcast();
2046                }
2047                break;
2048            }
2049            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2050                synchronized (ActivityManagerService.this) {
2051                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2052                        try {
2053                            // Make a one-way callback to the listener
2054                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2055                        } catch (RemoteException e){
2056                            // Handled by the RemoteCallbackList
2057                        }
2058                    }
2059                    mTaskStackListeners.finishBroadcast();
2060                }
2061                break;
2062            }
2063            case NOTIFY_FORCED_RESIZABLE_MSG: {
2064                synchronized (ActivityManagerService.this) {
2065                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2066                        try {
2067                            // Make a one-way callback to the listener
2068                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2069                                    (String) msg.obj, msg.arg1);
2070                        } catch (RemoteException e){
2071                            // Handled by the RemoteCallbackList
2072                        }
2073                    }
2074                    mTaskStackListeners.finishBroadcast();
2075                }
2076                break;
2077            }
2078                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2079                    synchronized (ActivityManagerService.this) {
2080                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2081                            try {
2082                                // Make a one-way callback to the listener
2083                                mTaskStackListeners.getBroadcastItem(i)
2084                                        .onActivityDismissingDockedStack();
2085                            } catch (RemoteException e){
2086                                // Handled by the RemoteCallbackList
2087                            }
2088                        }
2089                        mTaskStackListeners.finishBroadcast();
2090                    }
2091                    break;
2092                }
2093            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2094                final int uid = msg.arg1;
2095                final byte[] firstPacket = (byte[]) msg.obj;
2096
2097                synchronized (mPidsSelfLocked) {
2098                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2099                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2100                        if (p.uid == uid) {
2101                            try {
2102                                p.thread.notifyCleartextNetwork(firstPacket);
2103                            } catch (RemoteException ignored) {
2104                            }
2105                        }
2106                    }
2107                }
2108                break;
2109            }
2110            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2111                final String procName;
2112                final int uid;
2113                final long memLimit;
2114                final String reportPackage;
2115                synchronized (ActivityManagerService.this) {
2116                    procName = mMemWatchDumpProcName;
2117                    uid = mMemWatchDumpUid;
2118                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2119                    if (val == null) {
2120                        val = mMemWatchProcesses.get(procName, 0);
2121                    }
2122                    if (val != null) {
2123                        memLimit = val.first;
2124                        reportPackage = val.second;
2125                    } else {
2126                        memLimit = 0;
2127                        reportPackage = null;
2128                    }
2129                }
2130                if (procName == null) {
2131                    return;
2132                }
2133
2134                if (DEBUG_PSS) Slog.d(TAG_PSS,
2135                        "Showing dump heap notification from " + procName + "/" + uid);
2136
2137                INotificationManager inm = NotificationManager.getService();
2138                if (inm == null) {
2139                    return;
2140                }
2141
2142                String text = mContext.getString(R.string.dump_heap_notification, procName);
2143
2144
2145                Intent deleteIntent = new Intent();
2146                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2147                Intent intent = new Intent();
2148                intent.setClassName("android", DumpHeapActivity.class.getName());
2149                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2150                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2151                if (reportPackage != null) {
2152                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2153                }
2154                int userId = UserHandle.getUserId(uid);
2155                Notification notification = new Notification.Builder(mContext)
2156                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2157                        .setWhen(0)
2158                        .setOngoing(true)
2159                        .setAutoCancel(true)
2160                        .setTicker(text)
2161                        .setColor(mContext.getColor(
2162                                com.android.internal.R.color.system_notification_accent_color))
2163                        .setContentTitle(text)
2164                        .setContentText(
2165                                mContext.getText(R.string.dump_heap_notification_detail))
2166                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2167                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2168                                new UserHandle(userId)))
2169                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2170                                deleteIntent, 0, UserHandle.SYSTEM))
2171                        .build();
2172
2173                try {
2174                    int[] outId = new int[1];
2175                    inm.enqueueNotificationWithTag("android", "android", null,
2176                            R.string.dump_heap_notification,
2177                            notification, outId, userId);
2178                } catch (RuntimeException e) {
2179                    Slog.w(ActivityManagerService.TAG,
2180                            "Error showing notification for dump heap", e);
2181                } catch (RemoteException e) {
2182                }
2183            } break;
2184            case DELETE_DUMPHEAP_MSG: {
2185                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2186                        DumpHeapActivity.JAVA_URI,
2187                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2188                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2189                        UserHandle.myUserId());
2190                synchronized (ActivityManagerService.this) {
2191                    mMemWatchDumpFile = null;
2192                    mMemWatchDumpProcName = null;
2193                    mMemWatchDumpPid = -1;
2194                    mMemWatchDumpUid = -1;
2195                }
2196            } break;
2197            case FOREGROUND_PROFILE_CHANGED_MSG: {
2198                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2199            } break;
2200            case REPORT_TIME_TRACKER_MSG: {
2201                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2202                tracker.deliverResult(mContext);
2203            } break;
2204            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2205                mUserController.dispatchUserSwitchComplete(msg.arg1);
2206            } break;
2207            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2208                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2209                try {
2210                    connection.shutdown();
2211                } catch (RemoteException e) {
2212                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2213                }
2214                // Only a UiAutomation can set this flag and now that
2215                // it is finished we make sure it is reset to its default.
2216                mUserIsMonkey = false;
2217            } break;
2218            case APP_BOOST_DEACTIVATE_MSG: {
2219                synchronized(ActivityManagerService.this) {
2220                    if (mIsBoosted) {
2221                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2222                            nativeMigrateFromBoost();
2223                            mIsBoosted = false;
2224                            mBoostStartTime = 0;
2225                        } else {
2226                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2227                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2228                        }
2229                    }
2230                }
2231            } break;
2232            case IDLE_UIDS_MSG: {
2233                idleUids();
2234            } break;
2235            case LOG_STACK_STATE: {
2236                synchronized (ActivityManagerService.this) {
2237                    mStackSupervisor.logStackState();
2238                }
2239            } break;
2240            case VR_MODE_CHANGE_MSG: {
2241                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2242                final ActivityRecord r = (ActivityRecord) msg.obj;
2243                boolean vrMode;
2244                ComponentName requestedPackage;
2245                ComponentName callingPackage;
2246                int userId;
2247                synchronized (ActivityManagerService.this) {
2248                    vrMode = r.requestedVrComponent != null;
2249                    requestedPackage = r.requestedVrComponent;
2250                    userId = r.userId;
2251                    callingPackage = r.info.getComponentName();
2252                    if (mInVrMode != vrMode) {
2253                        mInVrMode = vrMode;
2254                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2255                    }
2256                }
2257                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2258            } break;
2259            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2260                final ActivityRecord r = (ActivityRecord) msg.obj;
2261                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2262                if (needsVrMode) {
2263                    VrManagerInternal vrService =
2264                            LocalServices.getService(VrManagerInternal.class);
2265                    boolean enable = msg.arg1 == 1;
2266                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2267                            r.info.getComponentName());
2268                }
2269            } break;
2270            }
2271        }
2272    };
2273
2274    static final int COLLECT_PSS_BG_MSG = 1;
2275
2276    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2277        @Override
2278        public void handleMessage(Message msg) {
2279            switch (msg.what) {
2280            case COLLECT_PSS_BG_MSG: {
2281                long start = SystemClock.uptimeMillis();
2282                MemInfoReader memInfo = null;
2283                synchronized (ActivityManagerService.this) {
2284                    if (mFullPssPending) {
2285                        mFullPssPending = false;
2286                        memInfo = new MemInfoReader();
2287                    }
2288                }
2289                if (memInfo != null) {
2290                    updateCpuStatsNow();
2291                    long nativeTotalPss = 0;
2292                    synchronized (mProcessCpuTracker) {
2293                        final int N = mProcessCpuTracker.countStats();
2294                        for (int j=0; j<N; j++) {
2295                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2296                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2297                                // This is definitely an application process; skip it.
2298                                continue;
2299                            }
2300                            synchronized (mPidsSelfLocked) {
2301                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2302                                    // This is one of our own processes; skip it.
2303                                    continue;
2304                                }
2305                            }
2306                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2307                        }
2308                    }
2309                    memInfo.readMemInfo();
2310                    synchronized (ActivityManagerService.this) {
2311                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2312                                + (SystemClock.uptimeMillis()-start) + "ms");
2313                        final long cachedKb = memInfo.getCachedSizeKb();
2314                        final long freeKb = memInfo.getFreeSizeKb();
2315                        final long zramKb = memInfo.getZramTotalSizeKb();
2316                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2317                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2318                                kernelKb*1024, nativeTotalPss*1024);
2319                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2320                                nativeTotalPss);
2321                    }
2322                }
2323
2324                int num = 0;
2325                long[] tmp = new long[2];
2326                do {
2327                    ProcessRecord proc;
2328                    int procState;
2329                    int pid;
2330                    long lastPssTime;
2331                    synchronized (ActivityManagerService.this) {
2332                        if (mPendingPssProcesses.size() <= 0) {
2333                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2334                                    "Collected PSS of " + num + " processes in "
2335                                    + (SystemClock.uptimeMillis() - start) + "ms");
2336                            mPendingPssProcesses.clear();
2337                            return;
2338                        }
2339                        proc = mPendingPssProcesses.remove(0);
2340                        procState = proc.pssProcState;
2341                        lastPssTime = proc.lastPssTime;
2342                        if (proc.thread != null && procState == proc.setProcState
2343                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2344                                        < SystemClock.uptimeMillis()) {
2345                            pid = proc.pid;
2346                        } else {
2347                            proc = null;
2348                            pid = 0;
2349                        }
2350                    }
2351                    if (proc != null) {
2352                        long pss = Debug.getPss(pid, tmp, null);
2353                        synchronized (ActivityManagerService.this) {
2354                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2355                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2356                                num++;
2357                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2358                                        SystemClock.uptimeMillis());
2359                            }
2360                        }
2361                    }
2362                } while (true);
2363            }
2364            }
2365        }
2366    };
2367
2368    public void setSystemProcess() {
2369        try {
2370            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2371            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2372            ServiceManager.addService("meminfo", new MemBinder(this));
2373            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2374            ServiceManager.addService("dbinfo", new DbBinder(this));
2375            if (MONITOR_CPU_USAGE) {
2376                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2377            }
2378            ServiceManager.addService("permission", new PermissionController(this));
2379            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2380
2381            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2382                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2383            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2384
2385            synchronized (this) {
2386                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2387                app.persistent = true;
2388                app.pid = MY_PID;
2389                app.maxAdj = ProcessList.SYSTEM_ADJ;
2390                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2391                synchronized (mPidsSelfLocked) {
2392                    mPidsSelfLocked.put(app.pid, app);
2393                }
2394                updateLruProcessLocked(app, false, null);
2395                updateOomAdjLocked();
2396            }
2397        } catch (PackageManager.NameNotFoundException e) {
2398            throw new RuntimeException(
2399                    "Unable to find android system package", e);
2400        }
2401    }
2402
2403    public void setWindowManager(WindowManagerService wm) {
2404        mWindowManager = wm;
2405        mStackSupervisor.setWindowManager(wm);
2406        mActivityStarter.setWindowManager(wm);
2407    }
2408
2409    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2410        mUsageStatsService = usageStatsManager;
2411    }
2412
2413    public void startObservingNativeCrashes() {
2414        final NativeCrashListener ncl = new NativeCrashListener(this);
2415        ncl.start();
2416    }
2417
2418    public IAppOpsService getAppOpsService() {
2419        return mAppOpsService;
2420    }
2421
2422    static class MemBinder extends Binder {
2423        ActivityManagerService mActivityManagerService;
2424        MemBinder(ActivityManagerService activityManagerService) {
2425            mActivityManagerService = activityManagerService;
2426        }
2427
2428        @Override
2429        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2430            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2431                    != PackageManager.PERMISSION_GRANTED) {
2432                pw.println("Permission Denial: can't dump meminfo from from pid="
2433                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2434                        + " without permission " + android.Manifest.permission.DUMP);
2435                return;
2436            }
2437
2438            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2439        }
2440    }
2441
2442    static class GraphicsBinder extends Binder {
2443        ActivityManagerService mActivityManagerService;
2444        GraphicsBinder(ActivityManagerService activityManagerService) {
2445            mActivityManagerService = activityManagerService;
2446        }
2447
2448        @Override
2449        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2450            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2451                    != PackageManager.PERMISSION_GRANTED) {
2452                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2453                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2454                        + " without permission " + android.Manifest.permission.DUMP);
2455                return;
2456            }
2457
2458            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2459        }
2460    }
2461
2462    static class DbBinder extends Binder {
2463        ActivityManagerService mActivityManagerService;
2464        DbBinder(ActivityManagerService activityManagerService) {
2465            mActivityManagerService = activityManagerService;
2466        }
2467
2468        @Override
2469        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2470            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2471                    != PackageManager.PERMISSION_GRANTED) {
2472                pw.println("Permission Denial: can't dump dbinfo from from pid="
2473                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2474                        + " without permission " + android.Manifest.permission.DUMP);
2475                return;
2476            }
2477
2478            mActivityManagerService.dumpDbInfo(fd, pw, args);
2479        }
2480    }
2481
2482    static class CpuBinder extends Binder {
2483        ActivityManagerService mActivityManagerService;
2484        CpuBinder(ActivityManagerService activityManagerService) {
2485            mActivityManagerService = activityManagerService;
2486        }
2487
2488        @Override
2489        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2490            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2491                    != PackageManager.PERMISSION_GRANTED) {
2492                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2493                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2494                        + " without permission " + android.Manifest.permission.DUMP);
2495                return;
2496            }
2497
2498            synchronized (mActivityManagerService.mProcessCpuTracker) {
2499                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2500                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2501                        SystemClock.uptimeMillis()));
2502            }
2503        }
2504    }
2505
2506    public static final class Lifecycle extends SystemService {
2507        private final ActivityManagerService mService;
2508
2509        public Lifecycle(Context context) {
2510            super(context);
2511            mService = new ActivityManagerService(context);
2512        }
2513
2514        @Override
2515        public void onStart() {
2516            mService.start();
2517        }
2518
2519        public ActivityManagerService getService() {
2520            return mService;
2521        }
2522    }
2523
2524    // Note: This method is invoked on the main thread but may need to attach various
2525    // handlers to other threads.  So take care to be explicit about the looper.
2526    public ActivityManagerService(Context systemContext) {
2527        mContext = systemContext;
2528        mFactoryTest = FactoryTest.getMode();
2529        mSystemThread = ActivityThread.currentActivityThread();
2530
2531        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2532
2533        mHandlerThread = new ServiceThread(TAG,
2534                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2535        mHandlerThread.start();
2536        mHandler = new MainHandler(mHandlerThread.getLooper());
2537        mUiHandler = new UiHandler();
2538
2539        /* static; one-time init here */
2540        if (sKillHandler == null) {
2541            sKillThread = new ServiceThread(TAG + ":kill",
2542                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2543            sKillThread.start();
2544            sKillHandler = new KillHandler(sKillThread.getLooper());
2545        }
2546
2547        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2548                "foreground", BROADCAST_FG_TIMEOUT, false);
2549        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2550                "background", BROADCAST_BG_TIMEOUT, true);
2551        mBroadcastQueues[0] = mFgBroadcastQueue;
2552        mBroadcastQueues[1] = mBgBroadcastQueue;
2553
2554        mServices = new ActiveServices(this);
2555        mProviderMap = new ProviderMap(this);
2556        mAppErrors = new AppErrors(mContext, this);
2557
2558        // TODO: Move creation of battery stats service outside of activity manager service.
2559        File dataDir = Environment.getDataDirectory();
2560        File systemDir = new File(dataDir, "system");
2561        systemDir.mkdirs();
2562        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2563        mBatteryStatsService.getActiveStatistics().readLocked();
2564        mBatteryStatsService.scheduleWriteToDisk();
2565        mOnBattery = DEBUG_POWER ? true
2566                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2567        mBatteryStatsService.getActiveStatistics().setCallback(this);
2568
2569        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2570
2571        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2572        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2573                new IAppOpsCallback.Stub() {
2574                    @Override public void opChanged(int op, int uid, String packageName) {
2575                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2576                            if (mAppOpsService.checkOperation(op, uid, packageName)
2577                                    != AppOpsManager.MODE_ALLOWED) {
2578                                runInBackgroundDisabled(uid);
2579                            }
2580                        }
2581                    }
2582                });
2583
2584        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2585
2586        mUserController = new UserController(this);
2587
2588        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2589            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2590
2591        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2592
2593        mConfiguration.setToDefaults();
2594        mConfiguration.setLocales(LocaleList.getDefault());
2595
2596        mConfigurationSeq = mConfiguration.seq = 1;
2597        mProcessCpuTracker.init();
2598
2599        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2600        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2601        mStackSupervisor = new ActivityStackSupervisor(this);
2602        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2603        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2604
2605        mProcessCpuThread = new Thread("CpuTracker") {
2606            @Override
2607            public void run() {
2608                while (true) {
2609                    try {
2610                        try {
2611                            synchronized(this) {
2612                                final long now = SystemClock.uptimeMillis();
2613                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2614                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2615                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2616                                //        + ", write delay=" + nextWriteDelay);
2617                                if (nextWriteDelay < nextCpuDelay) {
2618                                    nextCpuDelay = nextWriteDelay;
2619                                }
2620                                if (nextCpuDelay > 0) {
2621                                    mProcessCpuMutexFree.set(true);
2622                                    this.wait(nextCpuDelay);
2623                                }
2624                            }
2625                        } catch (InterruptedException e) {
2626                        }
2627                        updateCpuStatsNow();
2628                    } catch (Exception e) {
2629                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2630                    }
2631                }
2632            }
2633        };
2634
2635        Watchdog.getInstance().addMonitor(this);
2636        Watchdog.getInstance().addThread(mHandler);
2637    }
2638
2639    public void setSystemServiceManager(SystemServiceManager mgr) {
2640        mSystemServiceManager = mgr;
2641    }
2642
2643    public void setInstaller(Installer installer) {
2644        mInstaller = installer;
2645    }
2646
2647    private void start() {
2648        Process.removeAllProcessGroups();
2649        mProcessCpuThread.start();
2650
2651        mBatteryStatsService.publish(mContext);
2652        mAppOpsService.publish(mContext);
2653        Slog.d("AppOps", "AppOpsService published");
2654        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2655    }
2656
2657    void onUserStoppedLocked(int userId) {
2658        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2659    }
2660
2661    public void initPowerManagement() {
2662        mStackSupervisor.initPowerManagement();
2663        mBatteryStatsService.initPowerManagement();
2664        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2665        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2666        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2667        mVoiceWakeLock.setReferenceCounted(false);
2668    }
2669
2670    @Override
2671    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2672            throws RemoteException {
2673        if (code == SYSPROPS_TRANSACTION) {
2674            // We need to tell all apps about the system property change.
2675            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2676            synchronized(this) {
2677                final int NP = mProcessNames.getMap().size();
2678                for (int ip=0; ip<NP; ip++) {
2679                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2680                    final int NA = apps.size();
2681                    for (int ia=0; ia<NA; ia++) {
2682                        ProcessRecord app = apps.valueAt(ia);
2683                        if (app.thread != null) {
2684                            procs.add(app.thread.asBinder());
2685                        }
2686                    }
2687                }
2688            }
2689
2690            int N = procs.size();
2691            for (int i=0; i<N; i++) {
2692                Parcel data2 = Parcel.obtain();
2693                try {
2694                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2695                } catch (RemoteException e) {
2696                }
2697                data2.recycle();
2698            }
2699        }
2700        try {
2701            return super.onTransact(code, data, reply, flags);
2702        } catch (RuntimeException e) {
2703            // The activity manager only throws security exceptions, so let's
2704            // log all others.
2705            if (!(e instanceof SecurityException)) {
2706                Slog.wtf(TAG, "Activity Manager Crash", e);
2707            }
2708            throw e;
2709        }
2710    }
2711
2712    void updateCpuStats() {
2713        final long now = SystemClock.uptimeMillis();
2714        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2715            return;
2716        }
2717        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2718            synchronized (mProcessCpuThread) {
2719                mProcessCpuThread.notify();
2720            }
2721        }
2722    }
2723
2724    void updateCpuStatsNow() {
2725        synchronized (mProcessCpuTracker) {
2726            mProcessCpuMutexFree.set(false);
2727            final long now = SystemClock.uptimeMillis();
2728            boolean haveNewCpuStats = false;
2729
2730            if (MONITOR_CPU_USAGE &&
2731                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2732                mLastCpuTime.set(now);
2733                mProcessCpuTracker.update();
2734                if (mProcessCpuTracker.hasGoodLastStats()) {
2735                    haveNewCpuStats = true;
2736                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2737                    //Slog.i(TAG, "Total CPU usage: "
2738                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2739
2740                    // Slog the cpu usage if the property is set.
2741                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2742                        int user = mProcessCpuTracker.getLastUserTime();
2743                        int system = mProcessCpuTracker.getLastSystemTime();
2744                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2745                        int irq = mProcessCpuTracker.getLastIrqTime();
2746                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2747                        int idle = mProcessCpuTracker.getLastIdleTime();
2748
2749                        int total = user + system + iowait + irq + softIrq + idle;
2750                        if (total == 0) total = 1;
2751
2752                        EventLog.writeEvent(EventLogTags.CPU,
2753                                ((user+system+iowait+irq+softIrq) * 100) / total,
2754                                (user * 100) / total,
2755                                (system * 100) / total,
2756                                (iowait * 100) / total,
2757                                (irq * 100) / total,
2758                                (softIrq * 100) / total);
2759                    }
2760                }
2761            }
2762
2763            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2764            synchronized(bstats) {
2765                synchronized(mPidsSelfLocked) {
2766                    if (haveNewCpuStats) {
2767                        if (bstats.startAddingCpuLocked()) {
2768                            int totalUTime = 0;
2769                            int totalSTime = 0;
2770                            final int N = mProcessCpuTracker.countStats();
2771                            for (int i=0; i<N; i++) {
2772                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2773                                if (!st.working) {
2774                                    continue;
2775                                }
2776                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2777                                totalUTime += st.rel_utime;
2778                                totalSTime += st.rel_stime;
2779                                if (pr != null) {
2780                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2781                                    if (ps == null || !ps.isActive()) {
2782                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2783                                                pr.info.uid, pr.processName);
2784                                    }
2785                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2786                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2787                                } else {
2788                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2789                                    if (ps == null || !ps.isActive()) {
2790                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2791                                                bstats.mapUid(st.uid), st.name);
2792                                    }
2793                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2794                                }
2795                            }
2796                            final int userTime = mProcessCpuTracker.getLastUserTime();
2797                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2798                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2799                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2800                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2801                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2802                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2803                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2804                        }
2805                    }
2806                }
2807
2808                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2809                    mLastWriteTime = now;
2810                    mBatteryStatsService.scheduleWriteToDisk();
2811                }
2812            }
2813        }
2814    }
2815
2816    @Override
2817    public void batteryNeedsCpuUpdate() {
2818        updateCpuStatsNow();
2819    }
2820
2821    @Override
2822    public void batteryPowerChanged(boolean onBattery) {
2823        // When plugging in, update the CPU stats first before changing
2824        // the plug state.
2825        updateCpuStatsNow();
2826        synchronized (this) {
2827            synchronized(mPidsSelfLocked) {
2828                mOnBattery = DEBUG_POWER ? true : onBattery;
2829            }
2830        }
2831    }
2832
2833    @Override
2834    public void batterySendBroadcast(Intent intent) {
2835        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2836                AppOpsManager.OP_NONE, null, false, false,
2837                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2838    }
2839
2840    /**
2841     * Initialize the application bind args. These are passed to each
2842     * process when the bindApplication() IPC is sent to the process. They're
2843     * lazily setup to make sure the services are running when they're asked for.
2844     */
2845    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2846        if (mAppBindArgs == null) {
2847            mAppBindArgs = new HashMap<>();
2848
2849            // Isolated processes won't get this optimization, so that we don't
2850            // violate the rules about which services they have access to.
2851            if (!isolated) {
2852                // Setup the application init args
2853                mAppBindArgs.put("package", ServiceManager.getService("package"));
2854                mAppBindArgs.put("window", ServiceManager.getService("window"));
2855                mAppBindArgs.put(Context.ALARM_SERVICE,
2856                        ServiceManager.getService(Context.ALARM_SERVICE));
2857            }
2858        }
2859        return mAppBindArgs;
2860    }
2861
2862    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2863        if (r == null || mFocusedActivity == r) {
2864            return false;
2865        }
2866
2867        if (!r.isFocusable()) {
2868            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2869            return false;
2870        }
2871
2872        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2873
2874        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2875        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2876                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2877        mDoingSetFocusedActivity = true;
2878
2879        final ActivityRecord last = mFocusedActivity;
2880        mFocusedActivity = r;
2881        if (r.task.isApplicationTask()) {
2882            if (mCurAppTimeTracker != r.appTimeTracker) {
2883                // We are switching app tracking.  Complete the current one.
2884                if (mCurAppTimeTracker != null) {
2885                    mCurAppTimeTracker.stop();
2886                    mHandler.obtainMessage(
2887                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2888                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2889                    mCurAppTimeTracker = null;
2890                }
2891                if (r.appTimeTracker != null) {
2892                    mCurAppTimeTracker = r.appTimeTracker;
2893                    startTimeTrackingFocusedActivityLocked();
2894                }
2895            } else {
2896                startTimeTrackingFocusedActivityLocked();
2897            }
2898        } else {
2899            r.appTimeTracker = null;
2900        }
2901        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2902        // TODO: Probably not, because we don't want to resume voice on switching
2903        // back to this activity
2904        if (r.task.voiceInteractor != null) {
2905            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2906        } else {
2907            finishRunningVoiceLocked();
2908            IVoiceInteractionSession session;
2909            if (last != null && ((session = last.task.voiceSession) != null
2910                    || (session = last.voiceSession) != null)) {
2911                // We had been in a voice interaction session, but now focused has
2912                // move to something different.  Just finish the session, we can't
2913                // return to it and retain the proper state and synchronization with
2914                // the voice interaction service.
2915                finishVoiceTask(session);
2916            }
2917        }
2918        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2919            mWindowManager.setFocusedApp(r.appToken, true);
2920        }
2921        applyUpdateLockStateLocked(r);
2922        applyUpdateVrModeLocked(r);
2923        if (mFocusedActivity.userId != mLastFocusedUserId) {
2924            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2925            mHandler.obtainMessage(
2926                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2927            mLastFocusedUserId = mFocusedActivity.userId;
2928        }
2929
2930        // Log a warning if the focused app is changed during the process. This could
2931        // indicate a problem of the focus setting logic!
2932        if (mFocusedActivity != r) Slog.w(TAG,
2933                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2934        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2935
2936        EventLogTags.writeAmFocusedActivity(
2937                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2938                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2939                reason);
2940        return true;
2941    }
2942
2943    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2944        if (mFocusedActivity != goingAway) {
2945            return;
2946        }
2947
2948        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2949        if (focusedStack != null) {
2950            final ActivityRecord top = focusedStack.topActivity();
2951            if (top != null && top.userId != mLastFocusedUserId) {
2952                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2953                mHandler.sendMessage(
2954                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2955                mLastFocusedUserId = top.userId;
2956            }
2957        }
2958
2959        // Try to move focus to another activity if possible.
2960        if (setFocusedActivityLocked(
2961                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2962            return;
2963        }
2964
2965        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2966                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2967        mFocusedActivity = null;
2968        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2969    }
2970
2971    @Override
2972    public void setFocusedStack(int stackId) {
2973        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2974        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2975        final long callingId = Binder.clearCallingIdentity();
2976        try {
2977            synchronized (this) {
2978                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2979                if (stack == null) {
2980                    return;
2981                }
2982                final ActivityRecord r = stack.topRunningActivityLocked();
2983                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2984                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2985                }
2986            }
2987        } finally {
2988            Binder.restoreCallingIdentity(callingId);
2989        }
2990    }
2991
2992    @Override
2993    public void setFocusedTask(int taskId) {
2994        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2995        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2996        final long callingId = Binder.clearCallingIdentity();
2997        try {
2998            synchronized (this) {
2999                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3000                if (task == null) {
3001                    return;
3002                }
3003                final ActivityRecord r = task.topRunningActivityLocked();
3004                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3005                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3006                }
3007            }
3008        } finally {
3009            Binder.restoreCallingIdentity(callingId);
3010        }
3011    }
3012
3013    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3014    @Override
3015    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3016        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3017        synchronized (this) {
3018            if (listener != null) {
3019                mTaskStackListeners.register(listener);
3020            }
3021        }
3022    }
3023
3024    @Override
3025    public void notifyActivityDrawn(IBinder token) {
3026        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3027        synchronized (this) {
3028            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3029            if (r != null) {
3030                r.task.stack.notifyActivityDrawnLocked(r);
3031            }
3032        }
3033    }
3034
3035    final void applyUpdateLockStateLocked(ActivityRecord r) {
3036        // Modifications to the UpdateLock state are done on our handler, outside
3037        // the activity manager's locks.  The new state is determined based on the
3038        // state *now* of the relevant activity record.  The object is passed to
3039        // the handler solely for logging detail, not to be consulted/modified.
3040        final boolean nextState = r != null && r.immersive;
3041        mHandler.sendMessage(
3042                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3043    }
3044
3045    final void applyUpdateVrModeLocked(ActivityRecord r) {
3046        mHandler.sendMessage(
3047                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3048    }
3049
3050    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3051        mHandler.sendMessage(
3052                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3053    }
3054
3055    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3056        Message msg = Message.obtain();
3057        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3058        msg.obj = r.task.askedCompatMode ? null : r;
3059        mUiHandler.sendMessage(msg);
3060    }
3061
3062    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3063            String what, Object obj, ProcessRecord srcApp) {
3064        app.lastActivityTime = now;
3065
3066        if (app.activities.size() > 0) {
3067            // Don't want to touch dependent processes that are hosting activities.
3068            return index;
3069        }
3070
3071        int lrui = mLruProcesses.lastIndexOf(app);
3072        if (lrui < 0) {
3073            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3074                    + what + " " + obj + " from " + srcApp);
3075            return index;
3076        }
3077
3078        if (lrui >= index) {
3079            // Don't want to cause this to move dependent processes *back* in the
3080            // list as if they were less frequently used.
3081            return index;
3082        }
3083
3084        if (lrui >= mLruProcessActivityStart) {
3085            // Don't want to touch dependent processes that are hosting activities.
3086            return index;
3087        }
3088
3089        mLruProcesses.remove(lrui);
3090        if (index > 0) {
3091            index--;
3092        }
3093        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3094                + " in LRU list: " + app);
3095        mLruProcesses.add(index, app);
3096        return index;
3097    }
3098
3099    static void killProcessGroup(int uid, int pid) {
3100        if (sKillHandler != null) {
3101            sKillHandler.sendMessage(
3102                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3103        } else {
3104            Slog.w(TAG, "Asked to kill process group before system bringup!");
3105            Process.killProcessGroup(uid, pid);
3106        }
3107    }
3108
3109    final void removeLruProcessLocked(ProcessRecord app) {
3110        int lrui = mLruProcesses.lastIndexOf(app);
3111        if (lrui >= 0) {
3112            if (!app.killed) {
3113                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3114                Process.killProcessQuiet(app.pid);
3115                killProcessGroup(app.uid, app.pid);
3116            }
3117            if (lrui <= mLruProcessActivityStart) {
3118                mLruProcessActivityStart--;
3119            }
3120            if (lrui <= mLruProcessServiceStart) {
3121                mLruProcessServiceStart--;
3122            }
3123            mLruProcesses.remove(lrui);
3124        }
3125    }
3126
3127    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3128            ProcessRecord client) {
3129        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3130                || app.treatLikeActivity;
3131        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3132        if (!activityChange && hasActivity) {
3133            // The process has activities, so we are only allowing activity-based adjustments
3134            // to move it.  It should be kept in the front of the list with other
3135            // processes that have activities, and we don't want those to change their
3136            // order except due to activity operations.
3137            return;
3138        }
3139
3140        mLruSeq++;
3141        final long now = SystemClock.uptimeMillis();
3142        app.lastActivityTime = now;
3143
3144        // First a quick reject: if the app is already at the position we will
3145        // put it, then there is nothing to do.
3146        if (hasActivity) {
3147            final int N = mLruProcesses.size();
3148            if (N > 0 && mLruProcesses.get(N-1) == app) {
3149                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3150                return;
3151            }
3152        } else {
3153            if (mLruProcessServiceStart > 0
3154                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3155                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3156                return;
3157            }
3158        }
3159
3160        int lrui = mLruProcesses.lastIndexOf(app);
3161
3162        if (app.persistent && lrui >= 0) {
3163            // We don't care about the position of persistent processes, as long as
3164            // they are in the list.
3165            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3166            return;
3167        }
3168
3169        /* In progress: compute new position first, so we can avoid doing work
3170           if the process is not actually going to move.  Not yet working.
3171        int addIndex;
3172        int nextIndex;
3173        boolean inActivity = false, inService = false;
3174        if (hasActivity) {
3175            // Process has activities, put it at the very tipsy-top.
3176            addIndex = mLruProcesses.size();
3177            nextIndex = mLruProcessServiceStart;
3178            inActivity = true;
3179        } else if (hasService) {
3180            // Process has services, put it at the top of the service list.
3181            addIndex = mLruProcessActivityStart;
3182            nextIndex = mLruProcessServiceStart;
3183            inActivity = true;
3184            inService = true;
3185        } else  {
3186            // Process not otherwise of interest, it goes to the top of the non-service area.
3187            addIndex = mLruProcessServiceStart;
3188            if (client != null) {
3189                int clientIndex = mLruProcesses.lastIndexOf(client);
3190                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3191                        + app);
3192                if (clientIndex >= 0 && addIndex > clientIndex) {
3193                    addIndex = clientIndex;
3194                }
3195            }
3196            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3197        }
3198
3199        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3200                + mLruProcessActivityStart + "): " + app);
3201        */
3202
3203        if (lrui >= 0) {
3204            if (lrui < mLruProcessActivityStart) {
3205                mLruProcessActivityStart--;
3206            }
3207            if (lrui < mLruProcessServiceStart) {
3208                mLruProcessServiceStart--;
3209            }
3210            /*
3211            if (addIndex > lrui) {
3212                addIndex--;
3213            }
3214            if (nextIndex > lrui) {
3215                nextIndex--;
3216            }
3217            */
3218            mLruProcesses.remove(lrui);
3219        }
3220
3221        /*
3222        mLruProcesses.add(addIndex, app);
3223        if (inActivity) {
3224            mLruProcessActivityStart++;
3225        }
3226        if (inService) {
3227            mLruProcessActivityStart++;
3228        }
3229        */
3230
3231        int nextIndex;
3232        if (hasActivity) {
3233            final int N = mLruProcesses.size();
3234            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3235                // Process doesn't have activities, but has clients with
3236                // activities...  move it up, but one below the top (the top
3237                // should always have a real activity).
3238                if (DEBUG_LRU) Slog.d(TAG_LRU,
3239                        "Adding to second-top of LRU activity list: " + app);
3240                mLruProcesses.add(N - 1, app);
3241                // To keep it from spamming the LRU list (by making a bunch of clients),
3242                // we will push down any other entries owned by the app.
3243                final int uid = app.info.uid;
3244                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3245                    ProcessRecord subProc = mLruProcesses.get(i);
3246                    if (subProc.info.uid == uid) {
3247                        // We want to push this one down the list.  If the process after
3248                        // it is for the same uid, however, don't do so, because we don't
3249                        // want them internally to be re-ordered.
3250                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3251                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3252                                    "Pushing uid " + uid + " swapping at " + i + ": "
3253                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3254                            ProcessRecord tmp = mLruProcesses.get(i);
3255                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3256                            mLruProcesses.set(i - 1, tmp);
3257                            i--;
3258                        }
3259                    } else {
3260                        // A gap, we can stop here.
3261                        break;
3262                    }
3263                }
3264            } else {
3265                // Process has activities, put it at the very tipsy-top.
3266                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3267                mLruProcesses.add(app);
3268            }
3269            nextIndex = mLruProcessServiceStart;
3270        } else if (hasService) {
3271            // Process has services, put it at the top of the service list.
3272            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3273            mLruProcesses.add(mLruProcessActivityStart, app);
3274            nextIndex = mLruProcessServiceStart;
3275            mLruProcessActivityStart++;
3276        } else  {
3277            // Process not otherwise of interest, it goes to the top of the non-service area.
3278            int index = mLruProcessServiceStart;
3279            if (client != null) {
3280                // If there is a client, don't allow the process to be moved up higher
3281                // in the list than that client.
3282                int clientIndex = mLruProcesses.lastIndexOf(client);
3283                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3284                        + " when updating " + app);
3285                if (clientIndex <= lrui) {
3286                    // Don't allow the client index restriction to push it down farther in the
3287                    // list than it already is.
3288                    clientIndex = lrui;
3289                }
3290                if (clientIndex >= 0 && index > clientIndex) {
3291                    index = clientIndex;
3292                }
3293            }
3294            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3295            mLruProcesses.add(index, app);
3296            nextIndex = index-1;
3297            mLruProcessActivityStart++;
3298            mLruProcessServiceStart++;
3299        }
3300
3301        // If the app is currently using a content provider or service,
3302        // bump those processes as well.
3303        for (int j=app.connections.size()-1; j>=0; j--) {
3304            ConnectionRecord cr = app.connections.valueAt(j);
3305            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3306                    && cr.binding.service.app != null
3307                    && cr.binding.service.app.lruSeq != mLruSeq
3308                    && !cr.binding.service.app.persistent) {
3309                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3310                        "service connection", cr, app);
3311            }
3312        }
3313        for (int j=app.conProviders.size()-1; j>=0; j--) {
3314            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3315            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3316                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3317                        "provider reference", cpr, app);
3318            }
3319        }
3320    }
3321
3322    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3323        if (uid == Process.SYSTEM_UID) {
3324            // The system gets to run in any process.  If there are multiple
3325            // processes with the same uid, just pick the first (this
3326            // should never happen).
3327            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3328            if (procs == null) return null;
3329            final int procCount = procs.size();
3330            for (int i = 0; i < procCount; i++) {
3331                final int procUid = procs.keyAt(i);
3332                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3333                    // Don't use an app process or different user process for system component.
3334                    continue;
3335                }
3336                return procs.valueAt(i);
3337            }
3338        }
3339        ProcessRecord proc = mProcessNames.get(processName, uid);
3340        if (false && proc != null && !keepIfLarge
3341                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3342                && proc.lastCachedPss >= 4000) {
3343            // Turn this condition on to cause killing to happen regularly, for testing.
3344            if (proc.baseProcessTracker != null) {
3345                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3346            }
3347            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3348        } else if (proc != null && !keepIfLarge
3349                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3350                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3351            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3352            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3353                if (proc.baseProcessTracker != null) {
3354                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3355                }
3356                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3357            }
3358        }
3359        return proc;
3360    }
3361
3362    void notifyPackageUse(String packageName, int reason) {
3363        IPackageManager pm = AppGlobals.getPackageManager();
3364        try {
3365            pm.notifyPackageUse(packageName, reason);
3366        } catch (RemoteException e) {
3367        }
3368    }
3369
3370    boolean isNextTransitionForward() {
3371        int transit = mWindowManager.getPendingAppTransition();
3372        return transit == TRANSIT_ACTIVITY_OPEN
3373                || transit == TRANSIT_TASK_OPEN
3374                || transit == TRANSIT_TASK_TO_FRONT;
3375    }
3376
3377    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3378            String processName, String abiOverride, int uid, Runnable crashHandler) {
3379        synchronized(this) {
3380            ApplicationInfo info = new ApplicationInfo();
3381            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3382            // For isolated processes, the former contains the parent's uid and the latter the
3383            // actual uid of the isolated process.
3384            // In the special case introduced by this method (which is, starting an isolated
3385            // process directly from the SystemServer without an actual parent app process) the
3386            // closest thing to a parent's uid is SYSTEM_UID.
3387            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3388            // the |isolated| logic in the ProcessRecord constructor.
3389            info.uid = Process.SYSTEM_UID;
3390            info.processName = processName;
3391            info.className = entryPoint;
3392            info.packageName = "android";
3393            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3394                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3395                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3396                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3397                    crashHandler);
3398            return proc != null ? proc.pid : 0;
3399        }
3400    }
3401
3402    final ProcessRecord startProcessLocked(String processName,
3403            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3404            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3405            boolean isolated, boolean keepIfLarge) {
3406        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3407                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3408                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3409                null /* crashHandler */);
3410    }
3411
3412    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3413            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3414            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3415            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3416        long startTime = SystemClock.elapsedRealtime();
3417        ProcessRecord app;
3418        if (!isolated) {
3419            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3420            checkTime(startTime, "startProcess: after getProcessRecord");
3421
3422            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3423                // If we are in the background, then check to see if this process
3424                // is bad.  If so, we will just silently fail.
3425                if (mAppErrors.isBadProcessLocked(info)) {
3426                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3427                            + "/" + info.processName);
3428                    return null;
3429                }
3430            } else {
3431                // When the user is explicitly starting a process, then clear its
3432                // crash count so that we won't make it bad until they see at
3433                // least one crash dialog again, and make the process good again
3434                // if it had been bad.
3435                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3436                        + "/" + info.processName);
3437                mAppErrors.resetProcessCrashTimeLocked(info);
3438                if (mAppErrors.isBadProcessLocked(info)) {
3439                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3440                            UserHandle.getUserId(info.uid), info.uid,
3441                            info.processName);
3442                    mAppErrors.clearBadProcessLocked(info);
3443                    if (app != null) {
3444                        app.bad = false;
3445                    }
3446                }
3447            }
3448        } else {
3449            // If this is an isolated process, it can't re-use an existing process.
3450            app = null;
3451        }
3452
3453        // app launch boost for big.little configurations
3454        // use cpusets to migrate freshly launched tasks to big cores
3455        synchronized(ActivityManagerService.this) {
3456            nativeMigrateToBoost();
3457            mIsBoosted = true;
3458            mBoostStartTime = SystemClock.uptimeMillis();
3459            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3460            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3461        }
3462
3463        // We don't have to do anything more if:
3464        // (1) There is an existing application record; and
3465        // (2) The caller doesn't think it is dead, OR there is no thread
3466        //     object attached to it so we know it couldn't have crashed; and
3467        // (3) There is a pid assigned to it, so it is either starting or
3468        //     already running.
3469        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3470                + " app=" + app + " knownToBeDead=" + knownToBeDead
3471                + " thread=" + (app != null ? app.thread : null)
3472                + " pid=" + (app != null ? app.pid : -1));
3473        if (app != null && app.pid > 0) {
3474            if (!knownToBeDead || app.thread == null) {
3475                // We already have the app running, or are waiting for it to
3476                // come up (we have a pid but not yet its thread), so keep it.
3477                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3478                // If this is a new package in the process, add the package to the list
3479                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3480                checkTime(startTime, "startProcess: done, added package to proc");
3481                return app;
3482            }
3483
3484            // An application record is attached to a previous process,
3485            // clean it up now.
3486            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3487            checkTime(startTime, "startProcess: bad proc running, killing");
3488            killProcessGroup(app.uid, app.pid);
3489            handleAppDiedLocked(app, true, true);
3490            checkTime(startTime, "startProcess: done killing old proc");
3491        }
3492
3493        String hostingNameStr = hostingName != null
3494                ? hostingName.flattenToShortString() : null;
3495
3496        if (app == null) {
3497            checkTime(startTime, "startProcess: creating new process record");
3498            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3499            if (app == null) {
3500                Slog.w(TAG, "Failed making new process record for "
3501                        + processName + "/" + info.uid + " isolated=" + isolated);
3502                return null;
3503            }
3504            app.crashHandler = crashHandler;
3505            checkTime(startTime, "startProcess: done creating new process record");
3506        } else {
3507            // If this is a new package in the process, add the package to the list
3508            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3509            checkTime(startTime, "startProcess: added package to existing proc");
3510        }
3511
3512        // If the system is not ready yet, then hold off on starting this
3513        // process until it is.
3514        if (!mProcessesReady
3515                && !isAllowedWhileBooting(info)
3516                && !allowWhileBooting) {
3517            if (!mProcessesOnHold.contains(app)) {
3518                mProcessesOnHold.add(app);
3519            }
3520            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3521                    "System not ready, putting on hold: " + app);
3522            checkTime(startTime, "startProcess: returning with proc on hold");
3523            return app;
3524        }
3525
3526        checkTime(startTime, "startProcess: stepping in to startProcess");
3527        startProcessLocked(
3528                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3529        checkTime(startTime, "startProcess: done starting proc!");
3530        return (app.pid != 0) ? app : null;
3531    }
3532
3533    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3534        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3535    }
3536
3537    private final void startProcessLocked(ProcessRecord app,
3538            String hostingType, String hostingNameStr) {
3539        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3540                null /* entryPoint */, null /* entryPointArgs */);
3541    }
3542
3543    private final void startProcessLocked(ProcessRecord app, String hostingType,
3544            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3545        long startTime = SystemClock.elapsedRealtime();
3546        if (app.pid > 0 && app.pid != MY_PID) {
3547            checkTime(startTime, "startProcess: removing from pids map");
3548            synchronized (mPidsSelfLocked) {
3549                mPidsSelfLocked.remove(app.pid);
3550                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3551            }
3552            checkTime(startTime, "startProcess: done removing from pids map");
3553            app.setPid(0);
3554        }
3555
3556        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3557                "startProcessLocked removing on hold: " + app);
3558        mProcessesOnHold.remove(app);
3559
3560        checkTime(startTime, "startProcess: starting to update cpu stats");
3561        updateCpuStats();
3562        checkTime(startTime, "startProcess: done updating cpu stats");
3563
3564        try {
3565            try {
3566                final int userId = UserHandle.getUserId(app.uid);
3567                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3568            } catch (RemoteException e) {
3569                throw e.rethrowAsRuntimeException();
3570            }
3571
3572            int uid = app.uid;
3573            int[] gids = null;
3574            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3575            if (!app.isolated) {
3576                int[] permGids = null;
3577                try {
3578                    checkTime(startTime, "startProcess: getting gids from package manager");
3579                    final IPackageManager pm = AppGlobals.getPackageManager();
3580                    permGids = pm.getPackageGids(app.info.packageName,
3581                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3582                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3583                            MountServiceInternal.class);
3584                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3585                            app.info.packageName);
3586                } catch (RemoteException e) {
3587                    throw e.rethrowAsRuntimeException();
3588                }
3589
3590                /*
3591                 * Add shared application and profile GIDs so applications can share some
3592                 * resources like shared libraries and access user-wide resources
3593                 */
3594                if (ArrayUtils.isEmpty(permGids)) {
3595                    gids = new int[2];
3596                } else {
3597                    gids = new int[permGids.length + 2];
3598                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3599                }
3600                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3601                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3602            }
3603            checkTime(startTime, "startProcess: building args");
3604            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3605                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3606                        && mTopComponent != null
3607                        && app.processName.equals(mTopComponent.getPackageName())) {
3608                    uid = 0;
3609                }
3610                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3611                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3612                    uid = 0;
3613                }
3614            }
3615            int debugFlags = 0;
3616            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3617                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3618                // Also turn on CheckJNI for debuggable apps. It's quite
3619                // awkward to turn on otherwise.
3620                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3621            }
3622            // Run the app in safe mode if its manifest requests so or the
3623            // system is booted in safe mode.
3624            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3625                mSafeMode == true) {
3626                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3627            }
3628            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3629                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3630            }
3631            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3632            if ("true".equals(genDebugInfoProperty)) {
3633                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3634            }
3635            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3636                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3637            }
3638            if ("1".equals(SystemProperties.get("debug.assert"))) {
3639                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3640            }
3641            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3642                // Enable all debug flags required by the native debugger.
3643                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3644                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3645                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3646                mNativeDebuggingApp = null;
3647            }
3648
3649            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3650            if (requiredAbi == null) {
3651                requiredAbi = Build.SUPPORTED_ABIS[0];
3652            }
3653
3654            String instructionSet = null;
3655            if (app.info.primaryCpuAbi != null) {
3656                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3657            }
3658
3659            app.gids = gids;
3660            app.requiredAbi = requiredAbi;
3661            app.instructionSet = instructionSet;
3662
3663            // Start the process.  It will either succeed and return a result containing
3664            // the PID of the new process, or else throw a RuntimeException.
3665            boolean isActivityProcess = (entryPoint == null);
3666            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3667            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3668                    app.processName);
3669            checkTime(startTime, "startProcess: asking zygote to start proc");
3670            Process.ProcessStartResult startResult = Process.start(entryPoint,
3671                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3672                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3673                    app.info.dataDir, entryPointArgs);
3674            checkTime(startTime, "startProcess: returned from zygote!");
3675            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3676
3677            if (app.isolated) {
3678                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3679            }
3680            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3681            checkTime(startTime, "startProcess: done updating battery stats");
3682
3683            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3684                    UserHandle.getUserId(uid), startResult.pid, uid,
3685                    app.processName, hostingType,
3686                    hostingNameStr != null ? hostingNameStr : "");
3687
3688            try {
3689                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3690                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3691            } catch (RemoteException ex) {
3692                // Ignore
3693            }
3694
3695            if (app.persistent) {
3696                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3697            }
3698
3699            checkTime(startTime, "startProcess: building log message");
3700            StringBuilder buf = mStringBuilder;
3701            buf.setLength(0);
3702            buf.append("Start proc ");
3703            buf.append(startResult.pid);
3704            buf.append(':');
3705            buf.append(app.processName);
3706            buf.append('/');
3707            UserHandle.formatUid(buf, uid);
3708            if (!isActivityProcess) {
3709                buf.append(" [");
3710                buf.append(entryPoint);
3711                buf.append("]");
3712            }
3713            buf.append(" for ");
3714            buf.append(hostingType);
3715            if (hostingNameStr != null) {
3716                buf.append(" ");
3717                buf.append(hostingNameStr);
3718            }
3719            Slog.i(TAG, buf.toString());
3720            app.setPid(startResult.pid);
3721            app.usingWrapper = startResult.usingWrapper;
3722            app.removed = false;
3723            app.killed = false;
3724            app.killedByAm = false;
3725            checkTime(startTime, "startProcess: starting to update pids map");
3726            synchronized (mPidsSelfLocked) {
3727                this.mPidsSelfLocked.put(startResult.pid, app);
3728                if (isActivityProcess) {
3729                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3730                    msg.obj = app;
3731                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3732                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3733                }
3734            }
3735            checkTime(startTime, "startProcess: done updating pids map");
3736        } catch (RuntimeException e) {
3737            Slog.e(TAG, "Failure starting process " + app.processName, e);
3738
3739            // Something went very wrong while trying to start this process; one
3740            // common case is when the package is frozen due to an active
3741            // upgrade. To recover, clean up any active bookkeeping related to
3742            // starting this process. (We already invoked this method once when
3743            // the package was initially frozen through KILL_APPLICATION_MSG, so
3744            // it doesn't hurt to use it again.)
3745            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3746                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3747        }
3748    }
3749
3750    void updateUsageStats(ActivityRecord component, boolean resumed) {
3751        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3752                "updateUsageStats: comp=" + component + "res=" + resumed);
3753        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3754        if (resumed) {
3755            if (mUsageStatsService != null) {
3756                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3757                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3758            }
3759            synchronized (stats) {
3760                stats.noteActivityResumedLocked(component.app.uid);
3761            }
3762        } else {
3763            if (mUsageStatsService != null) {
3764                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3765                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3766            }
3767            synchronized (stats) {
3768                stats.noteActivityPausedLocked(component.app.uid);
3769            }
3770        }
3771    }
3772
3773    Intent getHomeIntent() {
3774        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3775        intent.setComponent(mTopComponent);
3776        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3777        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3778            intent.addCategory(Intent.CATEGORY_HOME);
3779        }
3780        return intent;
3781    }
3782
3783    boolean startHomeActivityLocked(int userId, String reason) {
3784        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3785                && mTopAction == null) {
3786            // We are running in factory test mode, but unable to find
3787            // the factory test app, so just sit around displaying the
3788            // error message and don't try to start anything.
3789            return false;
3790        }
3791        Intent intent = getHomeIntent();
3792        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3793        if (aInfo != null) {
3794            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3795            // Don't do this if the home app is currently being
3796            // instrumented.
3797            aInfo = new ActivityInfo(aInfo);
3798            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3799            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3800                    aInfo.applicationInfo.uid, true);
3801            if (app == null || app.instrumentationClass == null) {
3802                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3803                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3804            }
3805        } else {
3806            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3807        }
3808
3809        return true;
3810    }
3811
3812    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3813        ActivityInfo ai = null;
3814        ComponentName comp = intent.getComponent();
3815        try {
3816            if (comp != null) {
3817                // Factory test.
3818                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3819            } else {
3820                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3821                        intent,
3822                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3823                        flags, userId);
3824
3825                if (info != null) {
3826                    ai = info.activityInfo;
3827                }
3828            }
3829        } catch (RemoteException e) {
3830            // ignore
3831        }
3832
3833        return ai;
3834    }
3835
3836    /**
3837     * Starts the "new version setup screen" if appropriate.
3838     */
3839    void startSetupActivityLocked() {
3840        // Only do this once per boot.
3841        if (mCheckedForSetup) {
3842            return;
3843        }
3844
3845        // We will show this screen if the current one is a different
3846        // version than the last one shown, and we are not running in
3847        // low-level factory test mode.
3848        final ContentResolver resolver = mContext.getContentResolver();
3849        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3850                Settings.Global.getInt(resolver,
3851                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3852            mCheckedForSetup = true;
3853
3854            // See if we should be showing the platform update setup UI.
3855            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3856            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3857                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3858            if (!ris.isEmpty()) {
3859                final ResolveInfo ri = ris.get(0);
3860                String vers = ri.activityInfo.metaData != null
3861                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3862                        : null;
3863                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3864                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3865                            Intent.METADATA_SETUP_VERSION);
3866                }
3867                String lastVers = Settings.Secure.getString(
3868                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3869                if (vers != null && !vers.equals(lastVers)) {
3870                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3871                    intent.setComponent(new ComponentName(
3872                            ri.activityInfo.packageName, ri.activityInfo.name));
3873                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3874                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3875                            null, 0, 0, 0, null, false, false, null, null, null);
3876                }
3877            }
3878        }
3879    }
3880
3881    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3882        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3883    }
3884
3885    void enforceNotIsolatedCaller(String caller) {
3886        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3887            throw new SecurityException("Isolated process not allowed to call " + caller);
3888        }
3889    }
3890
3891    void enforceShellRestriction(String restriction, int userHandle) {
3892        if (Binder.getCallingUid() == Process.SHELL_UID) {
3893            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3894                throw new SecurityException("Shell does not have permission to access user "
3895                        + userHandle);
3896            }
3897        }
3898    }
3899
3900    @Override
3901    public int getFrontActivityScreenCompatMode() {
3902        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3903        synchronized (this) {
3904            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3905        }
3906    }
3907
3908    @Override
3909    public void setFrontActivityScreenCompatMode(int mode) {
3910        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3911                "setFrontActivityScreenCompatMode");
3912        synchronized (this) {
3913            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3914        }
3915    }
3916
3917    @Override
3918    public int getPackageScreenCompatMode(String packageName) {
3919        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3920        synchronized (this) {
3921            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3922        }
3923    }
3924
3925    @Override
3926    public void setPackageScreenCompatMode(String packageName, int mode) {
3927        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3928                "setPackageScreenCompatMode");
3929        synchronized (this) {
3930            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3931        }
3932    }
3933
3934    @Override
3935    public boolean getPackageAskScreenCompat(String packageName) {
3936        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3937        synchronized (this) {
3938            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3939        }
3940    }
3941
3942    @Override
3943    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3944        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3945                "setPackageAskScreenCompat");
3946        synchronized (this) {
3947            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3948        }
3949    }
3950
3951    private boolean hasUsageStatsPermission(String callingPackage) {
3952        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3953                Binder.getCallingUid(), callingPackage);
3954        if (mode == AppOpsManager.MODE_DEFAULT) {
3955            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3956                    == PackageManager.PERMISSION_GRANTED;
3957        }
3958        return mode == AppOpsManager.MODE_ALLOWED;
3959    }
3960
3961    @Override
3962    public int getPackageProcessState(String packageName, String callingPackage) {
3963        if (!hasUsageStatsPermission(callingPackage)) {
3964            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3965                    "getPackageProcessState");
3966        }
3967
3968        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3969        synchronized (this) {
3970            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3971                final ProcessRecord proc = mLruProcesses.get(i);
3972                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3973                        || procState > proc.setProcState) {
3974                    boolean found = false;
3975                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3976                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3977                            procState = proc.setProcState;
3978                            found = true;
3979                        }
3980                    }
3981                    if (proc.pkgDeps != null && !found) {
3982                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3983                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3984                                procState = proc.setProcState;
3985                                break;
3986                            }
3987                        }
3988                    }
3989                }
3990            }
3991        }
3992        return procState;
3993    }
3994
3995    @Override
3996    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3997        synchronized (this) {
3998            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3999            if (app == null) {
4000                return false;
4001            }
4002            if (app.trimMemoryLevel < level && app.thread != null &&
4003                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4004                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4005                try {
4006                    app.thread.scheduleTrimMemory(level);
4007                    app.trimMemoryLevel = level;
4008                    return true;
4009                } catch (RemoteException e) {
4010                    // Fallthrough to failure case.
4011                }
4012            }
4013        }
4014        return false;
4015    }
4016
4017    private void dispatchProcessesChanged() {
4018        int N;
4019        synchronized (this) {
4020            N = mPendingProcessChanges.size();
4021            if (mActiveProcessChanges.length < N) {
4022                mActiveProcessChanges = new ProcessChangeItem[N];
4023            }
4024            mPendingProcessChanges.toArray(mActiveProcessChanges);
4025            mPendingProcessChanges.clear();
4026            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4027                    "*** Delivering " + N + " process changes");
4028        }
4029
4030        int i = mProcessObservers.beginBroadcast();
4031        while (i > 0) {
4032            i--;
4033            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4034            if (observer != null) {
4035                try {
4036                    for (int j=0; j<N; j++) {
4037                        ProcessChangeItem item = mActiveProcessChanges[j];
4038                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4039                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4040                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4041                                    + item.uid + ": " + item.foregroundActivities);
4042                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4043                                    item.foregroundActivities);
4044                        }
4045                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4046                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4047                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4048                                    + ": " + item.processState);
4049                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4050                        }
4051                    }
4052                } catch (RemoteException e) {
4053                }
4054            }
4055        }
4056        mProcessObservers.finishBroadcast();
4057
4058        synchronized (this) {
4059            for (int j=0; j<N; j++) {
4060                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4061            }
4062        }
4063    }
4064
4065    private void dispatchProcessDied(int pid, int uid) {
4066        int i = mProcessObservers.beginBroadcast();
4067        while (i > 0) {
4068            i--;
4069            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4070            if (observer != null) {
4071                try {
4072                    observer.onProcessDied(pid, uid);
4073                } catch (RemoteException e) {
4074                }
4075            }
4076        }
4077        mProcessObservers.finishBroadcast();
4078    }
4079
4080    private void dispatchUidsChanged() {
4081        int N;
4082        synchronized (this) {
4083            N = mPendingUidChanges.size();
4084            if (mActiveUidChanges.length < N) {
4085                mActiveUidChanges = new UidRecord.ChangeItem[N];
4086            }
4087            for (int i=0; i<N; i++) {
4088                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4089                mActiveUidChanges[i] = change;
4090                if (change.uidRecord != null) {
4091                    change.uidRecord.pendingChange = null;
4092                    change.uidRecord = null;
4093                }
4094            }
4095            mPendingUidChanges.clear();
4096            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4097                    "*** Delivering " + N + " uid changes");
4098        }
4099
4100        if (mLocalPowerManager != null) {
4101            for (int j=0; j<N; j++) {
4102                UidRecord.ChangeItem item = mActiveUidChanges[j];
4103                if (item.change == UidRecord.CHANGE_GONE
4104                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4105                    mLocalPowerManager.uidGone(item.uid);
4106                } else {
4107                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4108                }
4109            }
4110        }
4111
4112        int i = mUidObservers.beginBroadcast();
4113        while (i > 0) {
4114            i--;
4115            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4116            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4117            if (observer != null) {
4118                try {
4119                    for (int j=0; j<N; j++) {
4120                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4121                        final int change = item.change;
4122                        UidRecord validateUid = null;
4123                        if (VALIDATE_UID_STATES && i == 0) {
4124                            validateUid = mValidateUids.get(item.uid);
4125                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4126                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4127                                validateUid = new UidRecord(item.uid);
4128                                mValidateUids.put(item.uid, validateUid);
4129                            }
4130                        }
4131                        if (change == UidRecord.CHANGE_IDLE
4132                                || change == UidRecord.CHANGE_GONE_IDLE) {
4133                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4134                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4135                                        "UID idle uid=" + item.uid);
4136                                observer.onUidIdle(item.uid);
4137                            }
4138                            if (VALIDATE_UID_STATES && i == 0) {
4139                                if (validateUid != null) {
4140                                    validateUid.idle = true;
4141                                }
4142                            }
4143                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4144                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4145                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4146                                        "UID active uid=" + item.uid);
4147                                observer.onUidActive(item.uid);
4148                            }
4149                            if (VALIDATE_UID_STATES && i == 0) {
4150                                validateUid.idle = false;
4151                            }
4152                        }
4153                        if (change == UidRecord.CHANGE_GONE
4154                                || change == UidRecord.CHANGE_GONE_IDLE) {
4155                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4156                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4157                                        "UID gone uid=" + item.uid);
4158                                observer.onUidGone(item.uid);
4159                            }
4160                            if (VALIDATE_UID_STATES && i == 0) {
4161                                if (validateUid != null) {
4162                                    mValidateUids.remove(item.uid);
4163                                }
4164                            }
4165                        } else {
4166                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4167                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4168                                        "UID CHANGED uid=" + item.uid
4169                                                + ": " + item.processState);
4170                                observer.onUidStateChanged(item.uid, item.processState);
4171                            }
4172                            if (VALIDATE_UID_STATES && i == 0) {
4173                                validateUid.curProcState = validateUid.setProcState
4174                                        = item.processState;
4175                            }
4176                        }
4177                    }
4178                } catch (RemoteException e) {
4179                }
4180            }
4181        }
4182        mUidObservers.finishBroadcast();
4183
4184        synchronized (this) {
4185            for (int j=0; j<N; j++) {
4186                mAvailUidChanges.add(mActiveUidChanges[j]);
4187            }
4188        }
4189    }
4190
4191    @Override
4192    public final int startActivity(IApplicationThread caller, String callingPackage,
4193            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4194            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4195        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4196                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4197                UserHandle.getCallingUserId());
4198    }
4199
4200    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4201        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4202        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4203                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4204                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4205
4206        // TODO: Switch to user app stacks here.
4207        String mimeType = intent.getType();
4208        final Uri data = intent.getData();
4209        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4210            mimeType = getProviderMimeType(data, userId);
4211        }
4212        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4213
4214        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4215        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4216                null, 0, 0, null, null, null, null, false, userId, container, null);
4217    }
4218
4219    @Override
4220    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4221            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4222            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4223        enforceNotIsolatedCaller("startActivity");
4224        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4225                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4226        // TODO: Switch to user app stacks here.
4227        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4228                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4229                profilerInfo, null, null, bOptions, false, userId, null, null);
4230    }
4231
4232    @Override
4233    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4234            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4235            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4236            int userId) {
4237
4238        // This is very dangerous -- it allows you to perform a start activity (including
4239        // permission grants) as any app that may launch one of your own activities.  So
4240        // we will only allow this to be done from activities that are part of the core framework,
4241        // and then only when they are running as the system.
4242        final ActivityRecord sourceRecord;
4243        final int targetUid;
4244        final String targetPackage;
4245        synchronized (this) {
4246            if (resultTo == null) {
4247                throw new SecurityException("Must be called from an activity");
4248            }
4249            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4250            if (sourceRecord == null) {
4251                throw new SecurityException("Called with bad activity token: " + resultTo);
4252            }
4253            if (!sourceRecord.info.packageName.equals("android")) {
4254                throw new SecurityException(
4255                        "Must be called from an activity that is declared in the android package");
4256            }
4257            if (sourceRecord.app == null) {
4258                throw new SecurityException("Called without a process attached to activity");
4259            }
4260            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4261                // This is still okay, as long as this activity is running under the
4262                // uid of the original calling activity.
4263                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4264                    throw new SecurityException(
4265                            "Calling activity in uid " + sourceRecord.app.uid
4266                                    + " must be system uid or original calling uid "
4267                                    + sourceRecord.launchedFromUid);
4268                }
4269            }
4270            if (ignoreTargetSecurity) {
4271                if (intent.getComponent() == null) {
4272                    throw new SecurityException(
4273                            "Component must be specified with ignoreTargetSecurity");
4274                }
4275                if (intent.getSelector() != null) {
4276                    throw new SecurityException(
4277                            "Selector not allowed with ignoreTargetSecurity");
4278                }
4279            }
4280            targetUid = sourceRecord.launchedFromUid;
4281            targetPackage = sourceRecord.launchedFromPackage;
4282        }
4283
4284        if (userId == UserHandle.USER_NULL) {
4285            userId = UserHandle.getUserId(sourceRecord.app.uid);
4286        }
4287
4288        // TODO: Switch to user app stacks here.
4289        try {
4290            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4291                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4292                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4293            return ret;
4294        } catch (SecurityException e) {
4295            // XXX need to figure out how to propagate to original app.
4296            // A SecurityException here is generally actually a fault of the original
4297            // calling activity (such as a fairly granting permissions), so propagate it
4298            // back to them.
4299            /*
4300            StringBuilder msg = new StringBuilder();
4301            msg.append("While launching");
4302            msg.append(intent.toString());
4303            msg.append(": ");
4304            msg.append(e.getMessage());
4305            */
4306            throw e;
4307        }
4308    }
4309
4310    @Override
4311    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4312            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4313            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4314        enforceNotIsolatedCaller("startActivityAndWait");
4315        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4316                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4317        WaitResult res = new WaitResult();
4318        // TODO: Switch to user app stacks here.
4319        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4320                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4321                bOptions, false, userId, null, null);
4322        return res;
4323    }
4324
4325    @Override
4326    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4327            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4328            int startFlags, Configuration config, Bundle bOptions, int userId) {
4329        enforceNotIsolatedCaller("startActivityWithConfig");
4330        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4331                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4332        // TODO: Switch to user app stacks here.
4333        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4334                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4335                null, null, config, bOptions, false, userId, null, null);
4336        return ret;
4337    }
4338
4339    @Override
4340    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4341            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4342            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4343            throws TransactionTooLargeException {
4344        enforceNotIsolatedCaller("startActivityIntentSender");
4345        // Refuse possible leaked file descriptors
4346        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4347            throw new IllegalArgumentException("File descriptors passed in Intent");
4348        }
4349
4350        IIntentSender sender = intent.getTarget();
4351        if (!(sender instanceof PendingIntentRecord)) {
4352            throw new IllegalArgumentException("Bad PendingIntent object");
4353        }
4354
4355        PendingIntentRecord pir = (PendingIntentRecord)sender;
4356
4357        synchronized (this) {
4358            // If this is coming from the currently resumed activity, it is
4359            // effectively saying that app switches are allowed at this point.
4360            final ActivityStack stack = getFocusedStack();
4361            if (stack.mResumedActivity != null &&
4362                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4363                mAppSwitchesAllowedTime = 0;
4364            }
4365        }
4366        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4367                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4368        return ret;
4369    }
4370
4371    @Override
4372    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4373            Intent intent, String resolvedType, IVoiceInteractionSession session,
4374            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4375            Bundle bOptions, int userId) {
4376        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4377                != PackageManager.PERMISSION_GRANTED) {
4378            String msg = "Permission Denial: startVoiceActivity() from pid="
4379                    + Binder.getCallingPid()
4380                    + ", uid=" + Binder.getCallingUid()
4381                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4382            Slog.w(TAG, msg);
4383            throw new SecurityException(msg);
4384        }
4385        if (session == null || interactor == null) {
4386            throw new NullPointerException("null session or interactor");
4387        }
4388        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4389                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4390        // TODO: Switch to user app stacks here.
4391        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4392                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4393                null, bOptions, false, userId, null, null);
4394    }
4395
4396    @Override
4397    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4398            throws RemoteException {
4399        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4400        synchronized (this) {
4401            ActivityRecord activity = getFocusedStack().topActivity();
4402            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4403                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4404            }
4405            if (mRunningVoice != null || activity.task.voiceSession != null
4406                    || activity.voiceSession != null) {
4407                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4408                return;
4409            }
4410            if (activity.pendingVoiceInteractionStart) {
4411                Slog.w(TAG, "Pending start of voice interaction already.");
4412                return;
4413            }
4414            activity.pendingVoiceInteractionStart = true;
4415        }
4416        LocalServices.getService(VoiceInteractionManagerInternal.class)
4417                .startLocalVoiceInteraction(callingActivity, options);
4418    }
4419
4420    @Override
4421    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4422        LocalServices.getService(VoiceInteractionManagerInternal.class)
4423                .stopLocalVoiceInteraction(callingActivity);
4424    }
4425
4426    @Override
4427    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4428        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4429                .supportsLocalVoiceInteraction();
4430    }
4431
4432    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4433            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4434        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4435        if (activityToCallback == null) return;
4436        activityToCallback.setVoiceSessionLocked(voiceSession);
4437
4438        // Inform the activity
4439        try {
4440            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4441                    voiceInteractor);
4442            long token = Binder.clearCallingIdentity();
4443            try {
4444                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4445            } finally {
4446                Binder.restoreCallingIdentity(token);
4447            }
4448            // TODO: VI Should we cache the activity so that it's easier to find later
4449            // rather than scan through all the stacks and activities?
4450        } catch (RemoteException re) {
4451            activityToCallback.clearVoiceSessionLocked();
4452            // TODO: VI Should this terminate the voice session?
4453        }
4454    }
4455
4456    @Override
4457    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4458        synchronized (this) {
4459            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4460                if (keepAwake) {
4461                    mVoiceWakeLock.acquire();
4462                } else {
4463                    mVoiceWakeLock.release();
4464                }
4465            }
4466        }
4467    }
4468
4469    @Override
4470    public boolean startNextMatchingActivity(IBinder callingActivity,
4471            Intent intent, Bundle bOptions) {
4472        // Refuse possible leaked file descriptors
4473        if (intent != null && intent.hasFileDescriptors() == true) {
4474            throw new IllegalArgumentException("File descriptors passed in Intent");
4475        }
4476        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4477
4478        synchronized (this) {
4479            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4480            if (r == null) {
4481                ActivityOptions.abort(options);
4482                return false;
4483            }
4484            if (r.app == null || r.app.thread == null) {
4485                // The caller is not running...  d'oh!
4486                ActivityOptions.abort(options);
4487                return false;
4488            }
4489            intent = new Intent(intent);
4490            // The caller is not allowed to change the data.
4491            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4492            // And we are resetting to find the next component...
4493            intent.setComponent(null);
4494
4495            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4496
4497            ActivityInfo aInfo = null;
4498            try {
4499                List<ResolveInfo> resolves =
4500                    AppGlobals.getPackageManager().queryIntentActivities(
4501                            intent, r.resolvedType,
4502                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4503                            UserHandle.getCallingUserId()).getList();
4504
4505                // Look for the original activity in the list...
4506                final int N = resolves != null ? resolves.size() : 0;
4507                for (int i=0; i<N; i++) {
4508                    ResolveInfo rInfo = resolves.get(i);
4509                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4510                            && rInfo.activityInfo.name.equals(r.info.name)) {
4511                        // We found the current one...  the next matching is
4512                        // after it.
4513                        i++;
4514                        if (i<N) {
4515                            aInfo = resolves.get(i).activityInfo;
4516                        }
4517                        if (debug) {
4518                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4519                                    + "/" + r.info.name);
4520                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4521                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4522                        }
4523                        break;
4524                    }
4525                }
4526            } catch (RemoteException e) {
4527            }
4528
4529            if (aInfo == null) {
4530                // Nobody who is next!
4531                ActivityOptions.abort(options);
4532                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4533                return false;
4534            }
4535
4536            intent.setComponent(new ComponentName(
4537                    aInfo.applicationInfo.packageName, aInfo.name));
4538            intent.setFlags(intent.getFlags()&~(
4539                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4540                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4541                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4542                    Intent.FLAG_ACTIVITY_NEW_TASK));
4543
4544            // Okay now we need to start the new activity, replacing the
4545            // currently running activity.  This is a little tricky because
4546            // we want to start the new one as if the current one is finished,
4547            // but not finish the current one first so that there is no flicker.
4548            // And thus...
4549            final boolean wasFinishing = r.finishing;
4550            r.finishing = true;
4551
4552            // Propagate reply information over to the new activity.
4553            final ActivityRecord resultTo = r.resultTo;
4554            final String resultWho = r.resultWho;
4555            final int requestCode = r.requestCode;
4556            r.resultTo = null;
4557            if (resultTo != null) {
4558                resultTo.removeResultsLocked(r, resultWho, requestCode);
4559            }
4560
4561            final long origId = Binder.clearCallingIdentity();
4562            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4563                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4564                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4565                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4566                    false, false, null, null, null);
4567            Binder.restoreCallingIdentity(origId);
4568
4569            r.finishing = wasFinishing;
4570            if (res != ActivityManager.START_SUCCESS) {
4571                return false;
4572            }
4573            return true;
4574        }
4575    }
4576
4577    @Override
4578    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4579        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4580            String msg = "Permission Denial: startActivityFromRecents called without " +
4581                    START_TASKS_FROM_RECENTS;
4582            Slog.w(TAG, msg);
4583            throw new SecurityException(msg);
4584        }
4585        final long origId = Binder.clearCallingIdentity();
4586        try {
4587            synchronized (this) {
4588                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4589            }
4590        } finally {
4591            Binder.restoreCallingIdentity(origId);
4592        }
4593    }
4594
4595    final int startActivityInPackage(int uid, String callingPackage,
4596            Intent intent, String resolvedType, IBinder resultTo,
4597            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4598            IActivityContainer container, TaskRecord inTask) {
4599
4600        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4601                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4602
4603        // TODO: Switch to user app stacks here.
4604        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4605                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4606                null, null, null, bOptions, false, userId, container, inTask);
4607        return ret;
4608    }
4609
4610    @Override
4611    public final int startActivities(IApplicationThread caller, String callingPackage,
4612            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4613            int userId) {
4614        enforceNotIsolatedCaller("startActivities");
4615        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4616                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4617        // TODO: Switch to user app stacks here.
4618        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4619                resolvedTypes, resultTo, bOptions, userId);
4620        return ret;
4621    }
4622
4623    final int startActivitiesInPackage(int uid, String callingPackage,
4624            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4625            Bundle bOptions, int userId) {
4626
4627        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4628                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4629        // TODO: Switch to user app stacks here.
4630        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4631                resultTo, bOptions, userId);
4632        return ret;
4633    }
4634
4635    @Override
4636    public void reportActivityFullyDrawn(IBinder token) {
4637        synchronized (this) {
4638            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4639            if (r == null) {
4640                return;
4641            }
4642            r.reportFullyDrawnLocked();
4643        }
4644    }
4645
4646    @Override
4647    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4648        synchronized (this) {
4649            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4650            if (r == null) {
4651                return;
4652            }
4653            TaskRecord task = r.task;
4654            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4655                // Fixed screen orientation isn't supported when activities aren't in full screen
4656                // mode.
4657                return;
4658            }
4659            final long origId = Binder.clearCallingIdentity();
4660            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4661            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4662                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4663            if (config != null) {
4664                r.frozenBeforeDestroy = true;
4665                if (!updateConfigurationLocked(config, r, false)) {
4666                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4667                }
4668            }
4669            Binder.restoreCallingIdentity(origId);
4670        }
4671    }
4672
4673    @Override
4674    public int getRequestedOrientation(IBinder token) {
4675        synchronized (this) {
4676            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4677            if (r == null) {
4678                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4679            }
4680            return mWindowManager.getAppOrientation(r.appToken);
4681        }
4682    }
4683
4684    /**
4685     * This is the internal entry point for handling Activity.finish().
4686     *
4687     * @param token The Binder token referencing the Activity we want to finish.
4688     * @param resultCode Result code, if any, from this Activity.
4689     * @param resultData Result data (Intent), if any, from this Activity.
4690     * @param finishTask Whether to finish the task associated with this Activity.
4691     *
4692     * @return Returns true if the activity successfully finished, or false if it is still running.
4693     */
4694    @Override
4695    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4696            int finishTask) {
4697        // Refuse possible leaked file descriptors
4698        if (resultData != null && resultData.hasFileDescriptors() == true) {
4699            throw new IllegalArgumentException("File descriptors passed in Intent");
4700        }
4701
4702        synchronized(this) {
4703            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4704            if (r == null) {
4705                return true;
4706            }
4707            // Keep track of the root activity of the task before we finish it
4708            TaskRecord tr = r.task;
4709            ActivityRecord rootR = tr.getRootActivity();
4710            if (rootR == null) {
4711                Slog.w(TAG, "Finishing task with all activities already finished");
4712            }
4713            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4714            // finish.
4715            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4716                    mStackSupervisor.isLastLockedTask(tr)) {
4717                Slog.i(TAG, "Not finishing task in lock task mode");
4718                mStackSupervisor.showLockTaskToast();
4719                return false;
4720            }
4721            if (mController != null) {
4722                // Find the first activity that is not finishing.
4723                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4724                if (next != null) {
4725                    // ask watcher if this is allowed
4726                    boolean resumeOK = true;
4727                    try {
4728                        resumeOK = mController.activityResuming(next.packageName);
4729                    } catch (RemoteException e) {
4730                        mController = null;
4731                        Watchdog.getInstance().setActivityController(null);
4732                    }
4733
4734                    if (!resumeOK) {
4735                        Slog.i(TAG, "Not finishing activity because controller resumed");
4736                        return false;
4737                    }
4738                }
4739            }
4740            final long origId = Binder.clearCallingIdentity();
4741            try {
4742                boolean res;
4743                final boolean finishWithRootActivity =
4744                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4745                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4746                        || (finishWithRootActivity && r == rootR)) {
4747                    // If requested, remove the task that is associated to this activity only if it
4748                    // was the root activity in the task. The result code and data is ignored
4749                    // because we don't support returning them across task boundaries. Also, to
4750                    // keep backwards compatibility we remove the task from recents when finishing
4751                    // task with root activity.
4752                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4753                    if (!res) {
4754                        Slog.i(TAG, "Removing task failed to finish activity");
4755                    }
4756                } else {
4757                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4758                            resultData, "app-request", true);
4759                    if (!res) {
4760                        Slog.i(TAG, "Failed to finish by app-request");
4761                    }
4762                }
4763                return res;
4764            } finally {
4765                Binder.restoreCallingIdentity(origId);
4766            }
4767        }
4768    }
4769
4770    @Override
4771    public final void finishHeavyWeightApp() {
4772        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4773                != PackageManager.PERMISSION_GRANTED) {
4774            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4775                    + Binder.getCallingPid()
4776                    + ", uid=" + Binder.getCallingUid()
4777                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4778            Slog.w(TAG, msg);
4779            throw new SecurityException(msg);
4780        }
4781
4782        synchronized(this) {
4783            if (mHeavyWeightProcess == null) {
4784                return;
4785            }
4786
4787            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4788            for (int i = 0; i < activities.size(); i++) {
4789                ActivityRecord r = activities.get(i);
4790                if (!r.finishing && r.isInStackLocked()) {
4791                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4792                            null, "finish-heavy", true);
4793                }
4794            }
4795
4796            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4797                    mHeavyWeightProcess.userId, 0));
4798            mHeavyWeightProcess = null;
4799        }
4800    }
4801
4802    @Override
4803    public void crashApplication(int uid, int initialPid, String packageName,
4804            String message) {
4805        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4806                != PackageManager.PERMISSION_GRANTED) {
4807            String msg = "Permission Denial: crashApplication() from pid="
4808                    + Binder.getCallingPid()
4809                    + ", uid=" + Binder.getCallingUid()
4810                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4811            Slog.w(TAG, msg);
4812            throw new SecurityException(msg);
4813        }
4814
4815        synchronized(this) {
4816            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4817        }
4818    }
4819
4820    @Override
4821    public final void finishSubActivity(IBinder token, String resultWho,
4822            int requestCode) {
4823        synchronized(this) {
4824            final long origId = Binder.clearCallingIdentity();
4825            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4826            if (r != null) {
4827                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4828            }
4829            Binder.restoreCallingIdentity(origId);
4830        }
4831    }
4832
4833    @Override
4834    public boolean finishActivityAffinity(IBinder token) {
4835        synchronized(this) {
4836            final long origId = Binder.clearCallingIdentity();
4837            try {
4838                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4839                if (r == null) {
4840                    return false;
4841                }
4842
4843                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4844                // can finish.
4845                final TaskRecord task = r.task;
4846                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4847                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4848                    mStackSupervisor.showLockTaskToast();
4849                    return false;
4850                }
4851                return task.stack.finishActivityAffinityLocked(r);
4852            } finally {
4853                Binder.restoreCallingIdentity(origId);
4854            }
4855        }
4856    }
4857
4858    @Override
4859    public void finishVoiceTask(IVoiceInteractionSession session) {
4860        synchronized (this) {
4861            final long origId = Binder.clearCallingIdentity();
4862            try {
4863                // TODO: VI Consider treating local voice interactions and voice tasks
4864                // differently here
4865                mStackSupervisor.finishVoiceTask(session);
4866            } finally {
4867                Binder.restoreCallingIdentity(origId);
4868            }
4869        }
4870
4871    }
4872
4873    @Override
4874    public boolean releaseActivityInstance(IBinder token) {
4875        synchronized(this) {
4876            final long origId = Binder.clearCallingIdentity();
4877            try {
4878                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4879                if (r == null) {
4880                    return false;
4881                }
4882                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4883            } finally {
4884                Binder.restoreCallingIdentity(origId);
4885            }
4886        }
4887    }
4888
4889    @Override
4890    public void releaseSomeActivities(IApplicationThread appInt) {
4891        synchronized(this) {
4892            final long origId = Binder.clearCallingIdentity();
4893            try {
4894                ProcessRecord app = getRecordForAppLocked(appInt);
4895                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4896            } finally {
4897                Binder.restoreCallingIdentity(origId);
4898            }
4899        }
4900    }
4901
4902    @Override
4903    public boolean willActivityBeVisible(IBinder token) {
4904        synchronized(this) {
4905            ActivityStack stack = ActivityRecord.getStackLocked(token);
4906            if (stack != null) {
4907                return stack.willActivityBeVisibleLocked(token);
4908            }
4909            return false;
4910        }
4911    }
4912
4913    @Override
4914    public void overridePendingTransition(IBinder token, String packageName,
4915            int enterAnim, int exitAnim) {
4916        synchronized(this) {
4917            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4918            if (self == null) {
4919                return;
4920            }
4921
4922            final long origId = Binder.clearCallingIdentity();
4923
4924            if (self.state == ActivityState.RESUMED
4925                    || self.state == ActivityState.PAUSING) {
4926                mWindowManager.overridePendingAppTransition(packageName,
4927                        enterAnim, exitAnim, null);
4928            }
4929
4930            Binder.restoreCallingIdentity(origId);
4931        }
4932    }
4933
4934    /**
4935     * Main function for removing an existing process from the activity manager
4936     * as a result of that process going away.  Clears out all connections
4937     * to the process.
4938     */
4939    private final void handleAppDiedLocked(ProcessRecord app,
4940            boolean restarting, boolean allowRestart) {
4941        int pid = app.pid;
4942        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4943        if (!kept && !restarting) {
4944            removeLruProcessLocked(app);
4945            if (pid > 0) {
4946                ProcessList.remove(pid);
4947            }
4948        }
4949
4950        if (mProfileProc == app) {
4951            clearProfilerLocked();
4952        }
4953
4954        // Remove this application's activities from active lists.
4955        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4956
4957        app.activities.clear();
4958
4959        if (app.instrumentationClass != null) {
4960            Slog.w(TAG, "Crash of app " + app.processName
4961                  + " running instrumentation " + app.instrumentationClass);
4962            Bundle info = new Bundle();
4963            info.putString("shortMsg", "Process crashed.");
4964            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4965        }
4966
4967        if (!restarting && hasVisibleActivities
4968                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4969            // If there was nothing to resume, and we are not already restarting this process, but
4970            // there is a visible activity that is hosted by the process...  then make sure all
4971            // visible activities are running, taking care of restarting this process.
4972            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4973        }
4974    }
4975
4976    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4977        IBinder threadBinder = thread.asBinder();
4978        // Find the application record.
4979        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4980            ProcessRecord rec = mLruProcesses.get(i);
4981            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4982                return i;
4983            }
4984        }
4985        return -1;
4986    }
4987
4988    final ProcessRecord getRecordForAppLocked(
4989            IApplicationThread thread) {
4990        if (thread == null) {
4991            return null;
4992        }
4993
4994        int appIndex = getLRURecordIndexForAppLocked(thread);
4995        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4996    }
4997
4998    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4999        // If there are no longer any background processes running,
5000        // and the app that died was not running instrumentation,
5001        // then tell everyone we are now low on memory.
5002        boolean haveBg = false;
5003        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5004            ProcessRecord rec = mLruProcesses.get(i);
5005            if (rec.thread != null
5006                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5007                haveBg = true;
5008                break;
5009            }
5010        }
5011
5012        if (!haveBg) {
5013            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5014            if (doReport) {
5015                long now = SystemClock.uptimeMillis();
5016                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5017                    doReport = false;
5018                } else {
5019                    mLastMemUsageReportTime = now;
5020                }
5021            }
5022            final ArrayList<ProcessMemInfo> memInfos
5023                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5024            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5025            long now = SystemClock.uptimeMillis();
5026            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5027                ProcessRecord rec = mLruProcesses.get(i);
5028                if (rec == dyingProc || rec.thread == null) {
5029                    continue;
5030                }
5031                if (doReport) {
5032                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5033                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5034                }
5035                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5036                    // The low memory report is overriding any current
5037                    // state for a GC request.  Make sure to do
5038                    // heavy/important/visible/foreground processes first.
5039                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5040                        rec.lastRequestedGc = 0;
5041                    } else {
5042                        rec.lastRequestedGc = rec.lastLowMemory;
5043                    }
5044                    rec.reportLowMemory = true;
5045                    rec.lastLowMemory = now;
5046                    mProcessesToGc.remove(rec);
5047                    addProcessToGcListLocked(rec);
5048                }
5049            }
5050            if (doReport) {
5051                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5052                mHandler.sendMessage(msg);
5053            }
5054            scheduleAppGcsLocked();
5055        }
5056    }
5057
5058    final void appDiedLocked(ProcessRecord app) {
5059       appDiedLocked(app, app.pid, app.thread, false);
5060    }
5061
5062    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5063            boolean fromBinderDied) {
5064        // First check if this ProcessRecord is actually active for the pid.
5065        synchronized (mPidsSelfLocked) {
5066            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5067            if (curProc != app) {
5068                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5069                return;
5070            }
5071        }
5072
5073        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5074        synchronized (stats) {
5075            stats.noteProcessDiedLocked(app.info.uid, pid);
5076        }
5077
5078        if (!app.killed) {
5079            if (!fromBinderDied) {
5080                Process.killProcessQuiet(pid);
5081            }
5082            killProcessGroup(app.uid, pid);
5083            app.killed = true;
5084        }
5085
5086        // Clean up already done if the process has been re-started.
5087        if (app.pid == pid && app.thread != null &&
5088                app.thread.asBinder() == thread.asBinder()) {
5089            boolean doLowMem = app.instrumentationClass == null;
5090            boolean doOomAdj = doLowMem;
5091            if (!app.killedByAm) {
5092                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5093                        + ") has died");
5094                mAllowLowerMemLevel = true;
5095            } else {
5096                // Note that we always want to do oom adj to update our state with the
5097                // new number of procs.
5098                mAllowLowerMemLevel = false;
5099                doLowMem = false;
5100            }
5101            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5102            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5103                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5104            handleAppDiedLocked(app, false, true);
5105
5106            if (doOomAdj) {
5107                updateOomAdjLocked();
5108            }
5109            if (doLowMem) {
5110                doLowMemReportIfNeededLocked(app);
5111            }
5112        } else if (app.pid != pid) {
5113            // A new process has already been started.
5114            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5115                    + ") has died and restarted (pid " + app.pid + ").");
5116            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5117        } else if (DEBUG_PROCESSES) {
5118            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5119                    + thread.asBinder());
5120        }
5121    }
5122
5123    /**
5124     * If a stack trace dump file is configured, dump process stack traces.
5125     * @param clearTraces causes the dump file to be erased prior to the new
5126     *    traces being written, if true; when false, the new traces will be
5127     *    appended to any existing file content.
5128     * @param firstPids of dalvik VM processes to dump stack traces for first
5129     * @param lastPids of dalvik VM processes to dump stack traces for last
5130     * @param nativeProcs optional list of native process names to dump stack crawls
5131     * @return file containing stack traces, or null if no dump file is configured
5132     */
5133    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5134            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5135        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5136        if (tracesPath == null || tracesPath.length() == 0) {
5137            return null;
5138        }
5139
5140        File tracesFile = new File(tracesPath);
5141        try {
5142            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5143            tracesFile.createNewFile();
5144            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5145        } catch (IOException e) {
5146            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5147            return null;
5148        }
5149
5150        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5151        return tracesFile;
5152    }
5153
5154    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5155            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5156        // Use a FileObserver to detect when traces finish writing.
5157        // The order of traces is considered important to maintain for legibility.
5158        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5159            @Override
5160            public synchronized void onEvent(int event, String path) { notify(); }
5161        };
5162
5163        try {
5164            observer.startWatching();
5165
5166            // First collect all of the stacks of the most important pids.
5167            if (firstPids != null) {
5168                try {
5169                    int num = firstPids.size();
5170                    for (int i = 0; i < num; i++) {
5171                        synchronized (observer) {
5172                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5173                                    + firstPids.get(i));
5174                            final long sime = SystemClock.elapsedRealtime();
5175                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5176                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5177                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5178                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5179                        }
5180                    }
5181                } catch (InterruptedException e) {
5182                    Slog.wtf(TAG, e);
5183                }
5184            }
5185
5186            // Next collect the stacks of the native pids
5187            if (nativeProcs != null) {
5188                int[] pids = Process.getPidsForCommands(nativeProcs);
5189                if (pids != null) {
5190                    for (int pid : pids) {
5191                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5192                        final long sime = SystemClock.elapsedRealtime();
5193                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5194                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5195                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5196                    }
5197                }
5198            }
5199
5200            // Lastly, measure CPU usage.
5201            if (processCpuTracker != null) {
5202                processCpuTracker.init();
5203                System.gc();
5204                processCpuTracker.update();
5205                try {
5206                    synchronized (processCpuTracker) {
5207                        processCpuTracker.wait(500); // measure over 1/2 second.
5208                    }
5209                } catch (InterruptedException e) {
5210                }
5211                processCpuTracker.update();
5212
5213                // We'll take the stack crawls of just the top apps using CPU.
5214                final int N = processCpuTracker.countWorkingStats();
5215                int numProcs = 0;
5216                for (int i=0; i<N && numProcs<5; i++) {
5217                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5218                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5219                        numProcs++;
5220                        try {
5221                            synchronized (observer) {
5222                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5223                                        + stats.pid);
5224                                final long stime = SystemClock.elapsedRealtime();
5225                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5226                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5227                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5228                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5229                            }
5230                        } catch (InterruptedException e) {
5231                            Slog.wtf(TAG, e);
5232                        }
5233                    } else if (DEBUG_ANR) {
5234                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5235                                + stats.pid);
5236                    }
5237                }
5238            }
5239        } finally {
5240            observer.stopWatching();
5241        }
5242    }
5243
5244    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5245        if (true || IS_USER_BUILD) {
5246            return;
5247        }
5248        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5249        if (tracesPath == null || tracesPath.length() == 0) {
5250            return;
5251        }
5252
5253        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5254        StrictMode.allowThreadDiskWrites();
5255        try {
5256            final File tracesFile = new File(tracesPath);
5257            final File tracesDir = tracesFile.getParentFile();
5258            final File tracesTmp = new File(tracesDir, "__tmp__");
5259            try {
5260                if (tracesFile.exists()) {
5261                    tracesTmp.delete();
5262                    tracesFile.renameTo(tracesTmp);
5263                }
5264                StringBuilder sb = new StringBuilder();
5265                Time tobj = new Time();
5266                tobj.set(System.currentTimeMillis());
5267                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5268                sb.append(": ");
5269                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5270                sb.append(" since ");
5271                sb.append(msg);
5272                FileOutputStream fos = new FileOutputStream(tracesFile);
5273                fos.write(sb.toString().getBytes());
5274                if (app == null) {
5275                    fos.write("\n*** No application process!".getBytes());
5276                }
5277                fos.close();
5278                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5279            } catch (IOException e) {
5280                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5281                return;
5282            }
5283
5284            if (app != null) {
5285                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5286                firstPids.add(app.pid);
5287                dumpStackTraces(tracesPath, firstPids, null, null, null);
5288            }
5289
5290            File lastTracesFile = null;
5291            File curTracesFile = null;
5292            for (int i=9; i>=0; i--) {
5293                String name = String.format(Locale.US, "slow%02d.txt", i);
5294                curTracesFile = new File(tracesDir, name);
5295                if (curTracesFile.exists()) {
5296                    if (lastTracesFile != null) {
5297                        curTracesFile.renameTo(lastTracesFile);
5298                    } else {
5299                        curTracesFile.delete();
5300                    }
5301                }
5302                lastTracesFile = curTracesFile;
5303            }
5304            tracesFile.renameTo(curTracesFile);
5305            if (tracesTmp.exists()) {
5306                tracesTmp.renameTo(tracesFile);
5307            }
5308        } finally {
5309            StrictMode.setThreadPolicy(oldPolicy);
5310        }
5311    }
5312
5313    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5314        if (!mLaunchWarningShown) {
5315            mLaunchWarningShown = true;
5316            mUiHandler.post(new Runnable() {
5317                @Override
5318                public void run() {
5319                    synchronized (ActivityManagerService.this) {
5320                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5321                        d.show();
5322                        mUiHandler.postDelayed(new Runnable() {
5323                            @Override
5324                            public void run() {
5325                                synchronized (ActivityManagerService.this) {
5326                                    d.dismiss();
5327                                    mLaunchWarningShown = false;
5328                                }
5329                            }
5330                        }, 4000);
5331                    }
5332                }
5333            });
5334        }
5335    }
5336
5337    @Override
5338    public boolean clearApplicationUserData(final String packageName,
5339            final IPackageDataObserver observer, int userId) {
5340        enforceNotIsolatedCaller("clearApplicationUserData");
5341        int uid = Binder.getCallingUid();
5342        int pid = Binder.getCallingPid();
5343        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5344                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5345
5346        final DevicePolicyManagerInternal dpmi = LocalServices
5347                .getService(DevicePolicyManagerInternal.class);
5348        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5349            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5350        }
5351
5352        long callingId = Binder.clearCallingIdentity();
5353        try {
5354            IPackageManager pm = AppGlobals.getPackageManager();
5355            int pkgUid = -1;
5356            synchronized(this) {
5357                try {
5358                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5359                } catch (RemoteException e) {
5360                }
5361                if (pkgUid == -1) {
5362                    Slog.w(TAG, "Invalid packageName: " + packageName);
5363                    if (observer != null) {
5364                        try {
5365                            observer.onRemoveCompleted(packageName, false);
5366                        } catch (RemoteException e) {
5367                            Slog.i(TAG, "Observer no longer exists.");
5368                        }
5369                    }
5370                    return false;
5371                }
5372                if (uid == pkgUid || checkComponentPermission(
5373                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5374                        pid, uid, -1, true)
5375                        == PackageManager.PERMISSION_GRANTED) {
5376                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5377                } else {
5378                    throw new SecurityException("PID " + pid + " does not have permission "
5379                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5380                                    + " of package " + packageName);
5381                }
5382
5383                // Remove all tasks match the cleared application package and user
5384                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5385                    final TaskRecord tr = mRecentTasks.get(i);
5386                    final String taskPackageName =
5387                            tr.getBaseIntent().getComponent().getPackageName();
5388                    if (tr.userId != userId) continue;
5389                    if (!taskPackageName.equals(packageName)) continue;
5390                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5391                }
5392            }
5393
5394            try {
5395                // Clear application user data
5396                pm.clearApplicationUserData(packageName, observer, userId);
5397
5398                synchronized(this) {
5399                    // Remove all permissions granted from/to this package
5400                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5401                }
5402
5403                // Remove all zen rules created by this package; revoke it's zen access.
5404                INotificationManager inm = NotificationManager.getService();
5405                inm.removeAutomaticZenRules(packageName);
5406                inm.setNotificationPolicyAccessGranted(packageName, false);
5407
5408                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5409                        Uri.fromParts("package", packageName, null));
5410                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5411                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5412                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5413                        null, null, 0, null, null, null, null, false, false, userId);
5414            } catch (RemoteException e) {
5415            }
5416        } finally {
5417            Binder.restoreCallingIdentity(callingId);
5418        }
5419        return true;
5420    }
5421
5422    @Override
5423    public void killBackgroundProcesses(final String packageName, int userId) {
5424        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5425                != PackageManager.PERMISSION_GRANTED &&
5426                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5427                        != PackageManager.PERMISSION_GRANTED) {
5428            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5429                    + Binder.getCallingPid()
5430                    + ", uid=" + Binder.getCallingUid()
5431                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5432            Slog.w(TAG, msg);
5433            throw new SecurityException(msg);
5434        }
5435
5436        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5437                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5438        long callingId = Binder.clearCallingIdentity();
5439        try {
5440            IPackageManager pm = AppGlobals.getPackageManager();
5441            synchronized(this) {
5442                int appId = -1;
5443                try {
5444                    appId = UserHandle.getAppId(
5445                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5446                } catch (RemoteException e) {
5447                }
5448                if (appId == -1) {
5449                    Slog.w(TAG, "Invalid packageName: " + packageName);
5450                    return;
5451                }
5452                killPackageProcessesLocked(packageName, appId, userId,
5453                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5454            }
5455        } finally {
5456            Binder.restoreCallingIdentity(callingId);
5457        }
5458    }
5459
5460    @Override
5461    public void killAllBackgroundProcesses() {
5462        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5463                != PackageManager.PERMISSION_GRANTED) {
5464            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5465                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5466                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5467            Slog.w(TAG, msg);
5468            throw new SecurityException(msg);
5469        }
5470
5471        final long callingId = Binder.clearCallingIdentity();
5472        try {
5473            synchronized (this) {
5474                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5475                final int NP = mProcessNames.getMap().size();
5476                for (int ip = 0; ip < NP; ip++) {
5477                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5478                    final int NA = apps.size();
5479                    for (int ia = 0; ia < NA; ia++) {
5480                        final ProcessRecord app = apps.valueAt(ia);
5481                        if (app.persistent) {
5482                            // We don't kill persistent processes.
5483                            continue;
5484                        }
5485                        if (app.removed) {
5486                            procs.add(app);
5487                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5488                            app.removed = true;
5489                            procs.add(app);
5490                        }
5491                    }
5492                }
5493
5494                final int N = procs.size();
5495                for (int i = 0; i < N; i++) {
5496                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5497                }
5498
5499                mAllowLowerMemLevel = true;
5500
5501                updateOomAdjLocked();
5502                doLowMemReportIfNeededLocked(null);
5503            }
5504        } finally {
5505            Binder.restoreCallingIdentity(callingId);
5506        }
5507    }
5508
5509    /**
5510     * Kills all background processes, except those matching any of the
5511     * specified properties.
5512     *
5513     * @param minTargetSdk the target SDK version at or above which to preserve
5514     *                     processes, or {@code -1} to ignore the target SDK
5515     * @param maxProcState the process state at or below which to preserve
5516     *                     processes, or {@code -1} to ignore the process state
5517     */
5518    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5519        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5520                != PackageManager.PERMISSION_GRANTED) {
5521            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5522                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5523                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5524            Slog.w(TAG, msg);
5525            throw new SecurityException(msg);
5526        }
5527
5528        final long callingId = Binder.clearCallingIdentity();
5529        try {
5530            synchronized (this) {
5531                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5532                final int NP = mProcessNames.getMap().size();
5533                for (int ip = 0; ip < NP; ip++) {
5534                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5535                    final int NA = apps.size();
5536                    for (int ia = 0; ia < NA; ia++) {
5537                        final ProcessRecord app = apps.valueAt(ia);
5538                        if (app.removed) {
5539                            procs.add(app);
5540                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5541                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5542                            app.removed = true;
5543                            procs.add(app);
5544                        }
5545                    }
5546                }
5547
5548                final int N = procs.size();
5549                for (int i = 0; i < N; i++) {
5550                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5551                }
5552            }
5553        } finally {
5554            Binder.restoreCallingIdentity(callingId);
5555        }
5556    }
5557
5558    @Override
5559    public void forceStopPackage(final String packageName, int userId) {
5560        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5561                != PackageManager.PERMISSION_GRANTED) {
5562            String msg = "Permission Denial: forceStopPackage() from pid="
5563                    + Binder.getCallingPid()
5564                    + ", uid=" + Binder.getCallingUid()
5565                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5566            Slog.w(TAG, msg);
5567            throw new SecurityException(msg);
5568        }
5569        final int callingPid = Binder.getCallingPid();
5570        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5571                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5572        long callingId = Binder.clearCallingIdentity();
5573        try {
5574            IPackageManager pm = AppGlobals.getPackageManager();
5575            synchronized(this) {
5576                int[] users = userId == UserHandle.USER_ALL
5577                        ? mUserController.getUsers() : new int[] { userId };
5578                for (int user : users) {
5579                    int pkgUid = -1;
5580                    try {
5581                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5582                                user);
5583                    } catch (RemoteException e) {
5584                    }
5585                    if (pkgUid == -1) {
5586                        Slog.w(TAG, "Invalid packageName: " + packageName);
5587                        continue;
5588                    }
5589                    try {
5590                        pm.setPackageStoppedState(packageName, true, user);
5591                    } catch (RemoteException e) {
5592                    } catch (IllegalArgumentException e) {
5593                        Slog.w(TAG, "Failed trying to unstop package "
5594                                + packageName + ": " + e);
5595                    }
5596                    if (mUserController.isUserRunningLocked(user, 0)) {
5597                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5598                    }
5599                }
5600            }
5601        } finally {
5602            Binder.restoreCallingIdentity(callingId);
5603        }
5604    }
5605
5606    @Override
5607    public void addPackageDependency(String packageName) {
5608        synchronized (this) {
5609            int callingPid = Binder.getCallingPid();
5610            if (callingPid == Process.myPid()) {
5611                //  Yeah, um, no.
5612                return;
5613            }
5614            ProcessRecord proc;
5615            synchronized (mPidsSelfLocked) {
5616                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5617            }
5618            if (proc != null) {
5619                if (proc.pkgDeps == null) {
5620                    proc.pkgDeps = new ArraySet<String>(1);
5621                }
5622                proc.pkgDeps.add(packageName);
5623            }
5624        }
5625    }
5626
5627    /*
5628     * The pkg name and app id have to be specified.
5629     */
5630    @Override
5631    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5632        if (pkg == null) {
5633            return;
5634        }
5635        // Make sure the uid is valid.
5636        if (appid < 0) {
5637            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5638            return;
5639        }
5640        int callerUid = Binder.getCallingUid();
5641        // Only the system server can kill an application
5642        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5643            // Post an aysnc message to kill the application
5644            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5645            msg.arg1 = appid;
5646            msg.arg2 = 0;
5647            Bundle bundle = new Bundle();
5648            bundle.putString("pkg", pkg);
5649            bundle.putString("reason", reason);
5650            msg.obj = bundle;
5651            mHandler.sendMessage(msg);
5652        } else {
5653            throw new SecurityException(callerUid + " cannot kill pkg: " +
5654                    pkg);
5655        }
5656    }
5657
5658    @Override
5659    public void closeSystemDialogs(String reason) {
5660        enforceNotIsolatedCaller("closeSystemDialogs");
5661
5662        final int pid = Binder.getCallingPid();
5663        final int uid = Binder.getCallingUid();
5664        final long origId = Binder.clearCallingIdentity();
5665        try {
5666            synchronized (this) {
5667                // Only allow this from foreground processes, so that background
5668                // applications can't abuse it to prevent system UI from being shown.
5669                if (uid >= Process.FIRST_APPLICATION_UID) {
5670                    ProcessRecord proc;
5671                    synchronized (mPidsSelfLocked) {
5672                        proc = mPidsSelfLocked.get(pid);
5673                    }
5674                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5675                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5676                                + " from background process " + proc);
5677                        return;
5678                    }
5679                }
5680                closeSystemDialogsLocked(reason);
5681            }
5682        } finally {
5683            Binder.restoreCallingIdentity(origId);
5684        }
5685    }
5686
5687    void closeSystemDialogsLocked(String reason) {
5688        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5689        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5690                | Intent.FLAG_RECEIVER_FOREGROUND);
5691        if (reason != null) {
5692            intent.putExtra("reason", reason);
5693        }
5694        mWindowManager.closeSystemDialogs(reason);
5695
5696        mStackSupervisor.closeSystemDialogsLocked();
5697
5698        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5699                AppOpsManager.OP_NONE, null, false, false,
5700                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5701    }
5702
5703    @Override
5704    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5705        enforceNotIsolatedCaller("getProcessMemoryInfo");
5706        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5707        for (int i=pids.length-1; i>=0; i--) {
5708            ProcessRecord proc;
5709            int oomAdj;
5710            synchronized (this) {
5711                synchronized (mPidsSelfLocked) {
5712                    proc = mPidsSelfLocked.get(pids[i]);
5713                    oomAdj = proc != null ? proc.setAdj : 0;
5714                }
5715            }
5716            infos[i] = new Debug.MemoryInfo();
5717            Debug.getMemoryInfo(pids[i], infos[i]);
5718            if (proc != null) {
5719                synchronized (this) {
5720                    if (proc.thread != null && proc.setAdj == oomAdj) {
5721                        // Record this for posterity if the process has been stable.
5722                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5723                                infos[i].getTotalUss(), false, proc.pkgList);
5724                    }
5725                }
5726            }
5727        }
5728        return infos;
5729    }
5730
5731    @Override
5732    public long[] getProcessPss(int[] pids) {
5733        enforceNotIsolatedCaller("getProcessPss");
5734        long[] pss = new long[pids.length];
5735        for (int i=pids.length-1; i>=0; i--) {
5736            ProcessRecord proc;
5737            int oomAdj;
5738            synchronized (this) {
5739                synchronized (mPidsSelfLocked) {
5740                    proc = mPidsSelfLocked.get(pids[i]);
5741                    oomAdj = proc != null ? proc.setAdj : 0;
5742                }
5743            }
5744            long[] tmpUss = new long[1];
5745            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5746            if (proc != null) {
5747                synchronized (this) {
5748                    if (proc.thread != null && proc.setAdj == oomAdj) {
5749                        // Record this for posterity if the process has been stable.
5750                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5751                    }
5752                }
5753            }
5754        }
5755        return pss;
5756    }
5757
5758    @Override
5759    public void killApplicationProcess(String processName, int uid) {
5760        if (processName == null) {
5761            return;
5762        }
5763
5764        int callerUid = Binder.getCallingUid();
5765        // Only the system server can kill an application
5766        if (callerUid == Process.SYSTEM_UID) {
5767            synchronized (this) {
5768                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5769                if (app != null && app.thread != null) {
5770                    try {
5771                        app.thread.scheduleSuicide();
5772                    } catch (RemoteException e) {
5773                        // If the other end already died, then our work here is done.
5774                    }
5775                } else {
5776                    Slog.w(TAG, "Process/uid not found attempting kill of "
5777                            + processName + " / " + uid);
5778                }
5779            }
5780        } else {
5781            throw new SecurityException(callerUid + " cannot kill app process: " +
5782                    processName);
5783        }
5784    }
5785
5786    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5787        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5788                false, true, false, false, UserHandle.getUserId(uid), reason);
5789        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5790                Uri.fromParts("package", packageName, null));
5791        if (!mProcessesReady) {
5792            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5793                    | Intent.FLAG_RECEIVER_FOREGROUND);
5794        }
5795        intent.putExtra(Intent.EXTRA_UID, uid);
5796        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5797        broadcastIntentLocked(null, null, intent,
5798                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5799                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5800    }
5801
5802
5803    private final boolean killPackageProcessesLocked(String packageName, int appId,
5804            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5805            boolean doit, boolean evenPersistent, String reason) {
5806        ArrayList<ProcessRecord> procs = new ArrayList<>();
5807
5808        // Remove all processes this package may have touched: all with the
5809        // same UID (except for the system or root user), and all whose name
5810        // matches the package name.
5811        final int NP = mProcessNames.getMap().size();
5812        for (int ip=0; ip<NP; ip++) {
5813            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5814            final int NA = apps.size();
5815            for (int ia=0; ia<NA; ia++) {
5816                ProcessRecord app = apps.valueAt(ia);
5817                if (app.persistent && !evenPersistent) {
5818                    // we don't kill persistent processes
5819                    continue;
5820                }
5821                if (app.removed) {
5822                    if (doit) {
5823                        procs.add(app);
5824                    }
5825                    continue;
5826                }
5827
5828                // Skip process if it doesn't meet our oom adj requirement.
5829                if (app.setAdj < minOomAdj) {
5830                    continue;
5831                }
5832
5833                // If no package is specified, we call all processes under the
5834                // give user id.
5835                if (packageName == null) {
5836                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5837                        continue;
5838                    }
5839                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5840                        continue;
5841                    }
5842                // Package has been specified, we want to hit all processes
5843                // that match it.  We need to qualify this by the processes
5844                // that are running under the specified app and user ID.
5845                } else {
5846                    final boolean isDep = app.pkgDeps != null
5847                            && app.pkgDeps.contains(packageName);
5848                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5849                        continue;
5850                    }
5851                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5852                        continue;
5853                    }
5854                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5855                        continue;
5856                    }
5857                }
5858
5859                // Process has passed all conditions, kill it!
5860                if (!doit) {
5861                    return true;
5862                }
5863                app.removed = true;
5864                procs.add(app);
5865            }
5866        }
5867
5868        int N = procs.size();
5869        for (int i=0; i<N; i++) {
5870            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5871        }
5872        updateOomAdjLocked();
5873        return N > 0;
5874    }
5875
5876    private void cleanupDisabledPackageComponentsLocked(
5877            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5878
5879        Set<String> disabledClasses = null;
5880        boolean packageDisabled = false;
5881        IPackageManager pm = AppGlobals.getPackageManager();
5882
5883        if (changedClasses == null) {
5884            // Nothing changed...
5885            return;
5886        }
5887
5888        // Determine enable/disable state of the package and its components.
5889        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5890        for (int i = changedClasses.length - 1; i >= 0; i--) {
5891            final String changedClass = changedClasses[i];
5892
5893            if (changedClass.equals(packageName)) {
5894                try {
5895                    // Entire package setting changed
5896                    enabled = pm.getApplicationEnabledSetting(packageName,
5897                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5898                } catch (Exception e) {
5899                    // No such package/component; probably racing with uninstall.  In any
5900                    // event it means we have nothing further to do here.
5901                    return;
5902                }
5903                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5904                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5905                if (packageDisabled) {
5906                    // Entire package is disabled.
5907                    // No need to continue to check component states.
5908                    disabledClasses = null;
5909                    break;
5910                }
5911            } else {
5912                try {
5913                    enabled = pm.getComponentEnabledSetting(
5914                            new ComponentName(packageName, changedClass),
5915                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5916                } catch (Exception e) {
5917                    // As above, probably racing with uninstall.
5918                    return;
5919                }
5920                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5921                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5922                    if (disabledClasses == null) {
5923                        disabledClasses = new ArraySet<>(changedClasses.length);
5924                    }
5925                    disabledClasses.add(changedClass);
5926                }
5927            }
5928        }
5929
5930        if (!packageDisabled && disabledClasses == null) {
5931            // Nothing to do here...
5932            return;
5933        }
5934
5935        // Clean-up disabled activities.
5936        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5937                packageName, disabledClasses, true, false, userId) && mBooted) {
5938            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5939            mStackSupervisor.scheduleIdleLocked();
5940        }
5941
5942        // Clean-up disabled tasks
5943        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5944
5945        // Clean-up disabled services.
5946        mServices.bringDownDisabledPackageServicesLocked(
5947                packageName, disabledClasses, userId, false, killProcess, true);
5948
5949        // Clean-up disabled providers.
5950        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5951        mProviderMap.collectPackageProvidersLocked(
5952                packageName, disabledClasses, true, false, userId, providers);
5953        for (int i = providers.size() - 1; i >= 0; i--) {
5954            removeDyingProviderLocked(null, providers.get(i), true);
5955        }
5956
5957        // Clean-up disabled broadcast receivers.
5958        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5959            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5960                    packageName, disabledClasses, userId, true);
5961        }
5962
5963    }
5964
5965    final boolean clearBroadcastQueueForUserLocked(int userId) {
5966        boolean didSomething = false;
5967        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5968            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5969                    null, null, userId, true);
5970        }
5971        return didSomething;
5972    }
5973
5974    final boolean forceStopPackageLocked(String packageName, int appId,
5975            boolean callerWillRestart, boolean purgeCache, boolean doit,
5976            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5977        int i;
5978
5979        if (userId == UserHandle.USER_ALL && packageName == null) {
5980            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5981        }
5982
5983        if (appId < 0 && packageName != null) {
5984            try {
5985                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5986                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5987            } catch (RemoteException e) {
5988            }
5989        }
5990
5991        if (doit) {
5992            if (packageName != null) {
5993                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5994                        + " user=" + userId + ": " + reason);
5995            } else {
5996                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5997            }
5998
5999            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6000        }
6001
6002        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6003                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6004                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6005
6006        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6007                packageName, null, doit, evenPersistent, userId)) {
6008            if (!doit) {
6009                return true;
6010            }
6011            didSomething = true;
6012        }
6013
6014        if (mServices.bringDownDisabledPackageServicesLocked(
6015                packageName, null, userId, evenPersistent, true, doit)) {
6016            if (!doit) {
6017                return true;
6018            }
6019            didSomething = true;
6020        }
6021
6022        if (packageName == null) {
6023            // Remove all sticky broadcasts from this user.
6024            mStickyBroadcasts.remove(userId);
6025        }
6026
6027        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6028        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6029                userId, providers)) {
6030            if (!doit) {
6031                return true;
6032            }
6033            didSomething = true;
6034        }
6035        for (i = providers.size() - 1; i >= 0; i--) {
6036            removeDyingProviderLocked(null, providers.get(i), true);
6037        }
6038
6039        // Remove transient permissions granted from/to this package/user
6040        removeUriPermissionsForPackageLocked(packageName, userId, false);
6041
6042        if (doit) {
6043            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6044                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6045                        packageName, null, userId, doit);
6046            }
6047        }
6048
6049        if (packageName == null || uninstalling) {
6050            // Remove pending intents.  For now we only do this when force
6051            // stopping users, because we have some problems when doing this
6052            // for packages -- app widgets are not currently cleaned up for
6053            // such packages, so they can be left with bad pending intents.
6054            if (mIntentSenderRecords.size() > 0) {
6055                Iterator<WeakReference<PendingIntentRecord>> it
6056                        = mIntentSenderRecords.values().iterator();
6057                while (it.hasNext()) {
6058                    WeakReference<PendingIntentRecord> wpir = it.next();
6059                    if (wpir == null) {
6060                        it.remove();
6061                        continue;
6062                    }
6063                    PendingIntentRecord pir = wpir.get();
6064                    if (pir == null) {
6065                        it.remove();
6066                        continue;
6067                    }
6068                    if (packageName == null) {
6069                        // Stopping user, remove all objects for the user.
6070                        if (pir.key.userId != userId) {
6071                            // Not the same user, skip it.
6072                            continue;
6073                        }
6074                    } else {
6075                        if (UserHandle.getAppId(pir.uid) != appId) {
6076                            // Different app id, skip it.
6077                            continue;
6078                        }
6079                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6080                            // Different user, skip it.
6081                            continue;
6082                        }
6083                        if (!pir.key.packageName.equals(packageName)) {
6084                            // Different package, skip it.
6085                            continue;
6086                        }
6087                    }
6088                    if (!doit) {
6089                        return true;
6090                    }
6091                    didSomething = true;
6092                    it.remove();
6093                    pir.canceled = true;
6094                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6095                        pir.key.activity.pendingResults.remove(pir.ref);
6096                    }
6097                }
6098            }
6099        }
6100
6101        if (doit) {
6102            if (purgeCache && packageName != null) {
6103                AttributeCache ac = AttributeCache.instance();
6104                if (ac != null) {
6105                    ac.removePackage(packageName);
6106                }
6107            }
6108            if (mBooted) {
6109                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6110                mStackSupervisor.scheduleIdleLocked();
6111            }
6112        }
6113
6114        return didSomething;
6115    }
6116
6117    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6118        ProcessRecord old = mProcessNames.remove(name, uid);
6119        if (old != null) {
6120            old.uidRecord.numProcs--;
6121            if (old.uidRecord.numProcs == 0) {
6122                // No more processes using this uid, tell clients it is gone.
6123                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6124                        "No more processes in " + old.uidRecord);
6125                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6126                mActiveUids.remove(uid);
6127                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6128            }
6129            old.uidRecord = null;
6130        }
6131        mIsolatedProcesses.remove(uid);
6132        return old;
6133    }
6134
6135    private final void addProcessNameLocked(ProcessRecord proc) {
6136        // We shouldn't already have a process under this name, but just in case we
6137        // need to clean up whatever may be there now.
6138        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6139        if (old == proc && proc.persistent) {
6140            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6141            Slog.w(TAG, "Re-adding persistent process " + proc);
6142        } else if (old != null) {
6143            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6144        }
6145        UidRecord uidRec = mActiveUids.get(proc.uid);
6146        if (uidRec == null) {
6147            uidRec = new UidRecord(proc.uid);
6148            // This is the first appearance of the uid, report it now!
6149            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6150                    "Creating new process uid: " + uidRec);
6151            mActiveUids.put(proc.uid, uidRec);
6152            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6153            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6154        }
6155        proc.uidRecord = uidRec;
6156        uidRec.numProcs++;
6157        mProcessNames.put(proc.processName, proc.uid, proc);
6158        if (proc.isolated) {
6159            mIsolatedProcesses.put(proc.uid, proc);
6160        }
6161    }
6162
6163    boolean removeProcessLocked(ProcessRecord app,
6164            boolean callerWillRestart, boolean allowRestart, String reason) {
6165        final String name = app.processName;
6166        final int uid = app.uid;
6167        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6168            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6169
6170        removeProcessNameLocked(name, uid);
6171        if (mHeavyWeightProcess == app) {
6172            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6173                    mHeavyWeightProcess.userId, 0));
6174            mHeavyWeightProcess = null;
6175        }
6176        boolean needRestart = false;
6177        if (app.pid > 0 && app.pid != MY_PID) {
6178            int pid = app.pid;
6179            synchronized (mPidsSelfLocked) {
6180                mPidsSelfLocked.remove(pid);
6181                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6182            }
6183            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6184            if (app.isolated) {
6185                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6186            }
6187            boolean willRestart = false;
6188            if (app.persistent && !app.isolated) {
6189                if (!callerWillRestart) {
6190                    willRestart = true;
6191                } else {
6192                    needRestart = true;
6193                }
6194            }
6195            app.kill(reason, true);
6196            handleAppDiedLocked(app, willRestart, allowRestart);
6197            if (willRestart) {
6198                removeLruProcessLocked(app);
6199                addAppLocked(app.info, false, null /* ABI override */);
6200            }
6201        } else {
6202            mRemovedProcesses.add(app);
6203        }
6204
6205        return needRestart;
6206    }
6207
6208    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6209        cleanupAppInLaunchingProvidersLocked(app, true);
6210        removeProcessLocked(app, false, true, "timeout publishing content providers");
6211    }
6212
6213    private final void processStartTimedOutLocked(ProcessRecord app) {
6214        final int pid = app.pid;
6215        boolean gone = false;
6216        synchronized (mPidsSelfLocked) {
6217            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6218            if (knownApp != null && knownApp.thread == null) {
6219                mPidsSelfLocked.remove(pid);
6220                gone = true;
6221            }
6222        }
6223
6224        if (gone) {
6225            Slog.w(TAG, "Process " + app + " failed to attach");
6226            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6227                    pid, app.uid, app.processName);
6228            removeProcessNameLocked(app.processName, app.uid);
6229            if (mHeavyWeightProcess == app) {
6230                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6231                        mHeavyWeightProcess.userId, 0));
6232                mHeavyWeightProcess = null;
6233            }
6234            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6235            if (app.isolated) {
6236                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6237            }
6238            // Take care of any launching providers waiting for this process.
6239            cleanupAppInLaunchingProvidersLocked(app, true);
6240            // Take care of any services that are waiting for the process.
6241            mServices.processStartTimedOutLocked(app);
6242            app.kill("start timeout", true);
6243            removeLruProcessLocked(app);
6244            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6245                Slog.w(TAG, "Unattached app died before backup, skipping");
6246                try {
6247                    IBackupManager bm = IBackupManager.Stub.asInterface(
6248                            ServiceManager.getService(Context.BACKUP_SERVICE));
6249                    bm.agentDisconnected(app.info.packageName);
6250                } catch (RemoteException e) {
6251                    // Can't happen; the backup manager is local
6252                }
6253            }
6254            if (isPendingBroadcastProcessLocked(pid)) {
6255                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6256                skipPendingBroadcastLocked(pid);
6257            }
6258        } else {
6259            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6260        }
6261    }
6262
6263    private final boolean attachApplicationLocked(IApplicationThread thread,
6264            int pid) {
6265
6266        // Find the application record that is being attached...  either via
6267        // the pid if we are running in multiple processes, or just pull the
6268        // next app record if we are emulating process with anonymous threads.
6269        ProcessRecord app;
6270        if (pid != MY_PID && pid >= 0) {
6271            synchronized (mPidsSelfLocked) {
6272                app = mPidsSelfLocked.get(pid);
6273            }
6274        } else {
6275            app = null;
6276        }
6277
6278        if (app == null) {
6279            Slog.w(TAG, "No pending application record for pid " + pid
6280                    + " (IApplicationThread " + thread + "); dropping process");
6281            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6282            if (pid > 0 && pid != MY_PID) {
6283                Process.killProcessQuiet(pid);
6284                //TODO: killProcessGroup(app.info.uid, pid);
6285            } else {
6286                try {
6287                    thread.scheduleExit();
6288                } catch (Exception e) {
6289                    // Ignore exceptions.
6290                }
6291            }
6292            return false;
6293        }
6294
6295        // If this application record is still attached to a previous
6296        // process, clean it up now.
6297        if (app.thread != null) {
6298            handleAppDiedLocked(app, true, true);
6299        }
6300
6301        // Tell the process all about itself.
6302
6303        if (DEBUG_ALL) Slog.v(
6304                TAG, "Binding process pid " + pid + " to record " + app);
6305
6306        final String processName = app.processName;
6307        try {
6308            AppDeathRecipient adr = new AppDeathRecipient(
6309                    app, pid, thread);
6310            thread.asBinder().linkToDeath(adr, 0);
6311            app.deathRecipient = adr;
6312        } catch (RemoteException e) {
6313            app.resetPackageList(mProcessStats);
6314            startProcessLocked(app, "link fail", processName);
6315            return false;
6316        }
6317
6318        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6319
6320        app.makeActive(thread, mProcessStats);
6321        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6322        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6323        app.forcingToForeground = null;
6324        updateProcessForegroundLocked(app, false, false);
6325        app.hasShownUi = false;
6326        app.debugging = false;
6327        app.cached = false;
6328        app.killedByAm = false;
6329
6330        // We carefully use the same state that PackageManager uses for
6331        // filtering, since we use this flag to decide if we need to install
6332        // providers when user is unlocked later
6333        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6334
6335        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6336
6337        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6338        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6339
6340        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6341            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6342            msg.obj = app;
6343            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6344        }
6345
6346        if (!normalMode) {
6347            Slog.i(TAG, "Launching preboot mode app: " + app);
6348        }
6349
6350        if (DEBUG_ALL) Slog.v(
6351            TAG, "New app record " + app
6352            + " thread=" + thread.asBinder() + " pid=" + pid);
6353        try {
6354            int testMode = IApplicationThread.DEBUG_OFF;
6355            if (mDebugApp != null && mDebugApp.equals(processName)) {
6356                testMode = mWaitForDebugger
6357                    ? IApplicationThread.DEBUG_WAIT
6358                    : IApplicationThread.DEBUG_ON;
6359                app.debugging = true;
6360                if (mDebugTransient) {
6361                    mDebugApp = mOrigDebugApp;
6362                    mWaitForDebugger = mOrigWaitForDebugger;
6363                }
6364            }
6365            String profileFile = app.instrumentationProfileFile;
6366            ParcelFileDescriptor profileFd = null;
6367            int samplingInterval = 0;
6368            boolean profileAutoStop = false;
6369            if (mProfileApp != null && mProfileApp.equals(processName)) {
6370                mProfileProc = app;
6371                profileFile = mProfileFile;
6372                profileFd = mProfileFd;
6373                samplingInterval = mSamplingInterval;
6374                profileAutoStop = mAutoStopProfiler;
6375            }
6376            boolean enableTrackAllocation = false;
6377            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6378                enableTrackAllocation = true;
6379                mTrackAllocationApp = null;
6380            }
6381
6382            // If the app is being launched for restore or full backup, set it up specially
6383            boolean isRestrictedBackupMode = false;
6384            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6385                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6386                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6387                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6388                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6389            }
6390
6391            if (app.instrumentationClass != null) {
6392                notifyPackageUse(app.instrumentationClass.getPackageName(),
6393                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6394            }
6395            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6396                    + processName + " with config " + mConfiguration);
6397            ApplicationInfo appInfo = app.instrumentationInfo != null
6398                    ? app.instrumentationInfo : app.info;
6399            app.compat = compatibilityInfoForPackageLocked(appInfo);
6400            if (profileFd != null) {
6401                profileFd = profileFd.dup();
6402            }
6403            ProfilerInfo profilerInfo = profileFile == null ? null
6404                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6405            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6406                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6407                    app.instrumentationUiAutomationConnection, testMode,
6408                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6409                    isRestrictedBackupMode || !normalMode, app.persistent,
6410                    new Configuration(mConfiguration), app.compat,
6411                    getCommonServicesLocked(app.isolated),
6412                    mCoreSettingsObserver.getCoreSettingsLocked());
6413            updateLruProcessLocked(app, false, null);
6414            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6415        } catch (Exception e) {
6416            // todo: Yikes!  What should we do?  For now we will try to
6417            // start another process, but that could easily get us in
6418            // an infinite loop of restarting processes...
6419            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6420
6421            app.resetPackageList(mProcessStats);
6422            app.unlinkDeathRecipient();
6423            startProcessLocked(app, "bind fail", processName);
6424            return false;
6425        }
6426
6427        // Remove this record from the list of starting applications.
6428        mPersistentStartingProcesses.remove(app);
6429        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6430                "Attach application locked removing on hold: " + app);
6431        mProcessesOnHold.remove(app);
6432
6433        boolean badApp = false;
6434        boolean didSomething = false;
6435
6436        // See if the top visible activity is waiting to run in this process...
6437        if (normalMode) {
6438            try {
6439                if (mStackSupervisor.attachApplicationLocked(app)) {
6440                    didSomething = true;
6441                }
6442            } catch (Exception e) {
6443                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6444                badApp = true;
6445            }
6446        }
6447
6448        // Find any services that should be running in this process...
6449        if (!badApp) {
6450            try {
6451                didSomething |= mServices.attachApplicationLocked(app, processName);
6452            } catch (Exception e) {
6453                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6454                badApp = true;
6455            }
6456        }
6457
6458        // Check if a next-broadcast receiver is in this process...
6459        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6460            try {
6461                didSomething |= sendPendingBroadcastsLocked(app);
6462            } catch (Exception e) {
6463                // If the app died trying to launch the receiver we declare it 'bad'
6464                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6465                badApp = true;
6466            }
6467        }
6468
6469        // Check whether the next backup agent is in this process...
6470        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6471            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6472                    "New app is backup target, launching agent for " + app);
6473            notifyPackageUse(mBackupTarget.appInfo.packageName,
6474                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6475            try {
6476                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6477                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6478                        mBackupTarget.backupMode);
6479            } catch (Exception e) {
6480                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6481                badApp = true;
6482            }
6483        }
6484
6485        if (badApp) {
6486            app.kill("error during init", true);
6487            handleAppDiedLocked(app, false, true);
6488            return false;
6489        }
6490
6491        if (!didSomething) {
6492            updateOomAdjLocked();
6493        }
6494
6495        return true;
6496    }
6497
6498    @Override
6499    public final void attachApplication(IApplicationThread thread) {
6500        synchronized (this) {
6501            int callingPid = Binder.getCallingPid();
6502            final long origId = Binder.clearCallingIdentity();
6503            attachApplicationLocked(thread, callingPid);
6504            Binder.restoreCallingIdentity(origId);
6505        }
6506    }
6507
6508    @Override
6509    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6510        final long origId = Binder.clearCallingIdentity();
6511        synchronized (this) {
6512            ActivityStack stack = ActivityRecord.getStackLocked(token);
6513            if (stack != null) {
6514                ActivityRecord r =
6515                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6516                if (stopProfiling) {
6517                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6518                        try {
6519                            mProfileFd.close();
6520                        } catch (IOException e) {
6521                        }
6522                        clearProfilerLocked();
6523                    }
6524                }
6525            }
6526        }
6527        Binder.restoreCallingIdentity(origId);
6528    }
6529
6530    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6531        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6532                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6533    }
6534
6535    void enableScreenAfterBoot() {
6536        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6537                SystemClock.uptimeMillis());
6538        mWindowManager.enableScreenAfterBoot();
6539
6540        synchronized (this) {
6541            updateEventDispatchingLocked();
6542        }
6543    }
6544
6545    @Override
6546    public void showBootMessage(final CharSequence msg, final boolean always) {
6547        if (Binder.getCallingUid() != Process.myUid()) {
6548            // These days only the core system can call this, so apps can't get in
6549            // the way of what we show about running them.
6550        }
6551        mWindowManager.showBootMessage(msg, always);
6552    }
6553
6554    @Override
6555    public void keyguardWaitingForActivityDrawn() {
6556        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6557        final long token = Binder.clearCallingIdentity();
6558        try {
6559            synchronized (this) {
6560                if (DEBUG_LOCKSCREEN) logLockScreen("");
6561                mWindowManager.keyguardWaitingForActivityDrawn();
6562                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6563                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6564                    updateSleepIfNeededLocked();
6565                }
6566            }
6567        } finally {
6568            Binder.restoreCallingIdentity(token);
6569        }
6570    }
6571
6572    @Override
6573    public void keyguardGoingAway(int flags) {
6574        enforceNotIsolatedCaller("keyguardGoingAway");
6575        final long token = Binder.clearCallingIdentity();
6576        try {
6577            synchronized (this) {
6578                if (DEBUG_LOCKSCREEN) logLockScreen("");
6579                mWindowManager.keyguardGoingAway(flags);
6580                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6581                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6582                    updateSleepIfNeededLocked();
6583
6584                    // Some stack visibility might change (e.g. docked stack)
6585                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6586                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6587                }
6588            }
6589        } finally {
6590            Binder.restoreCallingIdentity(token);
6591        }
6592    }
6593
6594    final void finishBooting() {
6595        synchronized (this) {
6596            if (!mBootAnimationComplete) {
6597                mCallFinishBooting = true;
6598                return;
6599            }
6600            mCallFinishBooting = false;
6601        }
6602
6603        ArraySet<String> completedIsas = new ArraySet<String>();
6604        for (String abi : Build.SUPPORTED_ABIS) {
6605            Process.establishZygoteConnectionForAbi(abi);
6606            final String instructionSet = VMRuntime.getInstructionSet(abi);
6607            if (!completedIsas.contains(instructionSet)) {
6608                try {
6609                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6610                } catch (InstallerException e) {
6611                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6612                            e.getMessage() +")");
6613                }
6614                completedIsas.add(instructionSet);
6615            }
6616        }
6617
6618        IntentFilter pkgFilter = new IntentFilter();
6619        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6620        pkgFilter.addDataScheme("package");
6621        mContext.registerReceiver(new BroadcastReceiver() {
6622            @Override
6623            public void onReceive(Context context, Intent intent) {
6624                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6625                if (pkgs != null) {
6626                    for (String pkg : pkgs) {
6627                        synchronized (ActivityManagerService.this) {
6628                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6629                                    0, "query restart")) {
6630                                setResultCode(Activity.RESULT_OK);
6631                                return;
6632                            }
6633                        }
6634                    }
6635                }
6636            }
6637        }, pkgFilter);
6638
6639        IntentFilter dumpheapFilter = new IntentFilter();
6640        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6641        mContext.registerReceiver(new BroadcastReceiver() {
6642            @Override
6643            public void onReceive(Context context, Intent intent) {
6644                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6645                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6646                } else {
6647                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6648                }
6649            }
6650        }, dumpheapFilter);
6651
6652        // Let system services know.
6653        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6654
6655        synchronized (this) {
6656            // Ensure that any processes we had put on hold are now started
6657            // up.
6658            final int NP = mProcessesOnHold.size();
6659            if (NP > 0) {
6660                ArrayList<ProcessRecord> procs =
6661                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6662                for (int ip=0; ip<NP; ip++) {
6663                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6664                            + procs.get(ip));
6665                    startProcessLocked(procs.get(ip), "on-hold", null);
6666                }
6667            }
6668
6669            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6670                // Start looking for apps that are abusing wake locks.
6671                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6672                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6673                // Tell anyone interested that we are done booting!
6674                SystemProperties.set("sys.boot_completed", "1");
6675
6676                // And trigger dev.bootcomplete if we are not showing encryption progress
6677                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6678                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6679                    SystemProperties.set("dev.bootcomplete", "1");
6680                }
6681                mUserController.sendBootCompletedLocked(
6682                        new IIntentReceiver.Stub() {
6683                            @Override
6684                            public void performReceive(Intent intent, int resultCode,
6685                                    String data, Bundle extras, boolean ordered,
6686                                    boolean sticky, int sendingUser) {
6687                                synchronized (ActivityManagerService.this) {
6688                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6689                                            true, false);
6690                                }
6691                            }
6692                        });
6693                scheduleStartProfilesLocked();
6694            }
6695        }
6696    }
6697
6698    @Override
6699    public void bootAnimationComplete() {
6700        final boolean callFinishBooting;
6701        synchronized (this) {
6702            callFinishBooting = mCallFinishBooting;
6703            mBootAnimationComplete = true;
6704        }
6705        if (callFinishBooting) {
6706            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6707            finishBooting();
6708            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6709        }
6710    }
6711
6712    final void ensureBootCompleted() {
6713        boolean booting;
6714        boolean enableScreen;
6715        synchronized (this) {
6716            booting = mBooting;
6717            mBooting = false;
6718            enableScreen = !mBooted;
6719            mBooted = true;
6720        }
6721
6722        if (booting) {
6723            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6724            finishBooting();
6725            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6726        }
6727
6728        if (enableScreen) {
6729            enableScreenAfterBoot();
6730        }
6731    }
6732
6733    @Override
6734    public final void activityResumed(IBinder token) {
6735        final long origId = Binder.clearCallingIdentity();
6736        synchronized(this) {
6737            ActivityStack stack = ActivityRecord.getStackLocked(token);
6738            if (stack != null) {
6739                stack.activityResumedLocked(token);
6740            }
6741        }
6742        Binder.restoreCallingIdentity(origId);
6743    }
6744
6745    @Override
6746    public final void activityPaused(IBinder token) {
6747        final long origId = Binder.clearCallingIdentity();
6748        synchronized(this) {
6749            ActivityStack stack = ActivityRecord.getStackLocked(token);
6750            if (stack != null) {
6751                stack.activityPausedLocked(token, false);
6752            }
6753        }
6754        Binder.restoreCallingIdentity(origId);
6755    }
6756
6757    @Override
6758    public final void activityStopped(IBinder token, Bundle icicle,
6759            PersistableBundle persistentState, CharSequence description) {
6760        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6761
6762        // Refuse possible leaked file descriptors
6763        if (icicle != null && icicle.hasFileDescriptors()) {
6764            throw new IllegalArgumentException("File descriptors passed in Bundle");
6765        }
6766
6767        final long origId = Binder.clearCallingIdentity();
6768
6769        synchronized (this) {
6770            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6771            if (r != null) {
6772                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6773            }
6774        }
6775
6776        trimApplications();
6777
6778        Binder.restoreCallingIdentity(origId);
6779    }
6780
6781    @Override
6782    public final void activityDestroyed(IBinder token) {
6783        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6784        synchronized (this) {
6785            ActivityStack stack = ActivityRecord.getStackLocked(token);
6786            if (stack != null) {
6787                stack.activityDestroyedLocked(token, "activityDestroyed");
6788            }
6789        }
6790    }
6791
6792    @Override
6793    public final void activityRelaunched(IBinder token) {
6794        final long origId = Binder.clearCallingIdentity();
6795        synchronized (this) {
6796            mStackSupervisor.activityRelaunchedLocked(token);
6797        }
6798        Binder.restoreCallingIdentity(origId);
6799    }
6800
6801    @Override
6802    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6803            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6804        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6805                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6806        synchronized (this) {
6807            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6808            if (record == null) {
6809                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6810                        + "found for: " + token);
6811            }
6812            record.setSizeConfigurations(horizontalSizeConfiguration,
6813                    verticalSizeConfigurations, smallestSizeConfigurations);
6814        }
6815    }
6816
6817    @Override
6818    public final void backgroundResourcesReleased(IBinder token) {
6819        final long origId = Binder.clearCallingIdentity();
6820        try {
6821            synchronized (this) {
6822                ActivityStack stack = ActivityRecord.getStackLocked(token);
6823                if (stack != null) {
6824                    stack.backgroundResourcesReleased();
6825                }
6826            }
6827        } finally {
6828            Binder.restoreCallingIdentity(origId);
6829        }
6830    }
6831
6832    @Override
6833    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6834        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6835    }
6836
6837    @Override
6838    public final void notifyEnterAnimationComplete(IBinder token) {
6839        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6840    }
6841
6842    @Override
6843    public String getCallingPackage(IBinder token) {
6844        synchronized (this) {
6845            ActivityRecord r = getCallingRecordLocked(token);
6846            return r != null ? r.info.packageName : null;
6847        }
6848    }
6849
6850    @Override
6851    public ComponentName getCallingActivity(IBinder token) {
6852        synchronized (this) {
6853            ActivityRecord r = getCallingRecordLocked(token);
6854            return r != null ? r.intent.getComponent() : null;
6855        }
6856    }
6857
6858    private ActivityRecord getCallingRecordLocked(IBinder token) {
6859        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6860        if (r == null) {
6861            return null;
6862        }
6863        return r.resultTo;
6864    }
6865
6866    @Override
6867    public ComponentName getActivityClassForToken(IBinder token) {
6868        synchronized(this) {
6869            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6870            if (r == null) {
6871                return null;
6872            }
6873            return r.intent.getComponent();
6874        }
6875    }
6876
6877    @Override
6878    public String getPackageForToken(IBinder token) {
6879        synchronized(this) {
6880            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6881            if (r == null) {
6882                return null;
6883            }
6884            return r.packageName;
6885        }
6886    }
6887
6888    @Override
6889    public boolean isRootVoiceInteraction(IBinder token) {
6890        synchronized(this) {
6891            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6892            if (r == null) {
6893                return false;
6894            }
6895            return r.rootVoiceInteraction;
6896        }
6897    }
6898
6899    @Override
6900    public IIntentSender getIntentSender(int type,
6901            String packageName, IBinder token, String resultWho,
6902            int requestCode, Intent[] intents, String[] resolvedTypes,
6903            int flags, Bundle bOptions, int userId) {
6904        enforceNotIsolatedCaller("getIntentSender");
6905        // Refuse possible leaked file descriptors
6906        if (intents != null) {
6907            if (intents.length < 1) {
6908                throw new IllegalArgumentException("Intents array length must be >= 1");
6909            }
6910            for (int i=0; i<intents.length; i++) {
6911                Intent intent = intents[i];
6912                if (intent != null) {
6913                    if (intent.hasFileDescriptors()) {
6914                        throw new IllegalArgumentException("File descriptors passed in Intent");
6915                    }
6916                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6917                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6918                        throw new IllegalArgumentException(
6919                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6920                    }
6921                    intents[i] = new Intent(intent);
6922                }
6923            }
6924            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6925                throw new IllegalArgumentException(
6926                        "Intent array length does not match resolvedTypes length");
6927            }
6928        }
6929        if (bOptions != null) {
6930            if (bOptions.hasFileDescriptors()) {
6931                throw new IllegalArgumentException("File descriptors passed in options");
6932            }
6933        }
6934
6935        synchronized(this) {
6936            int callingUid = Binder.getCallingUid();
6937            int origUserId = userId;
6938            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6939                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6940                    ALLOW_NON_FULL, "getIntentSender", null);
6941            if (origUserId == UserHandle.USER_CURRENT) {
6942                // We don't want to evaluate this until the pending intent is
6943                // actually executed.  However, we do want to always do the
6944                // security checking for it above.
6945                userId = UserHandle.USER_CURRENT;
6946            }
6947            try {
6948                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6949                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6950                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6951                    if (!UserHandle.isSameApp(callingUid, uid)) {
6952                        String msg = "Permission Denial: getIntentSender() from pid="
6953                            + Binder.getCallingPid()
6954                            + ", uid=" + Binder.getCallingUid()
6955                            + ", (need uid=" + uid + ")"
6956                            + " is not allowed to send as package " + packageName;
6957                        Slog.w(TAG, msg);
6958                        throw new SecurityException(msg);
6959                    }
6960                }
6961
6962                return getIntentSenderLocked(type, packageName, callingUid, userId,
6963                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6964
6965            } catch (RemoteException e) {
6966                throw new SecurityException(e);
6967            }
6968        }
6969    }
6970
6971    IIntentSender getIntentSenderLocked(int type, String packageName,
6972            int callingUid, int userId, IBinder token, String resultWho,
6973            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6974            Bundle bOptions) {
6975        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6976        ActivityRecord activity = null;
6977        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6978            activity = ActivityRecord.isInStackLocked(token);
6979            if (activity == null) {
6980                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6981                return null;
6982            }
6983            if (activity.finishing) {
6984                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6985                return null;
6986            }
6987        }
6988
6989        // We're going to be splicing together extras before sending, so we're
6990        // okay poking into any contained extras.
6991        if (intents != null) {
6992            for (int i = 0; i < intents.length; i++) {
6993                intents[i].setDefusable(true);
6994            }
6995        }
6996        Bundle.setDefusable(bOptions, true);
6997
6998        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6999        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7000        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7001        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7002                |PendingIntent.FLAG_UPDATE_CURRENT);
7003
7004        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7005                type, packageName, activity, resultWho,
7006                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7007        WeakReference<PendingIntentRecord> ref;
7008        ref = mIntentSenderRecords.get(key);
7009        PendingIntentRecord rec = ref != null ? ref.get() : null;
7010        if (rec != null) {
7011            if (!cancelCurrent) {
7012                if (updateCurrent) {
7013                    if (rec.key.requestIntent != null) {
7014                        rec.key.requestIntent.replaceExtras(intents != null ?
7015                                intents[intents.length - 1] : null);
7016                    }
7017                    if (intents != null) {
7018                        intents[intents.length-1] = rec.key.requestIntent;
7019                        rec.key.allIntents = intents;
7020                        rec.key.allResolvedTypes = resolvedTypes;
7021                    } else {
7022                        rec.key.allIntents = null;
7023                        rec.key.allResolvedTypes = null;
7024                    }
7025                }
7026                return rec;
7027            }
7028            rec.canceled = true;
7029            mIntentSenderRecords.remove(key);
7030        }
7031        if (noCreate) {
7032            return rec;
7033        }
7034        rec = new PendingIntentRecord(this, key, callingUid);
7035        mIntentSenderRecords.put(key, rec.ref);
7036        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7037            if (activity.pendingResults == null) {
7038                activity.pendingResults
7039                        = new HashSet<WeakReference<PendingIntentRecord>>();
7040            }
7041            activity.pendingResults.add(rec.ref);
7042        }
7043        return rec;
7044    }
7045
7046    @Override
7047    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7048            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7049        if (target instanceof PendingIntentRecord) {
7050            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7051                    finishedReceiver, requiredPermission, options);
7052        } else {
7053            try {
7054                target.send(code, intent, resolvedType, null, requiredPermission, options);
7055            } catch (RemoteException e) {
7056            }
7057            // Platform code can rely on getting a result back when the send is done, but if
7058            // this intent sender is from outside of the system we can't rely on it doing that.
7059            // So instead we don't give it the result receiver, and instead just directly
7060            // report the finish immediately.
7061            if (finishedReceiver != null) {
7062                try {
7063                    finishedReceiver.performReceive(intent, 0,
7064                            null, null, false, false, UserHandle.getCallingUserId());
7065                } catch (RemoteException e) {
7066                }
7067            }
7068            return 0;
7069        }
7070    }
7071
7072    @Override
7073    public void cancelIntentSender(IIntentSender sender) {
7074        if (!(sender instanceof PendingIntentRecord)) {
7075            return;
7076        }
7077        synchronized(this) {
7078            PendingIntentRecord rec = (PendingIntentRecord)sender;
7079            try {
7080                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7081                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7082                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7083                    String msg = "Permission Denial: cancelIntentSender() from pid="
7084                        + Binder.getCallingPid()
7085                        + ", uid=" + Binder.getCallingUid()
7086                        + " is not allowed to cancel packges "
7087                        + rec.key.packageName;
7088                    Slog.w(TAG, msg);
7089                    throw new SecurityException(msg);
7090                }
7091            } catch (RemoteException e) {
7092                throw new SecurityException(e);
7093            }
7094            cancelIntentSenderLocked(rec, true);
7095        }
7096    }
7097
7098    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7099        rec.canceled = true;
7100        mIntentSenderRecords.remove(rec.key);
7101        if (cleanActivity && rec.key.activity != null) {
7102            rec.key.activity.pendingResults.remove(rec.ref);
7103        }
7104    }
7105
7106    @Override
7107    public String getPackageForIntentSender(IIntentSender pendingResult) {
7108        if (!(pendingResult instanceof PendingIntentRecord)) {
7109            return null;
7110        }
7111        try {
7112            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7113            return res.key.packageName;
7114        } catch (ClassCastException e) {
7115        }
7116        return null;
7117    }
7118
7119    @Override
7120    public int getUidForIntentSender(IIntentSender sender) {
7121        if (sender instanceof PendingIntentRecord) {
7122            try {
7123                PendingIntentRecord res = (PendingIntentRecord)sender;
7124                return res.uid;
7125            } catch (ClassCastException e) {
7126            }
7127        }
7128        return -1;
7129    }
7130
7131    @Override
7132    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7133        if (!(pendingResult instanceof PendingIntentRecord)) {
7134            return false;
7135        }
7136        try {
7137            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7138            if (res.key.allIntents == null) {
7139                return false;
7140            }
7141            for (int i=0; i<res.key.allIntents.length; i++) {
7142                Intent intent = res.key.allIntents[i];
7143                if (intent.getPackage() != null && intent.getComponent() != null) {
7144                    return false;
7145                }
7146            }
7147            return true;
7148        } catch (ClassCastException e) {
7149        }
7150        return false;
7151    }
7152
7153    @Override
7154    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7155        if (!(pendingResult instanceof PendingIntentRecord)) {
7156            return false;
7157        }
7158        try {
7159            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7160            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7161                return true;
7162            }
7163            return false;
7164        } catch (ClassCastException e) {
7165        }
7166        return false;
7167    }
7168
7169    @Override
7170    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7171        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7172                "getIntentForIntentSender()");
7173        if (!(pendingResult instanceof PendingIntentRecord)) {
7174            return null;
7175        }
7176        try {
7177            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7178            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7179        } catch (ClassCastException e) {
7180        }
7181        return null;
7182    }
7183
7184    @Override
7185    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7186        if (!(pendingResult instanceof PendingIntentRecord)) {
7187            return null;
7188        }
7189        try {
7190            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7191            synchronized (this) {
7192                return getTagForIntentSenderLocked(res, prefix);
7193            }
7194        } catch (ClassCastException e) {
7195        }
7196        return null;
7197    }
7198
7199    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7200        final Intent intent = res.key.requestIntent;
7201        if (intent != null) {
7202            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7203                    || res.lastTagPrefix.equals(prefix))) {
7204                return res.lastTag;
7205            }
7206            res.lastTagPrefix = prefix;
7207            final StringBuilder sb = new StringBuilder(128);
7208            if (prefix != null) {
7209                sb.append(prefix);
7210            }
7211            if (intent.getAction() != null) {
7212                sb.append(intent.getAction());
7213            } else if (intent.getComponent() != null) {
7214                intent.getComponent().appendShortString(sb);
7215            } else {
7216                sb.append("?");
7217            }
7218            return res.lastTag = sb.toString();
7219        }
7220        return null;
7221    }
7222
7223    @Override
7224    public void setProcessLimit(int max) {
7225        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7226                "setProcessLimit()");
7227        synchronized (this) {
7228            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7229            mProcessLimitOverride = max;
7230        }
7231        trimApplications();
7232    }
7233
7234    @Override
7235    public int getProcessLimit() {
7236        synchronized (this) {
7237            return mProcessLimitOverride;
7238        }
7239    }
7240
7241    void foregroundTokenDied(ForegroundToken token) {
7242        synchronized (ActivityManagerService.this) {
7243            synchronized (mPidsSelfLocked) {
7244                ForegroundToken cur
7245                    = mForegroundProcesses.get(token.pid);
7246                if (cur != token) {
7247                    return;
7248                }
7249                mForegroundProcesses.remove(token.pid);
7250                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7251                if (pr == null) {
7252                    return;
7253                }
7254                pr.forcingToForeground = null;
7255                updateProcessForegroundLocked(pr, false, false);
7256            }
7257            updateOomAdjLocked();
7258        }
7259    }
7260
7261    @Override
7262    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7263        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7264                "setProcessForeground()");
7265        synchronized(this) {
7266            boolean changed = false;
7267
7268            synchronized (mPidsSelfLocked) {
7269                ProcessRecord pr = mPidsSelfLocked.get(pid);
7270                if (pr == null && isForeground) {
7271                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7272                    return;
7273                }
7274                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7275                if (oldToken != null) {
7276                    oldToken.token.unlinkToDeath(oldToken, 0);
7277                    mForegroundProcesses.remove(pid);
7278                    if (pr != null) {
7279                        pr.forcingToForeground = null;
7280                    }
7281                    changed = true;
7282                }
7283                if (isForeground && token != null) {
7284                    ForegroundToken newToken = new ForegroundToken() {
7285                        @Override
7286                        public void binderDied() {
7287                            foregroundTokenDied(this);
7288                        }
7289                    };
7290                    newToken.pid = pid;
7291                    newToken.token = token;
7292                    try {
7293                        token.linkToDeath(newToken, 0);
7294                        mForegroundProcesses.put(pid, newToken);
7295                        pr.forcingToForeground = token;
7296                        changed = true;
7297                    } catch (RemoteException e) {
7298                        // If the process died while doing this, we will later
7299                        // do the cleanup with the process death link.
7300                    }
7301                }
7302            }
7303
7304            if (changed) {
7305                updateOomAdjLocked();
7306            }
7307        }
7308    }
7309
7310    @Override
7311    public boolean isAppForeground(int uid) throws RemoteException {
7312        synchronized (this) {
7313            UidRecord uidRec = mActiveUids.get(uid);
7314            if (uidRec == null || uidRec.idle) {
7315                return false;
7316            }
7317            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7318        }
7319    }
7320
7321    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7322    // be guarded by permission checking.
7323    int getUidState(int uid) {
7324        synchronized (this) {
7325            UidRecord uidRec = mActiveUids.get(uid);
7326            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7327        }
7328    }
7329
7330    @Override
7331    public boolean isInMultiWindowMode(IBinder token) {
7332        final long origId = Binder.clearCallingIdentity();
7333        try {
7334            synchronized(this) {
7335                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7336                if (r == null) {
7337                    return false;
7338                }
7339                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7340                return !r.task.mFullscreen;
7341            }
7342        } finally {
7343            Binder.restoreCallingIdentity(origId);
7344        }
7345    }
7346
7347    @Override
7348    public boolean isInPictureInPictureMode(IBinder token) {
7349        final long origId = Binder.clearCallingIdentity();
7350        try {
7351            synchronized(this) {
7352                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7353                if (stack == null) {
7354                    return false;
7355                }
7356                return stack.mStackId == PINNED_STACK_ID;
7357            }
7358        } finally {
7359            Binder.restoreCallingIdentity(origId);
7360        }
7361    }
7362
7363    @Override
7364    public void enterPictureInPictureMode(IBinder token) {
7365        final long origId = Binder.clearCallingIdentity();
7366        try {
7367            synchronized(this) {
7368                if (!mSupportsPictureInPicture) {
7369                    throw new IllegalStateException("enterPictureInPictureMode: "
7370                            + "Device doesn't support picture-in-picture mode.");
7371                }
7372
7373                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7374
7375                if (r == null) {
7376                    throw new IllegalStateException("enterPictureInPictureMode: "
7377                            + "Can't find activity for token=" + token);
7378                }
7379
7380                if (!r.supportsPictureInPicture()) {
7381                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7382                            + "Picture-In-Picture not supported for r=" + r);
7383                }
7384
7385                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7386                // current bounds.
7387                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7388                final Rect bounds = (pinnedStack != null)
7389                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7390
7391                mStackSupervisor.moveActivityToPinnedStackLocked(
7392                        r, "enterPictureInPictureMode", bounds);
7393            }
7394        } finally {
7395            Binder.restoreCallingIdentity(origId);
7396        }
7397    }
7398
7399    // =========================================================
7400    // PROCESS INFO
7401    // =========================================================
7402
7403    static class ProcessInfoService extends IProcessInfoService.Stub {
7404        final ActivityManagerService mActivityManagerService;
7405        ProcessInfoService(ActivityManagerService activityManagerService) {
7406            mActivityManagerService = activityManagerService;
7407        }
7408
7409        @Override
7410        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7411            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7412                    /*in*/ pids, /*out*/ states, null);
7413        }
7414
7415        @Override
7416        public void getProcessStatesAndOomScoresFromPids(
7417                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7418            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7419                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7420        }
7421    }
7422
7423    /**
7424     * For each PID in the given input array, write the current process state
7425     * for that process into the states array, or -1 to indicate that no
7426     * process with the given PID exists. If scores array is provided, write
7427     * the oom score for the process into the scores array, with INVALID_ADJ
7428     * indicating the PID doesn't exist.
7429     */
7430    public void getProcessStatesAndOomScoresForPIDs(
7431            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7432        if (scores != null) {
7433            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7434                    "getProcessStatesAndOomScoresForPIDs()");
7435        }
7436
7437        if (pids == null) {
7438            throw new NullPointerException("pids");
7439        } else if (states == null) {
7440            throw new NullPointerException("states");
7441        } else if (pids.length != states.length) {
7442            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7443        } else if (scores != null && pids.length != scores.length) {
7444            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7445        }
7446
7447        synchronized (mPidsSelfLocked) {
7448            for (int i = 0; i < pids.length; i++) {
7449                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7450                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7451                        pr.curProcState;
7452                if (scores != null) {
7453                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7454                }
7455            }
7456        }
7457    }
7458
7459    // =========================================================
7460    // PERMISSIONS
7461    // =========================================================
7462
7463    static class PermissionController extends IPermissionController.Stub {
7464        ActivityManagerService mActivityManagerService;
7465        PermissionController(ActivityManagerService activityManagerService) {
7466            mActivityManagerService = activityManagerService;
7467        }
7468
7469        @Override
7470        public boolean checkPermission(String permission, int pid, int uid) {
7471            return mActivityManagerService.checkPermission(permission, pid,
7472                    uid) == PackageManager.PERMISSION_GRANTED;
7473        }
7474
7475        @Override
7476        public String[] getPackagesForUid(int uid) {
7477            return mActivityManagerService.mContext.getPackageManager()
7478                    .getPackagesForUid(uid);
7479        }
7480
7481        @Override
7482        public boolean isRuntimePermission(String permission) {
7483            try {
7484                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7485                        .getPermissionInfo(permission, 0);
7486                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7487            } catch (NameNotFoundException nnfe) {
7488                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7489            }
7490            return false;
7491        }
7492    }
7493
7494    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7495        @Override
7496        public int checkComponentPermission(String permission, int pid, int uid,
7497                int owningUid, boolean exported) {
7498            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7499                    owningUid, exported);
7500        }
7501
7502        @Override
7503        public Object getAMSLock() {
7504            return ActivityManagerService.this;
7505        }
7506    }
7507
7508    /**
7509     * This can be called with or without the global lock held.
7510     */
7511    int checkComponentPermission(String permission, int pid, int uid,
7512            int owningUid, boolean exported) {
7513        if (pid == MY_PID) {
7514            return PackageManager.PERMISSION_GRANTED;
7515        }
7516        return ActivityManager.checkComponentPermission(permission, uid,
7517                owningUid, exported);
7518    }
7519
7520    /**
7521     * As the only public entry point for permissions checking, this method
7522     * can enforce the semantic that requesting a check on a null global
7523     * permission is automatically denied.  (Internally a null permission
7524     * string is used when calling {@link #checkComponentPermission} in cases
7525     * when only uid-based security is needed.)
7526     *
7527     * This can be called with or without the global lock held.
7528     */
7529    @Override
7530    public int checkPermission(String permission, int pid, int uid) {
7531        if (permission == null) {
7532            return PackageManager.PERMISSION_DENIED;
7533        }
7534        return checkComponentPermission(permission, pid, uid, -1, true);
7535    }
7536
7537    @Override
7538    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7539        if (permission == null) {
7540            return PackageManager.PERMISSION_DENIED;
7541        }
7542
7543        // We might be performing an operation on behalf of an indirect binder
7544        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7545        // client identity accordingly before proceeding.
7546        Identity tlsIdentity = sCallerIdentity.get();
7547        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7548            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7549                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7550            uid = tlsIdentity.uid;
7551            pid = tlsIdentity.pid;
7552        }
7553
7554        return checkComponentPermission(permission, pid, uid, -1, true);
7555    }
7556
7557    /**
7558     * Binder IPC calls go through the public entry point.
7559     * This can be called with or without the global lock held.
7560     */
7561    int checkCallingPermission(String permission) {
7562        return checkPermission(permission,
7563                Binder.getCallingPid(),
7564                UserHandle.getAppId(Binder.getCallingUid()));
7565    }
7566
7567    /**
7568     * This can be called with or without the global lock held.
7569     */
7570    void enforceCallingPermission(String permission, String func) {
7571        if (checkCallingPermission(permission)
7572                == PackageManager.PERMISSION_GRANTED) {
7573            return;
7574        }
7575
7576        String msg = "Permission Denial: " + func + " from pid="
7577                + Binder.getCallingPid()
7578                + ", uid=" + Binder.getCallingUid()
7579                + " requires " + permission;
7580        Slog.w(TAG, msg);
7581        throw new SecurityException(msg);
7582    }
7583
7584    /**
7585     * Determine if UID is holding permissions required to access {@link Uri} in
7586     * the given {@link ProviderInfo}. Final permission checking is always done
7587     * in {@link ContentProvider}.
7588     */
7589    private final boolean checkHoldingPermissionsLocked(
7590            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7591        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7592                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7593        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7594            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7595                    != PERMISSION_GRANTED) {
7596                return false;
7597            }
7598        }
7599        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7600    }
7601
7602    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7603            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7604        if (pi.applicationInfo.uid == uid) {
7605            return true;
7606        } else if (!pi.exported) {
7607            return false;
7608        }
7609
7610        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7611        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7612        try {
7613            // check if target holds top-level <provider> permissions
7614            if (!readMet && pi.readPermission != null && considerUidPermissions
7615                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7616                readMet = true;
7617            }
7618            if (!writeMet && pi.writePermission != null && considerUidPermissions
7619                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7620                writeMet = true;
7621            }
7622
7623            // track if unprotected read/write is allowed; any denied
7624            // <path-permission> below removes this ability
7625            boolean allowDefaultRead = pi.readPermission == null;
7626            boolean allowDefaultWrite = pi.writePermission == null;
7627
7628            // check if target holds any <path-permission> that match uri
7629            final PathPermission[] pps = pi.pathPermissions;
7630            if (pps != null) {
7631                final String path = grantUri.uri.getPath();
7632                int i = pps.length;
7633                while (i > 0 && (!readMet || !writeMet)) {
7634                    i--;
7635                    PathPermission pp = pps[i];
7636                    if (pp.match(path)) {
7637                        if (!readMet) {
7638                            final String pprperm = pp.getReadPermission();
7639                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7640                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7641                                    + ": match=" + pp.match(path)
7642                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7643                            if (pprperm != null) {
7644                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7645                                        == PERMISSION_GRANTED) {
7646                                    readMet = true;
7647                                } else {
7648                                    allowDefaultRead = false;
7649                                }
7650                            }
7651                        }
7652                        if (!writeMet) {
7653                            final String ppwperm = pp.getWritePermission();
7654                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7655                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7656                                    + ": match=" + pp.match(path)
7657                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7658                            if (ppwperm != null) {
7659                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7660                                        == PERMISSION_GRANTED) {
7661                                    writeMet = true;
7662                                } else {
7663                                    allowDefaultWrite = false;
7664                                }
7665                            }
7666                        }
7667                    }
7668                }
7669            }
7670
7671            // grant unprotected <provider> read/write, if not blocked by
7672            // <path-permission> above
7673            if (allowDefaultRead) readMet = true;
7674            if (allowDefaultWrite) writeMet = true;
7675
7676        } catch (RemoteException e) {
7677            return false;
7678        }
7679
7680        return readMet && writeMet;
7681    }
7682
7683    public int getAppStartMode(int uid, String packageName) {
7684        synchronized (this) {
7685            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7686        }
7687    }
7688
7689    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7690            boolean allowWhenForeground) {
7691        UidRecord uidRec = mActiveUids.get(uid);
7692        if (!mLenientBackgroundCheck) {
7693            if (!allowWhenForeground || uidRec == null
7694                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7695                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7696                        packageName) != AppOpsManager.MODE_ALLOWED) {
7697                    return ActivityManager.APP_START_MODE_DELAYED;
7698                }
7699            }
7700
7701        } else if (uidRec == null || uidRec.idle) {
7702            if (callingPid >= 0) {
7703                ProcessRecord proc;
7704                synchronized (mPidsSelfLocked) {
7705                    proc = mPidsSelfLocked.get(callingPid);
7706                }
7707                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7708                    // Whoever is instigating this is in the foreground, so we will allow it
7709                    // to go through.
7710                    return ActivityManager.APP_START_MODE_NORMAL;
7711                }
7712            }
7713            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7714                    != AppOpsManager.MODE_ALLOWED) {
7715                return ActivityManager.APP_START_MODE_DELAYED;
7716            }
7717        }
7718        return ActivityManager.APP_START_MODE_NORMAL;
7719    }
7720
7721    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7722        ProviderInfo pi = null;
7723        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7724        if (cpr != null) {
7725            pi = cpr.info;
7726        } else {
7727            try {
7728                pi = AppGlobals.getPackageManager().resolveContentProvider(
7729                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7730            } catch (RemoteException ex) {
7731            }
7732        }
7733        return pi;
7734    }
7735
7736    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7737        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7738        if (targetUris != null) {
7739            return targetUris.get(grantUri);
7740        }
7741        return null;
7742    }
7743
7744    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7745            String targetPkg, int targetUid, GrantUri grantUri) {
7746        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7747        if (targetUris == null) {
7748            targetUris = Maps.newArrayMap();
7749            mGrantedUriPermissions.put(targetUid, targetUris);
7750        }
7751
7752        UriPermission perm = targetUris.get(grantUri);
7753        if (perm == null) {
7754            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7755            targetUris.put(grantUri, perm);
7756        }
7757
7758        return perm;
7759    }
7760
7761    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7762            final int modeFlags) {
7763        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7764        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7765                : UriPermission.STRENGTH_OWNED;
7766
7767        // Root gets to do everything.
7768        if (uid == 0) {
7769            return true;
7770        }
7771
7772        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7773        if (perms == null) return false;
7774
7775        // First look for exact match
7776        final UriPermission exactPerm = perms.get(grantUri);
7777        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7778            return true;
7779        }
7780
7781        // No exact match, look for prefixes
7782        final int N = perms.size();
7783        for (int i = 0; i < N; i++) {
7784            final UriPermission perm = perms.valueAt(i);
7785            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7786                    && perm.getStrength(modeFlags) >= minStrength) {
7787                return true;
7788            }
7789        }
7790
7791        return false;
7792    }
7793
7794    /**
7795     * @param uri This uri must NOT contain an embedded userId.
7796     * @param userId The userId in which the uri is to be resolved.
7797     */
7798    @Override
7799    public int checkUriPermission(Uri uri, int pid, int uid,
7800            final int modeFlags, int userId, IBinder callerToken) {
7801        enforceNotIsolatedCaller("checkUriPermission");
7802
7803        // Another redirected-binder-call permissions check as in
7804        // {@link checkPermissionWithToken}.
7805        Identity tlsIdentity = sCallerIdentity.get();
7806        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7807            uid = tlsIdentity.uid;
7808            pid = tlsIdentity.pid;
7809        }
7810
7811        // Our own process gets to do everything.
7812        if (pid == MY_PID) {
7813            return PackageManager.PERMISSION_GRANTED;
7814        }
7815        synchronized (this) {
7816            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7817                    ? PackageManager.PERMISSION_GRANTED
7818                    : PackageManager.PERMISSION_DENIED;
7819        }
7820    }
7821
7822    /**
7823     * Check if the targetPkg can be granted permission to access uri by
7824     * the callingUid using the given modeFlags.  Throws a security exception
7825     * if callingUid is not allowed to do this.  Returns the uid of the target
7826     * if the URI permission grant should be performed; returns -1 if it is not
7827     * needed (for example targetPkg already has permission to access the URI).
7828     * If you already know the uid of the target, you can supply it in
7829     * lastTargetUid else set that to -1.
7830     */
7831    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7832            final int modeFlags, int lastTargetUid) {
7833        if (!Intent.isAccessUriMode(modeFlags)) {
7834            return -1;
7835        }
7836
7837        if (targetPkg != null) {
7838            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7839                    "Checking grant " + targetPkg + " permission to " + grantUri);
7840        }
7841
7842        final IPackageManager pm = AppGlobals.getPackageManager();
7843
7844        // If this is not a content: uri, we can't do anything with it.
7845        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7846            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7847                    "Can't grant URI permission for non-content URI: " + grantUri);
7848            return -1;
7849        }
7850
7851        final String authority = grantUri.uri.getAuthority();
7852        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7853        if (pi == null) {
7854            Slog.w(TAG, "No content provider found for permission check: " +
7855                    grantUri.uri.toSafeString());
7856            return -1;
7857        }
7858
7859        int targetUid = lastTargetUid;
7860        if (targetUid < 0 && targetPkg != null) {
7861            try {
7862                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7863                        UserHandle.getUserId(callingUid));
7864                if (targetUid < 0) {
7865                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7866                            "Can't grant URI permission no uid for: " + targetPkg);
7867                    return -1;
7868                }
7869            } catch (RemoteException ex) {
7870                return -1;
7871            }
7872        }
7873
7874        if (targetUid >= 0) {
7875            // First...  does the target actually need this permission?
7876            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7877                // No need to grant the target this permission.
7878                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7879                        "Target " + targetPkg + " already has full permission to " + grantUri);
7880                return -1;
7881            }
7882        } else {
7883            // First...  there is no target package, so can anyone access it?
7884            boolean allowed = pi.exported;
7885            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7886                if (pi.readPermission != null) {
7887                    allowed = false;
7888                }
7889            }
7890            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7891                if (pi.writePermission != null) {
7892                    allowed = false;
7893                }
7894            }
7895            if (allowed) {
7896                return -1;
7897            }
7898        }
7899
7900        /* There is a special cross user grant if:
7901         * - The target is on another user.
7902         * - Apps on the current user can access the uri without any uid permissions.
7903         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7904         * grant uri permissions.
7905         */
7906        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7907                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7908                modeFlags, false /*without considering the uid permissions*/);
7909
7910        // Second...  is the provider allowing granting of URI permissions?
7911        if (!specialCrossUserGrant) {
7912            if (!pi.grantUriPermissions) {
7913                throw new SecurityException("Provider " + pi.packageName
7914                        + "/" + pi.name
7915                        + " does not allow granting of Uri permissions (uri "
7916                        + grantUri + ")");
7917            }
7918            if (pi.uriPermissionPatterns != null) {
7919                final int N = pi.uriPermissionPatterns.length;
7920                boolean allowed = false;
7921                for (int i=0; i<N; i++) {
7922                    if (pi.uriPermissionPatterns[i] != null
7923                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7924                        allowed = true;
7925                        break;
7926                    }
7927                }
7928                if (!allowed) {
7929                    throw new SecurityException("Provider " + pi.packageName
7930                            + "/" + pi.name
7931                            + " does not allow granting of permission to path of Uri "
7932                            + grantUri);
7933                }
7934            }
7935        }
7936
7937        // Third...  does the caller itself have permission to access
7938        // this uri?
7939        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7940            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7941                // Require they hold a strong enough Uri permission
7942                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7943                    throw new SecurityException("Uid " + callingUid
7944                            + " does not have permission to uri " + grantUri);
7945                }
7946            }
7947        }
7948        return targetUid;
7949    }
7950
7951    /**
7952     * @param uri This uri must NOT contain an embedded userId.
7953     * @param userId The userId in which the uri is to be resolved.
7954     */
7955    @Override
7956    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7957            final int modeFlags, int userId) {
7958        enforceNotIsolatedCaller("checkGrantUriPermission");
7959        synchronized(this) {
7960            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7961                    new GrantUri(userId, uri, false), modeFlags, -1);
7962        }
7963    }
7964
7965    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7966            final int modeFlags, UriPermissionOwner owner) {
7967        if (!Intent.isAccessUriMode(modeFlags)) {
7968            return;
7969        }
7970
7971        // So here we are: the caller has the assumed permission
7972        // to the uri, and the target doesn't.  Let's now give this to
7973        // the target.
7974
7975        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7976                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7977
7978        final String authority = grantUri.uri.getAuthority();
7979        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7980        if (pi == null) {
7981            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7982            return;
7983        }
7984
7985        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7986            grantUri.prefix = true;
7987        }
7988        final UriPermission perm = findOrCreateUriPermissionLocked(
7989                pi.packageName, targetPkg, targetUid, grantUri);
7990        perm.grantModes(modeFlags, owner);
7991    }
7992
7993    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7994            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7995        if (targetPkg == null) {
7996            throw new NullPointerException("targetPkg");
7997        }
7998        int targetUid;
7999        final IPackageManager pm = AppGlobals.getPackageManager();
8000        try {
8001            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8002        } catch (RemoteException ex) {
8003            return;
8004        }
8005
8006        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8007                targetUid);
8008        if (targetUid < 0) {
8009            return;
8010        }
8011
8012        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8013                owner);
8014    }
8015
8016    static class NeededUriGrants extends ArrayList<GrantUri> {
8017        final String targetPkg;
8018        final int targetUid;
8019        final int flags;
8020
8021        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8022            this.targetPkg = targetPkg;
8023            this.targetUid = targetUid;
8024            this.flags = flags;
8025        }
8026    }
8027
8028    /**
8029     * Like checkGrantUriPermissionLocked, but takes an Intent.
8030     */
8031    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8032            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8033        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8034                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8035                + " clip=" + (intent != null ? intent.getClipData() : null)
8036                + " from " + intent + "; flags=0x"
8037                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8038
8039        if (targetPkg == null) {
8040            throw new NullPointerException("targetPkg");
8041        }
8042
8043        if (intent == null) {
8044            return null;
8045        }
8046        Uri data = intent.getData();
8047        ClipData clip = intent.getClipData();
8048        if (data == null && clip == null) {
8049            return null;
8050        }
8051        // Default userId for uris in the intent (if they don't specify it themselves)
8052        int contentUserHint = intent.getContentUserHint();
8053        if (contentUserHint == UserHandle.USER_CURRENT) {
8054            contentUserHint = UserHandle.getUserId(callingUid);
8055        }
8056        final IPackageManager pm = AppGlobals.getPackageManager();
8057        int targetUid;
8058        if (needed != null) {
8059            targetUid = needed.targetUid;
8060        } else {
8061            try {
8062                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8063                        targetUserId);
8064            } catch (RemoteException ex) {
8065                return null;
8066            }
8067            if (targetUid < 0) {
8068                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8069                        "Can't grant URI permission no uid for: " + targetPkg
8070                        + " on user " + targetUserId);
8071                return null;
8072            }
8073        }
8074        if (data != null) {
8075            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8076            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8077                    targetUid);
8078            if (targetUid > 0) {
8079                if (needed == null) {
8080                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8081                }
8082                needed.add(grantUri);
8083            }
8084        }
8085        if (clip != null) {
8086            for (int i=0; i<clip.getItemCount(); i++) {
8087                Uri uri = clip.getItemAt(i).getUri();
8088                if (uri != null) {
8089                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8090                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8091                            targetUid);
8092                    if (targetUid > 0) {
8093                        if (needed == null) {
8094                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8095                        }
8096                        needed.add(grantUri);
8097                    }
8098                } else {
8099                    Intent clipIntent = clip.getItemAt(i).getIntent();
8100                    if (clipIntent != null) {
8101                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8102                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8103                        if (newNeeded != null) {
8104                            needed = newNeeded;
8105                        }
8106                    }
8107                }
8108            }
8109        }
8110
8111        return needed;
8112    }
8113
8114    /**
8115     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8116     */
8117    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8118            UriPermissionOwner owner) {
8119        if (needed != null) {
8120            for (int i=0; i<needed.size(); i++) {
8121                GrantUri grantUri = needed.get(i);
8122                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8123                        grantUri, needed.flags, owner);
8124            }
8125        }
8126    }
8127
8128    void grantUriPermissionFromIntentLocked(int callingUid,
8129            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8130        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8131                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8132        if (needed == null) {
8133            return;
8134        }
8135
8136        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8137    }
8138
8139    /**
8140     * @param uri This uri must NOT contain an embedded userId.
8141     * @param userId The userId in which the uri is to be resolved.
8142     */
8143    @Override
8144    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8145            final int modeFlags, int userId) {
8146        enforceNotIsolatedCaller("grantUriPermission");
8147        GrantUri grantUri = new GrantUri(userId, uri, false);
8148        synchronized(this) {
8149            final ProcessRecord r = getRecordForAppLocked(caller);
8150            if (r == null) {
8151                throw new SecurityException("Unable to find app for caller "
8152                        + caller
8153                        + " when granting permission to uri " + grantUri);
8154            }
8155            if (targetPkg == null) {
8156                throw new IllegalArgumentException("null target");
8157            }
8158            if (grantUri == null) {
8159                throw new IllegalArgumentException("null uri");
8160            }
8161
8162            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8163                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8164                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8165                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8166
8167            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8168                    UserHandle.getUserId(r.uid));
8169        }
8170    }
8171
8172    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8173        if (perm.modeFlags == 0) {
8174            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8175                    perm.targetUid);
8176            if (perms != null) {
8177                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8178                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8179
8180                perms.remove(perm.uri);
8181                if (perms.isEmpty()) {
8182                    mGrantedUriPermissions.remove(perm.targetUid);
8183                }
8184            }
8185        }
8186    }
8187
8188    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8189        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8190                "Revoking all granted permissions to " + grantUri);
8191
8192        final IPackageManager pm = AppGlobals.getPackageManager();
8193        final String authority = grantUri.uri.getAuthority();
8194        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8195        if (pi == null) {
8196            Slog.w(TAG, "No content provider found for permission revoke: "
8197                    + grantUri.toSafeString());
8198            return;
8199        }
8200
8201        // Does the caller have this permission on the URI?
8202        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8203            // If they don't have direct access to the URI, then revoke any
8204            // ownerless URI permissions that have been granted to them.
8205            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8206            if (perms != null) {
8207                boolean persistChanged = false;
8208                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8209                    final UriPermission perm = it.next();
8210                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8211                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8212                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8213                                "Revoking non-owned " + perm.targetUid
8214                                + " permission to " + perm.uri);
8215                        persistChanged |= perm.revokeModes(
8216                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8217                        if (perm.modeFlags == 0) {
8218                            it.remove();
8219                        }
8220                    }
8221                }
8222                if (perms.isEmpty()) {
8223                    mGrantedUriPermissions.remove(callingUid);
8224                }
8225                if (persistChanged) {
8226                    schedulePersistUriGrants();
8227                }
8228            }
8229            return;
8230        }
8231
8232        boolean persistChanged = false;
8233
8234        // Go through all of the permissions and remove any that match.
8235        int N = mGrantedUriPermissions.size();
8236        for (int i = 0; i < N; i++) {
8237            final int targetUid = mGrantedUriPermissions.keyAt(i);
8238            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8239
8240            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8241                final UriPermission perm = it.next();
8242                if (perm.uri.sourceUserId == grantUri.sourceUserId
8243                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8244                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8245                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8246                    persistChanged |= perm.revokeModes(
8247                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8248                    if (perm.modeFlags == 0) {
8249                        it.remove();
8250                    }
8251                }
8252            }
8253
8254            if (perms.isEmpty()) {
8255                mGrantedUriPermissions.remove(targetUid);
8256                N--;
8257                i--;
8258            }
8259        }
8260
8261        if (persistChanged) {
8262            schedulePersistUriGrants();
8263        }
8264    }
8265
8266    /**
8267     * @param uri This uri must NOT contain an embedded userId.
8268     * @param userId The userId in which the uri is to be resolved.
8269     */
8270    @Override
8271    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8272            int userId) {
8273        enforceNotIsolatedCaller("revokeUriPermission");
8274        synchronized(this) {
8275            final ProcessRecord r = getRecordForAppLocked(caller);
8276            if (r == null) {
8277                throw new SecurityException("Unable to find app for caller "
8278                        + caller
8279                        + " when revoking permission to uri " + uri);
8280            }
8281            if (uri == null) {
8282                Slog.w(TAG, "revokeUriPermission: null uri");
8283                return;
8284            }
8285
8286            if (!Intent.isAccessUriMode(modeFlags)) {
8287                return;
8288            }
8289
8290            final String authority = uri.getAuthority();
8291            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8292            if (pi == null) {
8293                Slog.w(TAG, "No content provider found for permission revoke: "
8294                        + uri.toSafeString());
8295                return;
8296            }
8297
8298            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8299        }
8300    }
8301
8302    /**
8303     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8304     * given package.
8305     *
8306     * @param packageName Package name to match, or {@code null} to apply to all
8307     *            packages.
8308     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8309     *            to all users.
8310     * @param persistable If persistable grants should be removed.
8311     */
8312    private void removeUriPermissionsForPackageLocked(
8313            String packageName, int userHandle, boolean persistable) {
8314        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8315            throw new IllegalArgumentException("Must narrow by either package or user");
8316        }
8317
8318        boolean persistChanged = false;
8319
8320        int N = mGrantedUriPermissions.size();
8321        for (int i = 0; i < N; i++) {
8322            final int targetUid = mGrantedUriPermissions.keyAt(i);
8323            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8324
8325            // Only inspect grants matching user
8326            if (userHandle == UserHandle.USER_ALL
8327                    || userHandle == UserHandle.getUserId(targetUid)) {
8328                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8329                    final UriPermission perm = it.next();
8330
8331                    // Only inspect grants matching package
8332                    if (packageName == null || perm.sourcePkg.equals(packageName)
8333                            || perm.targetPkg.equals(packageName)) {
8334                        persistChanged |= perm.revokeModes(persistable
8335                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8336
8337                        // Only remove when no modes remain; any persisted grants
8338                        // will keep this alive.
8339                        if (perm.modeFlags == 0) {
8340                            it.remove();
8341                        }
8342                    }
8343                }
8344
8345                if (perms.isEmpty()) {
8346                    mGrantedUriPermissions.remove(targetUid);
8347                    N--;
8348                    i--;
8349                }
8350            }
8351        }
8352
8353        if (persistChanged) {
8354            schedulePersistUriGrants();
8355        }
8356    }
8357
8358    @Override
8359    public IBinder newUriPermissionOwner(String name) {
8360        enforceNotIsolatedCaller("newUriPermissionOwner");
8361        synchronized(this) {
8362            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8363            return owner.getExternalTokenLocked();
8364        }
8365    }
8366
8367    @Override
8368    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8369        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8370        synchronized(this) {
8371            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8372            if (r == null) {
8373                throw new IllegalArgumentException("Activity does not exist; token="
8374                        + activityToken);
8375            }
8376            return r.getUriPermissionsLocked().getExternalTokenLocked();
8377        }
8378    }
8379    /**
8380     * @param uri This uri must NOT contain an embedded userId.
8381     * @param sourceUserId The userId in which the uri is to be resolved.
8382     * @param targetUserId The userId of the app that receives the grant.
8383     */
8384    @Override
8385    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8386            final int modeFlags, int sourceUserId, int targetUserId) {
8387        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8388                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8389                "grantUriPermissionFromOwner", null);
8390        synchronized(this) {
8391            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8392            if (owner == null) {
8393                throw new IllegalArgumentException("Unknown owner: " + token);
8394            }
8395            if (fromUid != Binder.getCallingUid()) {
8396                if (Binder.getCallingUid() != Process.myUid()) {
8397                    // Only system code can grant URI permissions on behalf
8398                    // of other users.
8399                    throw new SecurityException("nice try");
8400                }
8401            }
8402            if (targetPkg == null) {
8403                throw new IllegalArgumentException("null target");
8404            }
8405            if (uri == null) {
8406                throw new IllegalArgumentException("null uri");
8407            }
8408
8409            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8410                    modeFlags, owner, targetUserId);
8411        }
8412    }
8413
8414    /**
8415     * @param uri This uri must NOT contain an embedded userId.
8416     * @param userId The userId in which the uri is to be resolved.
8417     */
8418    @Override
8419    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8420        synchronized(this) {
8421            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8422            if (owner == null) {
8423                throw new IllegalArgumentException("Unknown owner: " + token);
8424            }
8425
8426            if (uri == null) {
8427                owner.removeUriPermissionsLocked(mode);
8428            } else {
8429                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8430            }
8431        }
8432    }
8433
8434    private void schedulePersistUriGrants() {
8435        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8436            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8437                    10 * DateUtils.SECOND_IN_MILLIS);
8438        }
8439    }
8440
8441    private void writeGrantedUriPermissions() {
8442        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8443
8444        // Snapshot permissions so we can persist without lock
8445        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8446        synchronized (this) {
8447            final int size = mGrantedUriPermissions.size();
8448            for (int i = 0; i < size; i++) {
8449                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8450                for (UriPermission perm : perms.values()) {
8451                    if (perm.persistedModeFlags != 0) {
8452                        persist.add(perm.snapshot());
8453                    }
8454                }
8455            }
8456        }
8457
8458        FileOutputStream fos = null;
8459        try {
8460            fos = mGrantFile.startWrite();
8461
8462            XmlSerializer out = new FastXmlSerializer();
8463            out.setOutput(fos, StandardCharsets.UTF_8.name());
8464            out.startDocument(null, true);
8465            out.startTag(null, TAG_URI_GRANTS);
8466            for (UriPermission.Snapshot perm : persist) {
8467                out.startTag(null, TAG_URI_GRANT);
8468                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8469                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8470                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8471                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8472                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8473                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8474                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8475                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8476                out.endTag(null, TAG_URI_GRANT);
8477            }
8478            out.endTag(null, TAG_URI_GRANTS);
8479            out.endDocument();
8480
8481            mGrantFile.finishWrite(fos);
8482        } catch (IOException e) {
8483            if (fos != null) {
8484                mGrantFile.failWrite(fos);
8485            }
8486        }
8487    }
8488
8489    private void readGrantedUriPermissionsLocked() {
8490        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8491
8492        final long now = System.currentTimeMillis();
8493
8494        FileInputStream fis = null;
8495        try {
8496            fis = mGrantFile.openRead();
8497            final XmlPullParser in = Xml.newPullParser();
8498            in.setInput(fis, StandardCharsets.UTF_8.name());
8499
8500            int type;
8501            while ((type = in.next()) != END_DOCUMENT) {
8502                final String tag = in.getName();
8503                if (type == START_TAG) {
8504                    if (TAG_URI_GRANT.equals(tag)) {
8505                        final int sourceUserId;
8506                        final int targetUserId;
8507                        final int userHandle = readIntAttribute(in,
8508                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8509                        if (userHandle != UserHandle.USER_NULL) {
8510                            // For backwards compatibility.
8511                            sourceUserId = userHandle;
8512                            targetUserId = userHandle;
8513                        } else {
8514                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8515                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8516                        }
8517                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8518                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8519                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8520                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8521                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8522                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8523
8524                        // Sanity check that provider still belongs to source package
8525                        final ProviderInfo pi = getProviderInfoLocked(
8526                                uri.getAuthority(), sourceUserId);
8527                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8528                            int targetUid = -1;
8529                            try {
8530                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8531                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8532                            } catch (RemoteException e) {
8533                            }
8534                            if (targetUid != -1) {
8535                                final UriPermission perm = findOrCreateUriPermissionLocked(
8536                                        sourcePkg, targetPkg, targetUid,
8537                                        new GrantUri(sourceUserId, uri, prefix));
8538                                perm.initPersistedModes(modeFlags, createdTime);
8539                            }
8540                        } else {
8541                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8542                                    + " but instead found " + pi);
8543                        }
8544                    }
8545                }
8546            }
8547        } catch (FileNotFoundException e) {
8548            // Missing grants is okay
8549        } catch (IOException e) {
8550            Slog.wtf(TAG, "Failed reading Uri grants", e);
8551        } catch (XmlPullParserException e) {
8552            Slog.wtf(TAG, "Failed reading Uri grants", e);
8553        } finally {
8554            IoUtils.closeQuietly(fis);
8555        }
8556    }
8557
8558    /**
8559     * @param uri This uri must NOT contain an embedded userId.
8560     * @param userId The userId in which the uri is to be resolved.
8561     */
8562    @Override
8563    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8564        enforceNotIsolatedCaller("takePersistableUriPermission");
8565
8566        Preconditions.checkFlagsArgument(modeFlags,
8567                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8568
8569        synchronized (this) {
8570            final int callingUid = Binder.getCallingUid();
8571            boolean persistChanged = false;
8572            GrantUri grantUri = new GrantUri(userId, uri, false);
8573
8574            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8575                    new GrantUri(userId, uri, false));
8576            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8577                    new GrantUri(userId, uri, true));
8578
8579            final boolean exactValid = (exactPerm != null)
8580                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8581            final boolean prefixValid = (prefixPerm != null)
8582                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8583
8584            if (!(exactValid || prefixValid)) {
8585                throw new SecurityException("No persistable permission grants found for UID "
8586                        + callingUid + " and Uri " + grantUri.toSafeString());
8587            }
8588
8589            if (exactValid) {
8590                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8591            }
8592            if (prefixValid) {
8593                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8594            }
8595
8596            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8597
8598            if (persistChanged) {
8599                schedulePersistUriGrants();
8600            }
8601        }
8602    }
8603
8604    /**
8605     * @param uri This uri must NOT contain an embedded userId.
8606     * @param userId The userId in which the uri is to be resolved.
8607     */
8608    @Override
8609    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8610        enforceNotIsolatedCaller("releasePersistableUriPermission");
8611
8612        Preconditions.checkFlagsArgument(modeFlags,
8613                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8614
8615        synchronized (this) {
8616            final int callingUid = Binder.getCallingUid();
8617            boolean persistChanged = false;
8618
8619            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8620                    new GrantUri(userId, uri, false));
8621            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8622                    new GrantUri(userId, uri, true));
8623            if (exactPerm == null && prefixPerm == null) {
8624                throw new SecurityException("No permission grants found for UID " + callingUid
8625                        + " and Uri " + uri.toSafeString());
8626            }
8627
8628            if (exactPerm != null) {
8629                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8630                removeUriPermissionIfNeededLocked(exactPerm);
8631            }
8632            if (prefixPerm != null) {
8633                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8634                removeUriPermissionIfNeededLocked(prefixPerm);
8635            }
8636
8637            if (persistChanged) {
8638                schedulePersistUriGrants();
8639            }
8640        }
8641    }
8642
8643    /**
8644     * Prune any older {@link UriPermission} for the given UID until outstanding
8645     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8646     *
8647     * @return if any mutations occured that require persisting.
8648     */
8649    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8650        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8651        if (perms == null) return false;
8652        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8653
8654        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8655        for (UriPermission perm : perms.values()) {
8656            if (perm.persistedModeFlags != 0) {
8657                persisted.add(perm);
8658            }
8659        }
8660
8661        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8662        if (trimCount <= 0) return false;
8663
8664        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8665        for (int i = 0; i < trimCount; i++) {
8666            final UriPermission perm = persisted.get(i);
8667
8668            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8669                    "Trimming grant created at " + perm.persistedCreateTime);
8670
8671            perm.releasePersistableModes(~0);
8672            removeUriPermissionIfNeededLocked(perm);
8673        }
8674
8675        return true;
8676    }
8677
8678    @Override
8679    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8680            String packageName, boolean incoming) {
8681        enforceNotIsolatedCaller("getPersistedUriPermissions");
8682        Preconditions.checkNotNull(packageName, "packageName");
8683
8684        final int callingUid = Binder.getCallingUid();
8685        final IPackageManager pm = AppGlobals.getPackageManager();
8686        try {
8687            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8688                    UserHandle.getUserId(callingUid));
8689            if (packageUid != callingUid) {
8690                throw new SecurityException(
8691                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8692            }
8693        } catch (RemoteException e) {
8694            throw new SecurityException("Failed to verify package name ownership");
8695        }
8696
8697        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8698        synchronized (this) {
8699            if (incoming) {
8700                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8701                        callingUid);
8702                if (perms == null) {
8703                    Slog.w(TAG, "No permission grants found for " + packageName);
8704                } else {
8705                    for (UriPermission perm : perms.values()) {
8706                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8707                            result.add(perm.buildPersistedPublicApiObject());
8708                        }
8709                    }
8710                }
8711            } else {
8712                final int size = mGrantedUriPermissions.size();
8713                for (int i = 0; i < size; i++) {
8714                    final ArrayMap<GrantUri, UriPermission> perms =
8715                            mGrantedUriPermissions.valueAt(i);
8716                    for (UriPermission perm : perms.values()) {
8717                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8718                            result.add(perm.buildPersistedPublicApiObject());
8719                        }
8720                    }
8721                }
8722            }
8723        }
8724        return new ParceledListSlice<android.content.UriPermission>(result);
8725    }
8726
8727    @Override
8728    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8729            String packageName, int userId) {
8730        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8731                "getGrantedUriPermissions");
8732
8733        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8734        synchronized (this) {
8735            final int size = mGrantedUriPermissions.size();
8736            for (int i = 0; i < size; i++) {
8737                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8738                for (UriPermission perm : perms.values()) {
8739                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8740                            && perm.persistedModeFlags != 0) {
8741                        result.add(perm.buildPersistedPublicApiObject());
8742                    }
8743                }
8744            }
8745        }
8746        return new ParceledListSlice<android.content.UriPermission>(result);
8747    }
8748
8749    @Override
8750    public void clearGrantedUriPermissions(String packageName, int userId) {
8751        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8752                "clearGrantedUriPermissions");
8753        removeUriPermissionsForPackageLocked(packageName, userId, true);
8754    }
8755
8756    @Override
8757    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8758        synchronized (this) {
8759            ProcessRecord app =
8760                who != null ? getRecordForAppLocked(who) : null;
8761            if (app == null) return;
8762
8763            Message msg = Message.obtain();
8764            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8765            msg.obj = app;
8766            msg.arg1 = waiting ? 1 : 0;
8767            mUiHandler.sendMessage(msg);
8768        }
8769    }
8770
8771    @Override
8772    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8773        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8774        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8775        outInfo.availMem = Process.getFreeMemory();
8776        outInfo.totalMem = Process.getTotalMemory();
8777        outInfo.threshold = homeAppMem;
8778        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8779        outInfo.hiddenAppThreshold = cachedAppMem;
8780        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8781                ProcessList.SERVICE_ADJ);
8782        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8783                ProcessList.VISIBLE_APP_ADJ);
8784        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8785                ProcessList.FOREGROUND_APP_ADJ);
8786    }
8787
8788    // =========================================================
8789    // TASK MANAGEMENT
8790    // =========================================================
8791
8792    @Override
8793    public List<IAppTask> getAppTasks(String callingPackage) {
8794        int callingUid = Binder.getCallingUid();
8795        long ident = Binder.clearCallingIdentity();
8796
8797        synchronized(this) {
8798            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8799            try {
8800                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8801
8802                final int N = mRecentTasks.size();
8803                for (int i = 0; i < N; i++) {
8804                    TaskRecord tr = mRecentTasks.get(i);
8805                    // Skip tasks that do not match the caller.  We don't need to verify
8806                    // callingPackage, because we are also limiting to callingUid and know
8807                    // that will limit to the correct security sandbox.
8808                    if (tr.effectiveUid != callingUid) {
8809                        continue;
8810                    }
8811                    Intent intent = tr.getBaseIntent();
8812                    if (intent == null ||
8813                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8814                        continue;
8815                    }
8816                    ActivityManager.RecentTaskInfo taskInfo =
8817                            createRecentTaskInfoFromTaskRecord(tr);
8818                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8819                    list.add(taskImpl);
8820                }
8821            } finally {
8822                Binder.restoreCallingIdentity(ident);
8823            }
8824            return list;
8825        }
8826    }
8827
8828    @Override
8829    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8830        final int callingUid = Binder.getCallingUid();
8831        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8832
8833        synchronized(this) {
8834            if (DEBUG_ALL) Slog.v(
8835                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8836
8837            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8838                    callingUid);
8839
8840            // TODO: Improve with MRU list from all ActivityStacks.
8841            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8842        }
8843
8844        return list;
8845    }
8846
8847    /**
8848     * Creates a new RecentTaskInfo from a TaskRecord.
8849     */
8850    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8851        // Update the task description to reflect any changes in the task stack
8852        tr.updateTaskDescription();
8853
8854        // Compose the recent task info
8855        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8856        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8857        rti.persistentId = tr.taskId;
8858        rti.baseIntent = new Intent(tr.getBaseIntent());
8859        rti.origActivity = tr.origActivity;
8860        rti.realActivity = tr.realActivity;
8861        rti.description = tr.lastDescription;
8862        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8863        rti.userId = tr.userId;
8864        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8865        rti.firstActiveTime = tr.firstActiveTime;
8866        rti.lastActiveTime = tr.lastActiveTime;
8867        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8868        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8869        rti.numActivities = 0;
8870        if (tr.mBounds != null) {
8871            rti.bounds = new Rect(tr.mBounds);
8872        }
8873        rti.isDockable = tr.canGoInDockedStack();
8874        rti.resizeMode = tr.mResizeMode;
8875
8876        ActivityRecord base = null;
8877        ActivityRecord top = null;
8878        ActivityRecord tmp;
8879
8880        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8881            tmp = tr.mActivities.get(i);
8882            if (tmp.finishing) {
8883                continue;
8884            }
8885            base = tmp;
8886            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8887                top = base;
8888            }
8889            rti.numActivities++;
8890        }
8891
8892        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8893        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8894
8895        return rti;
8896    }
8897
8898    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8899        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8900                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8901        if (!allowed) {
8902            if (checkPermission(android.Manifest.permission.GET_TASKS,
8903                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8904                // Temporary compatibility: some existing apps on the system image may
8905                // still be requesting the old permission and not switched to the new
8906                // one; if so, we'll still allow them full access.  This means we need
8907                // to see if they are holding the old permission and are a system app.
8908                try {
8909                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8910                        allowed = true;
8911                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8912                                + " is using old GET_TASKS but privileged; allowing");
8913                    }
8914                } catch (RemoteException e) {
8915                }
8916            }
8917        }
8918        if (!allowed) {
8919            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8920                    + " does not hold REAL_GET_TASKS; limiting output");
8921        }
8922        return allowed;
8923    }
8924
8925    @Override
8926    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8927        final int callingUid = Binder.getCallingUid();
8928        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8929                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8930
8931        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8932        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8933        synchronized (this) {
8934            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8935                    callingUid);
8936            final boolean detailed = checkCallingPermission(
8937                    android.Manifest.permission.GET_DETAILED_TASKS)
8938                    == PackageManager.PERMISSION_GRANTED;
8939
8940            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8941                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8942                return Collections.emptyList();
8943            }
8944            mRecentTasks.loadUserRecentsLocked(userId);
8945
8946            final int recentsCount = mRecentTasks.size();
8947            ArrayList<ActivityManager.RecentTaskInfo> res =
8948                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8949
8950            final Set<Integer> includedUsers;
8951            if (includeProfiles) {
8952                includedUsers = mUserController.getProfileIds(userId);
8953            } else {
8954                includedUsers = new HashSet<>();
8955            }
8956            includedUsers.add(Integer.valueOf(userId));
8957
8958            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8959                TaskRecord tr = mRecentTasks.get(i);
8960                // Only add calling user or related users recent tasks
8961                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8962                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8963                    continue;
8964                }
8965
8966                if (tr.realActivitySuspended) {
8967                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8968                    continue;
8969                }
8970
8971                // Return the entry if desired by the caller.  We always return
8972                // the first entry, because callers always expect this to be the
8973                // foreground app.  We may filter others if the caller has
8974                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8975                // we should exclude the entry.
8976
8977                if (i == 0
8978                        || withExcluded
8979                        || (tr.intent == null)
8980                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8981                                == 0)) {
8982                    if (!allowed) {
8983                        // If the caller doesn't have the GET_TASKS permission, then only
8984                        // allow them to see a small subset of tasks -- their own and home.
8985                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8986                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8987                            continue;
8988                        }
8989                    }
8990                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8991                        if (tr.stack != null && tr.stack.isHomeStack()) {
8992                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8993                                    "Skipping, home stack task: " + tr);
8994                            continue;
8995                        }
8996                    }
8997                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8998                        final ActivityStack stack = tr.stack;
8999                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9000                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9001                                    "Skipping, top task in docked stack: " + tr);
9002                            continue;
9003                        }
9004                    }
9005                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9006                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9007                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9008                                    "Skipping, pinned stack task: " + tr);
9009                            continue;
9010                        }
9011                    }
9012                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9013                        // Don't include auto remove tasks that are finished or finishing.
9014                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9015                                "Skipping, auto-remove without activity: " + tr);
9016                        continue;
9017                    }
9018                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9019                            && !tr.isAvailable) {
9020                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9021                                "Skipping, unavail real act: " + tr);
9022                        continue;
9023                    }
9024
9025                    if (!tr.mUserSetupComplete) {
9026                        // Don't include task launched while user is not done setting-up.
9027                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9028                                "Skipping, user setup not complete: " + tr);
9029                        continue;
9030                    }
9031
9032                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9033                    if (!detailed) {
9034                        rti.baseIntent.replaceExtras((Bundle)null);
9035                    }
9036
9037                    res.add(rti);
9038                    maxNum--;
9039                }
9040            }
9041            return res;
9042        }
9043    }
9044
9045    @Override
9046    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9047        synchronized (this) {
9048            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9049                    "getTaskThumbnail()");
9050            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9051                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9052            if (tr != null) {
9053                return tr.getTaskThumbnailLocked();
9054            }
9055        }
9056        return null;
9057    }
9058
9059    @Override
9060    public int addAppTask(IBinder activityToken, Intent intent,
9061            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9062        final int callingUid = Binder.getCallingUid();
9063        final long callingIdent = Binder.clearCallingIdentity();
9064
9065        try {
9066            synchronized (this) {
9067                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9068                if (r == null) {
9069                    throw new IllegalArgumentException("Activity does not exist; token="
9070                            + activityToken);
9071                }
9072                ComponentName comp = intent.getComponent();
9073                if (comp == null) {
9074                    throw new IllegalArgumentException("Intent " + intent
9075                            + " must specify explicit component");
9076                }
9077                if (thumbnail.getWidth() != mThumbnailWidth
9078                        || thumbnail.getHeight() != mThumbnailHeight) {
9079                    throw new IllegalArgumentException("Bad thumbnail size: got "
9080                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9081                            + mThumbnailWidth + "x" + mThumbnailHeight);
9082                }
9083                if (intent.getSelector() != null) {
9084                    intent.setSelector(null);
9085                }
9086                if (intent.getSourceBounds() != null) {
9087                    intent.setSourceBounds(null);
9088                }
9089                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9090                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9091                        // The caller has added this as an auto-remove task...  that makes no
9092                        // sense, so turn off auto-remove.
9093                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9094                    }
9095                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9096                    // Must be a new task.
9097                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9098                }
9099                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9100                    mLastAddedTaskActivity = null;
9101                }
9102                ActivityInfo ainfo = mLastAddedTaskActivity;
9103                if (ainfo == null) {
9104                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9105                            comp, 0, UserHandle.getUserId(callingUid));
9106                    if (ainfo.applicationInfo.uid != callingUid) {
9107                        throw new SecurityException(
9108                                "Can't add task for another application: target uid="
9109                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9110                    }
9111                }
9112
9113                // Use the full screen as the context for the task thumbnail
9114                final Point displaySize = new Point();
9115                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9116                r.task.stack.getDisplaySize(displaySize);
9117                thumbnailInfo.taskWidth = displaySize.x;
9118                thumbnailInfo.taskHeight = displaySize.y;
9119                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9120
9121                TaskRecord task = new TaskRecord(this,
9122                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9123                        ainfo, intent, description, thumbnailInfo);
9124
9125                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9126                if (trimIdx >= 0) {
9127                    // If this would have caused a trim, then we'll abort because that
9128                    // means it would be added at the end of the list but then just removed.
9129                    return INVALID_TASK_ID;
9130                }
9131
9132                final int N = mRecentTasks.size();
9133                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9134                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9135                    tr.removedFromRecents();
9136                }
9137
9138                task.inRecents = true;
9139                mRecentTasks.add(task);
9140                r.task.stack.addTask(task, false, "addAppTask");
9141
9142                task.setLastThumbnailLocked(thumbnail);
9143                task.freeLastThumbnail();
9144
9145                return task.taskId;
9146            }
9147        } finally {
9148            Binder.restoreCallingIdentity(callingIdent);
9149        }
9150    }
9151
9152    @Override
9153    public Point getAppTaskThumbnailSize() {
9154        synchronized (this) {
9155            return new Point(mThumbnailWidth,  mThumbnailHeight);
9156        }
9157    }
9158
9159    @Override
9160    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9161        synchronized (this) {
9162            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9163            if (r != null) {
9164                r.setTaskDescription(td);
9165                r.task.updateTaskDescription();
9166            }
9167        }
9168    }
9169
9170    @Override
9171    public void setTaskResizeable(int taskId, int resizeableMode) {
9172        synchronized (this) {
9173            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9174                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9175            if (task == null) {
9176                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9177                return;
9178            }
9179            if (task.mResizeMode != resizeableMode) {
9180                task.mResizeMode = resizeableMode;
9181                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9182                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9183                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9184            }
9185        }
9186    }
9187
9188    @Override
9189    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9190        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9191        long ident = Binder.clearCallingIdentity();
9192        try {
9193            synchronized (this) {
9194                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9195                if (task == null) {
9196                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9197                    return;
9198                }
9199                int stackId = task.stack.mStackId;
9200                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9201                // in crop windows resize mode or if the task size is affected by the docked stack
9202                // changing size. No need to update configuration.
9203                if (bounds != null && task.inCropWindowsResizeMode()
9204                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9205                    mWindowManager.scrollTask(task.taskId, bounds);
9206                    return;
9207                }
9208
9209                // Place the task in the right stack if it isn't there already based on
9210                // the requested bounds.
9211                // The stack transition logic is:
9212                // - a null bounds on a freeform task moves that task to fullscreen
9213                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9214                //   that task to freeform
9215                // - otherwise the task is not moved
9216                if (!StackId.isTaskResizeAllowed(stackId)) {
9217                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9218                }
9219                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9220                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9221                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9222                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9223                }
9224                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9225                if (stackId != task.stack.mStackId) {
9226                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9227                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9228                    preserveWindow = false;
9229                }
9230
9231                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9232                        false /* deferResume */);
9233            }
9234        } finally {
9235            Binder.restoreCallingIdentity(ident);
9236        }
9237    }
9238
9239    @Override
9240    public Rect getTaskBounds(int taskId) {
9241        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9242        long ident = Binder.clearCallingIdentity();
9243        Rect rect = new Rect();
9244        try {
9245            synchronized (this) {
9246                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9247                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9248                if (task == null) {
9249                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9250                    return rect;
9251                }
9252                if (task.stack != null) {
9253                    // Return the bounds from window manager since it will be adjusted for various
9254                    // things like the presense of a docked stack for tasks that aren't resizeable.
9255                    mWindowManager.getTaskBounds(task.taskId, rect);
9256                } else {
9257                    // Task isn't in window manager yet since it isn't associated with a stack.
9258                    // Return the persist value from activity manager
9259                    if (task.mBounds != null) {
9260                        rect.set(task.mBounds);
9261                    } else if (task.mLastNonFullscreenBounds != null) {
9262                        rect.set(task.mLastNonFullscreenBounds);
9263                    }
9264                }
9265            }
9266        } finally {
9267            Binder.restoreCallingIdentity(ident);
9268        }
9269        return rect;
9270    }
9271
9272    @Override
9273    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9274        if (userId != UserHandle.getCallingUserId()) {
9275            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9276                    "getTaskDescriptionIcon");
9277        }
9278        final File passedIconFile = new File(filePath);
9279        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9280                passedIconFile.getName());
9281        if (!legitIconFile.getPath().equals(filePath)
9282                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9283            throw new IllegalArgumentException("Bad file path: " + filePath
9284                    + " passed for userId " + userId);
9285        }
9286        return mRecentTasks.getTaskDescriptionIcon(filePath);
9287    }
9288
9289    @Override
9290    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9291            throws RemoteException {
9292        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9293                opts.getCustomInPlaceResId() == 0) {
9294            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9295                    "with valid animation");
9296        }
9297        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9298        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9299                opts.getCustomInPlaceResId());
9300        mWindowManager.executeAppTransition();
9301    }
9302
9303    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9304            boolean removeFromRecents) {
9305        if (removeFromRecents) {
9306            mRecentTasks.remove(tr);
9307            tr.removedFromRecents();
9308        }
9309        ComponentName component = tr.getBaseIntent().getComponent();
9310        if (component == null) {
9311            Slog.w(TAG, "No component for base intent of task: " + tr);
9312            return;
9313        }
9314
9315        // Find any running services associated with this app and stop if needed.
9316        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9317
9318        if (!killProcess) {
9319            return;
9320        }
9321
9322        // Determine if the process(es) for this task should be killed.
9323        final String pkg = component.getPackageName();
9324        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9325        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9326        for (int i = 0; i < pmap.size(); i++) {
9327
9328            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9329            for (int j = 0; j < uids.size(); j++) {
9330                ProcessRecord proc = uids.valueAt(j);
9331                if (proc.userId != tr.userId) {
9332                    // Don't kill process for a different user.
9333                    continue;
9334                }
9335                if (proc == mHomeProcess) {
9336                    // Don't kill the home process along with tasks from the same package.
9337                    continue;
9338                }
9339                if (!proc.pkgList.containsKey(pkg)) {
9340                    // Don't kill process that is not associated with this task.
9341                    continue;
9342                }
9343
9344                for (int k = 0; k < proc.activities.size(); k++) {
9345                    TaskRecord otherTask = proc.activities.get(k).task;
9346                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9347                        // Don't kill process(es) that has an activity in a different task that is
9348                        // also in recents.
9349                        return;
9350                    }
9351                }
9352
9353                if (proc.foregroundServices) {
9354                    // Don't kill process(es) with foreground service.
9355                    return;
9356                }
9357
9358                // Add process to kill list.
9359                procsToKill.add(proc);
9360            }
9361        }
9362
9363        // Kill the running processes.
9364        for (int i = 0; i < procsToKill.size(); i++) {
9365            ProcessRecord pr = procsToKill.get(i);
9366            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9367                    && pr.curReceiver == null) {
9368                pr.kill("remove task", true);
9369            } else {
9370                // We delay killing processes that are not in the background or running a receiver.
9371                pr.waitingToKill = "remove task";
9372            }
9373        }
9374    }
9375
9376    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9377        // Remove all tasks with activities in the specified package from the list of recent tasks
9378        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9379            TaskRecord tr = mRecentTasks.get(i);
9380            if (tr.userId != userId) continue;
9381
9382            ComponentName cn = tr.intent.getComponent();
9383            if (cn != null && cn.getPackageName().equals(packageName)) {
9384                // If the package name matches, remove the task.
9385                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9386            }
9387        }
9388    }
9389
9390    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9391            int userId) {
9392
9393        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9394            TaskRecord tr = mRecentTasks.get(i);
9395            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9396                continue;
9397            }
9398
9399            ComponentName cn = tr.intent.getComponent();
9400            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9401                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9402            if (sameComponent) {
9403                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9404            }
9405        }
9406    }
9407
9408    /**
9409     * Removes the task with the specified task id.
9410     *
9411     * @param taskId Identifier of the task to be removed.
9412     * @param killProcess Kill any process associated with the task if possible.
9413     * @param removeFromRecents Whether to also remove the task from recents.
9414     * @return Returns true if the given task was found and removed.
9415     */
9416    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9417            boolean removeFromRecents) {
9418        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9419                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9420        if (tr != null) {
9421            tr.removeTaskActivitiesLocked();
9422            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9423            if (tr.isPersistable) {
9424                notifyTaskPersisterLocked(null, true);
9425            }
9426            return true;
9427        }
9428        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9429        return false;
9430    }
9431
9432    @Override
9433    public void removeStack(int stackId) {
9434        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9435        if (stackId == HOME_STACK_ID) {
9436            throw new IllegalArgumentException("Removing home stack is not allowed.");
9437        }
9438
9439        synchronized (this) {
9440            final long ident = Binder.clearCallingIdentity();
9441            try {
9442                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9443                if (stack == null) {
9444                    return;
9445                }
9446                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9447                for (int i = tasks.size() - 1; i >= 0; i--) {
9448                    removeTaskByIdLocked(
9449                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9450                }
9451            } finally {
9452                Binder.restoreCallingIdentity(ident);
9453            }
9454        }
9455    }
9456
9457    @Override
9458    public boolean removeTask(int taskId) {
9459        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9460        synchronized (this) {
9461            final long ident = Binder.clearCallingIdentity();
9462            try {
9463                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9464            } finally {
9465                Binder.restoreCallingIdentity(ident);
9466            }
9467        }
9468    }
9469
9470    /**
9471     * TODO: Add mController hook
9472     */
9473    @Override
9474    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9475        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9476
9477        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9478        synchronized(this) {
9479            moveTaskToFrontLocked(taskId, flags, bOptions);
9480        }
9481    }
9482
9483    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9484        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9485
9486        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9487                Binder.getCallingUid(), -1, -1, "Task to front")) {
9488            ActivityOptions.abort(options);
9489            return;
9490        }
9491        final long origId = Binder.clearCallingIdentity();
9492        try {
9493            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9494            if (task == null) {
9495                Slog.d(TAG, "Could not find task for id: "+ taskId);
9496                return;
9497            }
9498            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9499                mStackSupervisor.showLockTaskToast();
9500                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9501                return;
9502            }
9503            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9504            if (prev != null && prev.isRecentsActivity()) {
9505                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9506            }
9507            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9508                    false /* forceNonResizable */);
9509        } finally {
9510            Binder.restoreCallingIdentity(origId);
9511        }
9512        ActivityOptions.abort(options);
9513    }
9514
9515    /**
9516     * Moves an activity, and all of the other activities within the same task, to the bottom
9517     * of the history stack.  The activity's order within the task is unchanged.
9518     *
9519     * @param token A reference to the activity we wish to move
9520     * @param nonRoot If false then this only works if the activity is the root
9521     *                of a task; if true it will work for any activity in a task.
9522     * @return Returns true if the move completed, false if not.
9523     */
9524    @Override
9525    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9526        enforceNotIsolatedCaller("moveActivityTaskToBack");
9527        synchronized(this) {
9528            final long origId = Binder.clearCallingIdentity();
9529            try {
9530                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9531                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9532                if (task != null) {
9533                    if (mStackSupervisor.isLockedTask(task)) {
9534                        mStackSupervisor.showLockTaskToast();
9535                        return false;
9536                    }
9537                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9538                }
9539            } finally {
9540                Binder.restoreCallingIdentity(origId);
9541            }
9542        }
9543        return false;
9544    }
9545
9546    @Override
9547    public void moveTaskBackwards(int task) {
9548        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9549                "moveTaskBackwards()");
9550
9551        synchronized(this) {
9552            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9553                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9554                return;
9555            }
9556            final long origId = Binder.clearCallingIdentity();
9557            moveTaskBackwardsLocked(task);
9558            Binder.restoreCallingIdentity(origId);
9559        }
9560    }
9561
9562    private final void moveTaskBackwardsLocked(int task) {
9563        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9564    }
9565
9566    @Override
9567    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9568            IActivityContainerCallback callback) throws RemoteException {
9569        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9570        synchronized (this) {
9571            if (parentActivityToken == null) {
9572                throw new IllegalArgumentException("parent token must not be null");
9573            }
9574            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9575            if (r == null) {
9576                return null;
9577            }
9578            if (callback == null) {
9579                throw new IllegalArgumentException("callback must not be null");
9580            }
9581            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9582        }
9583    }
9584
9585    @Override
9586    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9587        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9588        synchronized (this) {
9589            mStackSupervisor.deleteActivityContainer(container);
9590        }
9591    }
9592
9593    @Override
9594    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9595        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9596        synchronized (this) {
9597            final int stackId = mStackSupervisor.getNextStackId();
9598            final ActivityStack stack =
9599                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9600            if (stack == null) {
9601                return null;
9602            }
9603            return stack.mActivityContainer;
9604        }
9605    }
9606
9607    @Override
9608    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9609        synchronized (this) {
9610            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9611            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9612                return stack.mActivityContainer.getDisplayId();
9613            }
9614            return Display.DEFAULT_DISPLAY;
9615        }
9616    }
9617
9618    @Override
9619    public int getActivityStackId(IBinder token) throws RemoteException {
9620        synchronized (this) {
9621            ActivityStack stack = ActivityRecord.getStackLocked(token);
9622            if (stack == null) {
9623                return INVALID_STACK_ID;
9624            }
9625            return stack.mStackId;
9626        }
9627    }
9628
9629    @Override
9630    public void exitFreeformMode(IBinder token) throws RemoteException {
9631        synchronized (this) {
9632            long ident = Binder.clearCallingIdentity();
9633            try {
9634                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9635                if (r == null) {
9636                    throw new IllegalArgumentException(
9637                            "exitFreeformMode: No activity record matching token=" + token);
9638                }
9639                final ActivityStack stack = r.getStackLocked(token);
9640                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9641                    throw new IllegalStateException(
9642                            "exitFreeformMode: You can only go fullscreen from freeform.");
9643                }
9644                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9645                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9646                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9647            } finally {
9648                Binder.restoreCallingIdentity(ident);
9649            }
9650        }
9651    }
9652
9653    @Override
9654    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9655        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9656        if (stackId == HOME_STACK_ID) {
9657            throw new IllegalArgumentException(
9658                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9659        }
9660        synchronized (this) {
9661            long ident = Binder.clearCallingIdentity();
9662            try {
9663                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9664                        + " to stackId=" + stackId + " toTop=" + toTop);
9665                if (stackId == DOCKED_STACK_ID) {
9666                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9667                            null /* initialBounds */);
9668                }
9669                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9670                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9671                if (result && stackId == DOCKED_STACK_ID) {
9672                    // If task moved to docked stack - show recents if needed.
9673                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9674                            "moveTaskToDockedStack");
9675                }
9676            } finally {
9677                Binder.restoreCallingIdentity(ident);
9678            }
9679        }
9680    }
9681
9682    @Override
9683    public void swapDockedAndFullscreenStack() throws RemoteException {
9684        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9685        synchronized (this) {
9686            long ident = Binder.clearCallingIdentity();
9687            try {
9688                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9689                        FULLSCREEN_WORKSPACE_STACK_ID);
9690                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9691                        : null;
9692                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9693                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9694                        : null;
9695                if (topTask == null || tasks == null || tasks.size() == 0) {
9696                    Slog.w(TAG,
9697                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9698                    return;
9699                }
9700
9701                // TODO: App transition
9702                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9703
9704                // Defer the resume so resume/pausing while moving stacks is dangerous.
9705                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9706                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9707                        ANIMATE, true /* deferResume */);
9708                final int size = tasks.size();
9709                for (int i = 0; i < size; i++) {
9710                    final int id = tasks.get(i).taskId;
9711                    if (id == topTask.taskId) {
9712                        continue;
9713                    }
9714                    mStackSupervisor.moveTaskToStackLocked(id,
9715                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9716                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9717                }
9718
9719                // Because we deferred the resume, to avoid conflicts with stack switches while
9720                // resuming, we need to do it after all the tasks are moved.
9721                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9722                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9723
9724                mWindowManager.executeAppTransition();
9725            } finally {
9726                Binder.restoreCallingIdentity(ident);
9727            }
9728        }
9729    }
9730
9731    /**
9732     * Moves the input task to the docked stack.
9733     *
9734     * @param taskId Id of task to move.
9735     * @param createMode The mode the docked stack should be created in if it doesn't exist
9736     *                   already. See
9737     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9738     *                   and
9739     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9740     * @param toTop If the task and stack should be moved to the top.
9741     * @param animate Whether we should play an animation for the moving the task
9742     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9743     *                      docked stack. Pass {@code null} to use default bounds.
9744     */
9745    @Override
9746    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9747            Rect initialBounds, boolean moveHomeStackFront) {
9748        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9749        synchronized (this) {
9750            long ident = Binder.clearCallingIdentity();
9751            try {
9752                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9753                        + " to createMode=" + createMode + " toTop=" + toTop);
9754                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9755                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9756                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9757                        animate, DEFER_RESUME);
9758                if (moved) {
9759                    if (moveHomeStackFront) {
9760                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9761                    }
9762                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9763                }
9764                return moved;
9765            } finally {
9766                Binder.restoreCallingIdentity(ident);
9767            }
9768        }
9769    }
9770
9771    /**
9772     * Moves the top activity in the input stackId to the pinned stack.
9773     *
9774     * @param stackId Id of stack to move the top activity to pinned stack.
9775     * @param bounds Bounds to use for pinned stack.
9776     *
9777     * @return True if the top activity of the input stack was successfully moved to the pinned
9778     *          stack.
9779     */
9780    @Override
9781    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9782        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9783        synchronized (this) {
9784            if (!mSupportsPictureInPicture) {
9785                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9786                        + "Device doesn't support picture-in-pciture mode");
9787            }
9788
9789            long ident = Binder.clearCallingIdentity();
9790            try {
9791                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9792            } finally {
9793                Binder.restoreCallingIdentity(ident);
9794            }
9795        }
9796    }
9797
9798    @Override
9799    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9800            boolean preserveWindows, boolean animate, int animationDuration) {
9801        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9802        long ident = Binder.clearCallingIdentity();
9803        try {
9804            synchronized (this) {
9805                if (animate) {
9806                    if (stackId == PINNED_STACK_ID) {
9807                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9808                    } else {
9809                        throw new IllegalArgumentException("Stack: " + stackId
9810                                + " doesn't support animated resize.");
9811                    }
9812                } else {
9813                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9814                            null /* tempTaskInsetBounds */, preserveWindows,
9815                            allowResizeInDockedMode, !DEFER_RESUME);
9816                }
9817            }
9818        } finally {
9819            Binder.restoreCallingIdentity(ident);
9820        }
9821    }
9822
9823    @Override
9824    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9825            Rect tempDockedTaskInsetBounds,
9826            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9827        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9828                "resizeDockedStack()");
9829        long ident = Binder.clearCallingIdentity();
9830        try {
9831            synchronized (this) {
9832                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9833                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9834                        PRESERVE_WINDOWS);
9835            }
9836        } finally {
9837            Binder.restoreCallingIdentity(ident);
9838        }
9839    }
9840
9841    @Override
9842    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9843        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9844                "resizePinnedStack()");
9845        final long ident = Binder.clearCallingIdentity();
9846        try {
9847            synchronized (this) {
9848                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9849            }
9850        } finally {
9851            Binder.restoreCallingIdentity(ident);
9852        }
9853    }
9854
9855    @Override
9856    public void positionTaskInStack(int taskId, int stackId, int position) {
9857        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9858        if (stackId == HOME_STACK_ID) {
9859            throw new IllegalArgumentException(
9860                    "positionTaskInStack: Attempt to change the position of task "
9861                    + taskId + " in/to home stack");
9862        }
9863        synchronized (this) {
9864            long ident = Binder.clearCallingIdentity();
9865            try {
9866                if (DEBUG_STACK) Slog.d(TAG_STACK,
9867                        "positionTaskInStack: positioning task=" + taskId
9868                        + " in stackId=" + stackId + " at position=" + position);
9869                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9870            } finally {
9871                Binder.restoreCallingIdentity(ident);
9872            }
9873        }
9874    }
9875
9876    @Override
9877    public List<StackInfo> getAllStackInfos() {
9878        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9879        long ident = Binder.clearCallingIdentity();
9880        try {
9881            synchronized (this) {
9882                return mStackSupervisor.getAllStackInfosLocked();
9883            }
9884        } finally {
9885            Binder.restoreCallingIdentity(ident);
9886        }
9887    }
9888
9889    @Override
9890    public StackInfo getStackInfo(int stackId) {
9891        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9892        long ident = Binder.clearCallingIdentity();
9893        try {
9894            synchronized (this) {
9895                return mStackSupervisor.getStackInfoLocked(stackId);
9896            }
9897        } finally {
9898            Binder.restoreCallingIdentity(ident);
9899        }
9900    }
9901
9902    @Override
9903    public boolean isInHomeStack(int taskId) {
9904        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9905        long ident = Binder.clearCallingIdentity();
9906        try {
9907            synchronized (this) {
9908                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9909                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9910                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9911            }
9912        } finally {
9913            Binder.restoreCallingIdentity(ident);
9914        }
9915    }
9916
9917    @Override
9918    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9919        synchronized(this) {
9920            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9921        }
9922    }
9923
9924    @Override
9925    public void updateDeviceOwner(String packageName) {
9926        final int callingUid = Binder.getCallingUid();
9927        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9928            throw new SecurityException("updateDeviceOwner called from non-system process");
9929        }
9930        synchronized (this) {
9931            mDeviceOwnerName = packageName;
9932        }
9933    }
9934
9935    @Override
9936    public void updateLockTaskPackages(int userId, String[] packages) {
9937        final int callingUid = Binder.getCallingUid();
9938        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9939            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9940                    "updateLockTaskPackages()");
9941        }
9942        synchronized (this) {
9943            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9944                    Arrays.toString(packages));
9945            mLockTaskPackages.put(userId, packages);
9946            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9947        }
9948    }
9949
9950
9951    void startLockTaskModeLocked(TaskRecord task) {
9952        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9953        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9954            return;
9955        }
9956
9957        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9958        // is initiated by system after the pinning request was shown and locked mode is initiated
9959        // by an authorized app directly
9960        final int callingUid = Binder.getCallingUid();
9961        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9962        long ident = Binder.clearCallingIdentity();
9963        try {
9964            if (!isSystemInitiated) {
9965                task.mLockTaskUid = callingUid;
9966                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9967                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9968                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9969                    StatusBarManagerInternal statusBarManager =
9970                            LocalServices.getService(StatusBarManagerInternal.class);
9971                    if (statusBarManager != null) {
9972                        statusBarManager.showScreenPinningRequest(task.taskId);
9973                    }
9974                    return;
9975                }
9976
9977                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9978                if (stack == null || task != stack.topTask()) {
9979                    throw new IllegalArgumentException("Invalid task, not in foreground");
9980                }
9981            }
9982            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9983                    "Locking fully");
9984            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9985                    ActivityManager.LOCK_TASK_MODE_PINNED :
9986                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9987                    "startLockTask", true);
9988        } finally {
9989            Binder.restoreCallingIdentity(ident);
9990        }
9991    }
9992
9993    @Override
9994    public void startLockTaskMode(int taskId) {
9995        synchronized (this) {
9996            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9997            if (task != null) {
9998                startLockTaskModeLocked(task);
9999            }
10000        }
10001    }
10002
10003    @Override
10004    public void startLockTaskMode(IBinder token) {
10005        synchronized (this) {
10006            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10007            if (r == null) {
10008                return;
10009            }
10010            final TaskRecord task = r.task;
10011            if (task != null) {
10012                startLockTaskModeLocked(task);
10013            }
10014        }
10015    }
10016
10017    @Override
10018    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10019        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10020        // This makes inner call to look as if it was initiated by system.
10021        long ident = Binder.clearCallingIdentity();
10022        try {
10023            synchronized (this) {
10024                startLockTaskMode(taskId);
10025            }
10026        } finally {
10027            Binder.restoreCallingIdentity(ident);
10028        }
10029    }
10030
10031    @Override
10032    public void stopLockTaskMode() {
10033        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10034        if (lockTask == null) {
10035            // Our work here is done.
10036            return;
10037        }
10038
10039        final int callingUid = Binder.getCallingUid();
10040        final int lockTaskUid = lockTask.mLockTaskUid;
10041        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10042        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10043            // Done.
10044            return;
10045        } else {
10046            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10047            // It is possible lockTaskMode was started by the system process because
10048            // android:lockTaskMode is set to a locking value in the application manifest
10049            // instead of the app calling startLockTaskMode. In this case
10050            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10051            // {@link TaskRecord.effectiveUid} instead. Also caller with
10052            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10053            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10054                    && callingUid != lockTaskUid
10055                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10056                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10057                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10058            }
10059        }
10060        long ident = Binder.clearCallingIdentity();
10061        try {
10062            Log.d(TAG, "stopLockTaskMode");
10063            // Stop lock task
10064            synchronized (this) {
10065                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10066                        "stopLockTask", true);
10067            }
10068        } finally {
10069            Binder.restoreCallingIdentity(ident);
10070        }
10071    }
10072
10073    /**
10074     * This API should be called by SystemUI only when user perform certain action to dismiss
10075     * lock task mode. We should only dismiss pinned lock task mode in this case.
10076     */
10077    @Override
10078    public void stopSystemLockTaskMode() throws RemoteException {
10079        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10080            stopLockTaskMode();
10081        } else {
10082            mStackSupervisor.showLockTaskToast();
10083        }
10084    }
10085
10086    @Override
10087    public boolean isInLockTaskMode() {
10088        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10089    }
10090
10091    @Override
10092    public int getLockTaskModeState() {
10093        synchronized (this) {
10094            return mStackSupervisor.getLockTaskModeState();
10095        }
10096    }
10097
10098    @Override
10099    public void showLockTaskEscapeMessage(IBinder token) {
10100        synchronized (this) {
10101            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10102            if (r == null) {
10103                return;
10104            }
10105            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10106        }
10107    }
10108
10109    // =========================================================
10110    // CONTENT PROVIDERS
10111    // =========================================================
10112
10113    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10114        List<ProviderInfo> providers = null;
10115        try {
10116            providers = AppGlobals.getPackageManager()
10117                    .queryContentProviders(app.processName, app.uid,
10118                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10119                                    | MATCH_DEBUG_TRIAGED_MISSING)
10120                    .getList();
10121        } catch (RemoteException ex) {
10122        }
10123        if (DEBUG_MU) Slog.v(TAG_MU,
10124                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10125        int userId = app.userId;
10126        if (providers != null) {
10127            int N = providers.size();
10128            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10129            for (int i=0; i<N; i++) {
10130                ProviderInfo cpi =
10131                    (ProviderInfo)providers.get(i);
10132                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10133                        cpi.name, cpi.flags);
10134                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10135                    // This is a singleton provider, but a user besides the
10136                    // default user is asking to initialize a process it runs
10137                    // in...  well, no, it doesn't actually run in this process,
10138                    // it runs in the process of the default user.  Get rid of it.
10139                    providers.remove(i);
10140                    N--;
10141                    i--;
10142                    continue;
10143                }
10144
10145                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10146                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10147                if (cpr == null) {
10148                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10149                    mProviderMap.putProviderByClass(comp, cpr);
10150                }
10151                if (DEBUG_MU) Slog.v(TAG_MU,
10152                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10153                app.pubProviders.put(cpi.name, cpr);
10154                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10155                    // Don't add this if it is a platform component that is marked
10156                    // to run in multiple processes, because this is actually
10157                    // part of the framework so doesn't make sense to track as a
10158                    // separate apk in the process.
10159                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10160                            mProcessStats);
10161                }
10162                notifyPackageUse(cpi.applicationInfo.packageName,
10163                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10164            }
10165        }
10166        return providers;
10167    }
10168
10169    /**
10170     * Check if {@link ProcessRecord} has a possible chance at accessing the
10171     * given {@link ProviderInfo}. Final permission checking is always done
10172     * in {@link ContentProvider}.
10173     */
10174    private final String checkContentProviderPermissionLocked(
10175            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10176        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10177        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10178        boolean checkedGrants = false;
10179        if (checkUser) {
10180            // Looking for cross-user grants before enforcing the typical cross-users permissions
10181            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10182            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10183                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10184                    return null;
10185                }
10186                checkedGrants = true;
10187            }
10188            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10189                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10190            if (userId != tmpTargetUserId) {
10191                // When we actually went to determine the final targer user ID, this ended
10192                // up different than our initial check for the authority.  This is because
10193                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10194                // SELF.  So we need to re-check the grants again.
10195                checkedGrants = false;
10196            }
10197        }
10198        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10199                cpi.applicationInfo.uid, cpi.exported)
10200                == PackageManager.PERMISSION_GRANTED) {
10201            return null;
10202        }
10203        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10204                cpi.applicationInfo.uid, cpi.exported)
10205                == PackageManager.PERMISSION_GRANTED) {
10206            return null;
10207        }
10208
10209        PathPermission[] pps = cpi.pathPermissions;
10210        if (pps != null) {
10211            int i = pps.length;
10212            while (i > 0) {
10213                i--;
10214                PathPermission pp = pps[i];
10215                String pprperm = pp.getReadPermission();
10216                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10217                        cpi.applicationInfo.uid, cpi.exported)
10218                        == PackageManager.PERMISSION_GRANTED) {
10219                    return null;
10220                }
10221                String ppwperm = pp.getWritePermission();
10222                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10223                        cpi.applicationInfo.uid, cpi.exported)
10224                        == PackageManager.PERMISSION_GRANTED) {
10225                    return null;
10226                }
10227            }
10228        }
10229        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10230            return null;
10231        }
10232
10233        String msg;
10234        if (!cpi.exported) {
10235            msg = "Permission Denial: opening provider " + cpi.name
10236                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10237                    + ", uid=" + callingUid + ") that is not exported from uid "
10238                    + cpi.applicationInfo.uid;
10239        } else {
10240            msg = "Permission Denial: opening provider " + cpi.name
10241                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10242                    + ", uid=" + callingUid + ") requires "
10243                    + cpi.readPermission + " or " + cpi.writePermission;
10244        }
10245        Slog.w(TAG, msg);
10246        return msg;
10247    }
10248
10249    /**
10250     * Returns if the ContentProvider has granted a uri to callingUid
10251     */
10252    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10253        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10254        if (perms != null) {
10255            for (int i=perms.size()-1; i>=0; i--) {
10256                GrantUri grantUri = perms.keyAt(i);
10257                if (grantUri.sourceUserId == userId || !checkUser) {
10258                    if (matchesProvider(grantUri.uri, cpi)) {
10259                        return true;
10260                    }
10261                }
10262            }
10263        }
10264        return false;
10265    }
10266
10267    /**
10268     * Returns true if the uri authority is one of the authorities specified in the provider.
10269     */
10270    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10271        String uriAuth = uri.getAuthority();
10272        String cpiAuth = cpi.authority;
10273        if (cpiAuth.indexOf(';') == -1) {
10274            return cpiAuth.equals(uriAuth);
10275        }
10276        String[] cpiAuths = cpiAuth.split(";");
10277        int length = cpiAuths.length;
10278        for (int i = 0; i < length; i++) {
10279            if (cpiAuths[i].equals(uriAuth)) return true;
10280        }
10281        return false;
10282    }
10283
10284    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10285            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10286        if (r != null) {
10287            for (int i=0; i<r.conProviders.size(); i++) {
10288                ContentProviderConnection conn = r.conProviders.get(i);
10289                if (conn.provider == cpr) {
10290                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10291                            "Adding provider requested by "
10292                            + r.processName + " from process "
10293                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10294                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10295                    if (stable) {
10296                        conn.stableCount++;
10297                        conn.numStableIncs++;
10298                    } else {
10299                        conn.unstableCount++;
10300                        conn.numUnstableIncs++;
10301                    }
10302                    return conn;
10303                }
10304            }
10305            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10306            if (stable) {
10307                conn.stableCount = 1;
10308                conn.numStableIncs = 1;
10309            } else {
10310                conn.unstableCount = 1;
10311                conn.numUnstableIncs = 1;
10312            }
10313            cpr.connections.add(conn);
10314            r.conProviders.add(conn);
10315            startAssociationLocked(r.uid, r.processName, r.curProcState,
10316                    cpr.uid, cpr.name, cpr.info.processName);
10317            return conn;
10318        }
10319        cpr.addExternalProcessHandleLocked(externalProcessToken);
10320        return null;
10321    }
10322
10323    boolean decProviderCountLocked(ContentProviderConnection conn,
10324            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10325        if (conn != null) {
10326            cpr = conn.provider;
10327            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10328                    "Removing provider requested by "
10329                    + conn.client.processName + " from process "
10330                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10331                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10332            if (stable) {
10333                conn.stableCount--;
10334            } else {
10335                conn.unstableCount--;
10336            }
10337            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10338                cpr.connections.remove(conn);
10339                conn.client.conProviders.remove(conn);
10340                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10341                    // The client is more important than last activity -- note the time this
10342                    // is happening, so we keep the old provider process around a bit as last
10343                    // activity to avoid thrashing it.
10344                    if (cpr.proc != null) {
10345                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10346                    }
10347                }
10348                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10349                return true;
10350            }
10351            return false;
10352        }
10353        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10354        return false;
10355    }
10356
10357    private void checkTime(long startTime, String where) {
10358        long now = SystemClock.uptimeMillis();
10359        if ((now-startTime) > 50) {
10360            // If we are taking more than 50ms, log about it.
10361            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10362        }
10363    }
10364
10365    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10366            String name, IBinder token, boolean stable, int userId) {
10367        ContentProviderRecord cpr;
10368        ContentProviderConnection conn = null;
10369        ProviderInfo cpi = null;
10370
10371        synchronized(this) {
10372            long startTime = SystemClock.uptimeMillis();
10373
10374            ProcessRecord r = null;
10375            if (caller != null) {
10376                r = getRecordForAppLocked(caller);
10377                if (r == null) {
10378                    throw new SecurityException(
10379                            "Unable to find app for caller " + caller
10380                          + " (pid=" + Binder.getCallingPid()
10381                          + ") when getting content provider " + name);
10382                }
10383            }
10384
10385            boolean checkCrossUser = true;
10386
10387            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10388
10389            // First check if this content provider has been published...
10390            cpr = mProviderMap.getProviderByName(name, userId);
10391            // If that didn't work, check if it exists for user 0 and then
10392            // verify that it's a singleton provider before using it.
10393            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10394                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10395                if (cpr != null) {
10396                    cpi = cpr.info;
10397                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10398                            cpi.name, cpi.flags)
10399                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10400                        userId = UserHandle.USER_SYSTEM;
10401                        checkCrossUser = false;
10402                    } else {
10403                        cpr = null;
10404                        cpi = null;
10405                    }
10406                }
10407            }
10408
10409            boolean providerRunning = cpr != null;
10410            if (providerRunning) {
10411                cpi = cpr.info;
10412                String msg;
10413                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10414                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10415                        != null) {
10416                    throw new SecurityException(msg);
10417                }
10418                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10419
10420                if (r != null && cpr.canRunHere(r)) {
10421                    // This provider has been published or is in the process
10422                    // of being published...  but it is also allowed to run
10423                    // in the caller's process, so don't make a connection
10424                    // and just let the caller instantiate its own instance.
10425                    ContentProviderHolder holder = cpr.newHolder(null);
10426                    // don't give caller the provider object, it needs
10427                    // to make its own.
10428                    holder.provider = null;
10429                    return holder;
10430                }
10431
10432                final long origId = Binder.clearCallingIdentity();
10433
10434                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10435
10436                // In this case the provider instance already exists, so we can
10437                // return it right away.
10438                conn = incProviderCountLocked(r, cpr, token, stable);
10439                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10440                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10441                        // If this is a perceptible app accessing the provider,
10442                        // make sure to count it as being accessed and thus
10443                        // back up on the LRU list.  This is good because
10444                        // content providers are often expensive to start.
10445                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10446                        updateLruProcessLocked(cpr.proc, false, null);
10447                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10448                    }
10449                }
10450
10451                if (cpr.proc != null) {
10452                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10453                    boolean success = updateOomAdjLocked(cpr.proc);
10454                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10455                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10456                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10457                    // NOTE: there is still a race here where a signal could be
10458                    // pending on the process even though we managed to update its
10459                    // adj level.  Not sure what to do about this, but at least
10460                    // the race is now smaller.
10461                    if (!success) {
10462                        // Uh oh...  it looks like the provider's process
10463                        // has been killed on us.  We need to wait for a new
10464                        // process to be started, and make sure its death
10465                        // doesn't kill our process.
10466                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10467                                + " is crashing; detaching " + r);
10468                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10469                        checkTime(startTime, "getContentProviderImpl: before appDied");
10470                        appDiedLocked(cpr.proc);
10471                        checkTime(startTime, "getContentProviderImpl: after appDied");
10472                        if (!lastRef) {
10473                            // This wasn't the last ref our process had on
10474                            // the provider...  we have now been killed, bail.
10475                            return null;
10476                        }
10477                        providerRunning = false;
10478                        conn = null;
10479                    }
10480                }
10481
10482                Binder.restoreCallingIdentity(origId);
10483            }
10484
10485            if (!providerRunning) {
10486                try {
10487                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10488                    cpi = AppGlobals.getPackageManager().
10489                        resolveContentProvider(name,
10490                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10491                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10492                } catch (RemoteException ex) {
10493                }
10494                if (cpi == null) {
10495                    return null;
10496                }
10497                // If the provider is a singleton AND
10498                // (it's a call within the same user || the provider is a
10499                // privileged app)
10500                // Then allow connecting to the singleton provider
10501                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10502                        cpi.name, cpi.flags)
10503                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10504                if (singleton) {
10505                    userId = UserHandle.USER_SYSTEM;
10506                }
10507                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10508                checkTime(startTime, "getContentProviderImpl: got app info for user");
10509
10510                String msg;
10511                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10512                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10513                        != null) {
10514                    throw new SecurityException(msg);
10515                }
10516                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10517
10518                if (!mProcessesReady
10519                        && !cpi.processName.equals("system")) {
10520                    // If this content provider does not run in the system
10521                    // process, and the system is not yet ready to run other
10522                    // processes, then fail fast instead of hanging.
10523                    throw new IllegalArgumentException(
10524                            "Attempt to launch content provider before system ready");
10525                }
10526
10527                // Make sure that the user who owns this provider is running.  If not,
10528                // we don't want to allow it to run.
10529                if (!mUserController.isUserRunningLocked(userId, 0)) {
10530                    Slog.w(TAG, "Unable to launch app "
10531                            + cpi.applicationInfo.packageName + "/"
10532                            + cpi.applicationInfo.uid + " for provider "
10533                            + name + ": user " + userId + " is stopped");
10534                    return null;
10535                }
10536
10537                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10538                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10539                cpr = mProviderMap.getProviderByClass(comp, userId);
10540                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10541                final boolean firstClass = cpr == null;
10542                if (firstClass) {
10543                    final long ident = Binder.clearCallingIdentity();
10544
10545                    // If permissions need a review before any of the app components can run,
10546                    // we return no provider and launch a review activity if the calling app
10547                    // is in the foreground.
10548                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10549                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10550                            return null;
10551                        }
10552                    }
10553
10554                    try {
10555                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10556                        ApplicationInfo ai =
10557                            AppGlobals.getPackageManager().
10558                                getApplicationInfo(
10559                                        cpi.applicationInfo.packageName,
10560                                        STOCK_PM_FLAGS, userId);
10561                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10562                        if (ai == null) {
10563                            Slog.w(TAG, "No package info for content provider "
10564                                    + cpi.name);
10565                            return null;
10566                        }
10567                        ai = getAppInfoForUser(ai, userId);
10568                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10569                    } catch (RemoteException ex) {
10570                        // pm is in same process, this will never happen.
10571                    } finally {
10572                        Binder.restoreCallingIdentity(ident);
10573                    }
10574                }
10575
10576                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10577
10578                if (r != null && cpr.canRunHere(r)) {
10579                    // If this is a multiprocess provider, then just return its
10580                    // info and allow the caller to instantiate it.  Only do
10581                    // this if the provider is the same user as the caller's
10582                    // process, or can run as root (so can be in any process).
10583                    return cpr.newHolder(null);
10584                }
10585
10586                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10587                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10588                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10589
10590                // This is single process, and our app is now connecting to it.
10591                // See if we are already in the process of launching this
10592                // provider.
10593                final int N = mLaunchingProviders.size();
10594                int i;
10595                for (i = 0; i < N; i++) {
10596                    if (mLaunchingProviders.get(i) == cpr) {
10597                        break;
10598                    }
10599                }
10600
10601                // If the provider is not already being launched, then get it
10602                // started.
10603                if (i >= N) {
10604                    final long origId = Binder.clearCallingIdentity();
10605
10606                    try {
10607                        // Content provider is now in use, its package can't be stopped.
10608                        try {
10609                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10610                            AppGlobals.getPackageManager().setPackageStoppedState(
10611                                    cpr.appInfo.packageName, false, userId);
10612                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10613                        } catch (RemoteException e) {
10614                        } catch (IllegalArgumentException e) {
10615                            Slog.w(TAG, "Failed trying to unstop package "
10616                                    + cpr.appInfo.packageName + ": " + e);
10617                        }
10618
10619                        // Use existing process if already started
10620                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10621                        ProcessRecord proc = getProcessRecordLocked(
10622                                cpi.processName, cpr.appInfo.uid, false);
10623                        if (proc != null && proc.thread != null) {
10624                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10625                                    "Installing in existing process " + proc);
10626                            if (!proc.pubProviders.containsKey(cpi.name)) {
10627                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10628                                proc.pubProviders.put(cpi.name, cpr);
10629                                try {
10630                                    proc.thread.scheduleInstallProvider(cpi);
10631                                } catch (RemoteException e) {
10632                                }
10633                            }
10634                        } else {
10635                            checkTime(startTime, "getContentProviderImpl: before start process");
10636                            proc = startProcessLocked(cpi.processName,
10637                                    cpr.appInfo, false, 0, "content provider",
10638                                    new ComponentName(cpi.applicationInfo.packageName,
10639                                            cpi.name), false, false, false);
10640                            checkTime(startTime, "getContentProviderImpl: after start process");
10641                            if (proc == null) {
10642                                Slog.w(TAG, "Unable to launch app "
10643                                        + cpi.applicationInfo.packageName + "/"
10644                                        + cpi.applicationInfo.uid + " for provider "
10645                                        + name + ": process is bad");
10646                                return null;
10647                            }
10648                        }
10649                        cpr.launchingApp = proc;
10650                        mLaunchingProviders.add(cpr);
10651                    } finally {
10652                        Binder.restoreCallingIdentity(origId);
10653                    }
10654                }
10655
10656                checkTime(startTime, "getContentProviderImpl: updating data structures");
10657
10658                // Make sure the provider is published (the same provider class
10659                // may be published under multiple names).
10660                if (firstClass) {
10661                    mProviderMap.putProviderByClass(comp, cpr);
10662                }
10663
10664                mProviderMap.putProviderByName(name, cpr);
10665                conn = incProviderCountLocked(r, cpr, token, stable);
10666                if (conn != null) {
10667                    conn.waiting = true;
10668                }
10669            }
10670            checkTime(startTime, "getContentProviderImpl: done!");
10671        }
10672
10673        // Wait for the provider to be published...
10674        synchronized (cpr) {
10675            while (cpr.provider == null) {
10676                if (cpr.launchingApp == null) {
10677                    Slog.w(TAG, "Unable to launch app "
10678                            + cpi.applicationInfo.packageName + "/"
10679                            + cpi.applicationInfo.uid + " for provider "
10680                            + name + ": launching app became null");
10681                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10682                            UserHandle.getUserId(cpi.applicationInfo.uid),
10683                            cpi.applicationInfo.packageName,
10684                            cpi.applicationInfo.uid, name);
10685                    return null;
10686                }
10687                try {
10688                    if (DEBUG_MU) Slog.v(TAG_MU,
10689                            "Waiting to start provider " + cpr
10690                            + " launchingApp=" + cpr.launchingApp);
10691                    if (conn != null) {
10692                        conn.waiting = true;
10693                    }
10694                    cpr.wait();
10695                } catch (InterruptedException ex) {
10696                } finally {
10697                    if (conn != null) {
10698                        conn.waiting = false;
10699                    }
10700                }
10701            }
10702        }
10703        return cpr != null ? cpr.newHolder(conn) : null;
10704    }
10705
10706    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10707            ProcessRecord r, final int userId) {
10708        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10709                cpi.packageName, userId)) {
10710
10711            final boolean callerForeground = r == null || r.setSchedGroup
10712                    != ProcessList.SCHED_GROUP_BACKGROUND;
10713
10714            // Show a permission review UI only for starting from a foreground app
10715            if (!callerForeground) {
10716                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10717                        + cpi.packageName + " requires a permissions review");
10718                return false;
10719            }
10720
10721            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10722            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10723                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10724            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10725
10726            if (DEBUG_PERMISSIONS_REVIEW) {
10727                Slog.i(TAG, "u" + userId + " Launching permission review "
10728                        + "for package " + cpi.packageName);
10729            }
10730
10731            final UserHandle userHandle = new UserHandle(userId);
10732            mHandler.post(new Runnable() {
10733                @Override
10734                public void run() {
10735                    mContext.startActivityAsUser(intent, userHandle);
10736                }
10737            });
10738
10739            return false;
10740        }
10741
10742        return true;
10743    }
10744
10745    PackageManagerInternal getPackageManagerInternalLocked() {
10746        if (mPackageManagerInt == null) {
10747            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10748        }
10749        return mPackageManagerInt;
10750    }
10751
10752    @Override
10753    public final ContentProviderHolder getContentProvider(
10754            IApplicationThread caller, String name, int userId, boolean stable) {
10755        enforceNotIsolatedCaller("getContentProvider");
10756        if (caller == null) {
10757            String msg = "null IApplicationThread when getting content provider "
10758                    + name;
10759            Slog.w(TAG, msg);
10760            throw new SecurityException(msg);
10761        }
10762        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10763        // with cross-user grant.
10764        return getContentProviderImpl(caller, name, null, stable, userId);
10765    }
10766
10767    public ContentProviderHolder getContentProviderExternal(
10768            String name, int userId, IBinder token) {
10769        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10770            "Do not have permission in call getContentProviderExternal()");
10771        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10772                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10773        return getContentProviderExternalUnchecked(name, token, userId);
10774    }
10775
10776    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10777            IBinder token, int userId) {
10778        return getContentProviderImpl(null, name, token, true, userId);
10779    }
10780
10781    /**
10782     * Drop a content provider from a ProcessRecord's bookkeeping
10783     */
10784    public void removeContentProvider(IBinder connection, boolean stable) {
10785        enforceNotIsolatedCaller("removeContentProvider");
10786        long ident = Binder.clearCallingIdentity();
10787        try {
10788            synchronized (this) {
10789                ContentProviderConnection conn;
10790                try {
10791                    conn = (ContentProviderConnection)connection;
10792                } catch (ClassCastException e) {
10793                    String msg ="removeContentProvider: " + connection
10794                            + " not a ContentProviderConnection";
10795                    Slog.w(TAG, msg);
10796                    throw new IllegalArgumentException(msg);
10797                }
10798                if (conn == null) {
10799                    throw new NullPointerException("connection is null");
10800                }
10801                if (decProviderCountLocked(conn, null, null, stable)) {
10802                    updateOomAdjLocked();
10803                }
10804            }
10805        } finally {
10806            Binder.restoreCallingIdentity(ident);
10807        }
10808    }
10809
10810    public void removeContentProviderExternal(String name, IBinder token) {
10811        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10812            "Do not have permission in call removeContentProviderExternal()");
10813        int userId = UserHandle.getCallingUserId();
10814        long ident = Binder.clearCallingIdentity();
10815        try {
10816            removeContentProviderExternalUnchecked(name, token, userId);
10817        } finally {
10818            Binder.restoreCallingIdentity(ident);
10819        }
10820    }
10821
10822    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10823        synchronized (this) {
10824            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10825            if(cpr == null) {
10826                //remove from mProvidersByClass
10827                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10828                return;
10829            }
10830
10831            //update content provider record entry info
10832            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10833            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10834            if (localCpr.hasExternalProcessHandles()) {
10835                if (localCpr.removeExternalProcessHandleLocked(token)) {
10836                    updateOomAdjLocked();
10837                } else {
10838                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10839                            + " with no external reference for token: "
10840                            + token + ".");
10841                }
10842            } else {
10843                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10844                        + " with no external references.");
10845            }
10846        }
10847    }
10848
10849    public final void publishContentProviders(IApplicationThread caller,
10850            List<ContentProviderHolder> providers) {
10851        if (providers == null) {
10852            return;
10853        }
10854
10855        enforceNotIsolatedCaller("publishContentProviders");
10856        synchronized (this) {
10857            final ProcessRecord r = getRecordForAppLocked(caller);
10858            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10859            if (r == null) {
10860                throw new SecurityException(
10861                        "Unable to find app for caller " + caller
10862                      + " (pid=" + Binder.getCallingPid()
10863                      + ") when publishing content providers");
10864            }
10865
10866            final long origId = Binder.clearCallingIdentity();
10867
10868            final int N = providers.size();
10869            for (int i = 0; i < N; i++) {
10870                ContentProviderHolder src = providers.get(i);
10871                if (src == null || src.info == null || src.provider == null) {
10872                    continue;
10873                }
10874                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10875                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10876                if (dst != null) {
10877                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10878                    mProviderMap.putProviderByClass(comp, dst);
10879                    String names[] = dst.info.authority.split(";");
10880                    for (int j = 0; j < names.length; j++) {
10881                        mProviderMap.putProviderByName(names[j], dst);
10882                    }
10883
10884                    int launchingCount = mLaunchingProviders.size();
10885                    int j;
10886                    boolean wasInLaunchingProviders = false;
10887                    for (j = 0; j < launchingCount; j++) {
10888                        if (mLaunchingProviders.get(j) == dst) {
10889                            mLaunchingProviders.remove(j);
10890                            wasInLaunchingProviders = true;
10891                            j--;
10892                            launchingCount--;
10893                        }
10894                    }
10895                    if (wasInLaunchingProviders) {
10896                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10897                    }
10898                    synchronized (dst) {
10899                        dst.provider = src.provider;
10900                        dst.proc = r;
10901                        dst.notifyAll();
10902                    }
10903                    updateOomAdjLocked(r);
10904                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10905                            src.info.authority);
10906                }
10907            }
10908
10909            Binder.restoreCallingIdentity(origId);
10910        }
10911    }
10912
10913    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10914        ContentProviderConnection conn;
10915        try {
10916            conn = (ContentProviderConnection)connection;
10917        } catch (ClassCastException e) {
10918            String msg ="refContentProvider: " + connection
10919                    + " not a ContentProviderConnection";
10920            Slog.w(TAG, msg);
10921            throw new IllegalArgumentException(msg);
10922        }
10923        if (conn == null) {
10924            throw new NullPointerException("connection is null");
10925        }
10926
10927        synchronized (this) {
10928            if (stable > 0) {
10929                conn.numStableIncs += stable;
10930            }
10931            stable = conn.stableCount + stable;
10932            if (stable < 0) {
10933                throw new IllegalStateException("stableCount < 0: " + stable);
10934            }
10935
10936            if (unstable > 0) {
10937                conn.numUnstableIncs += unstable;
10938            }
10939            unstable = conn.unstableCount + unstable;
10940            if (unstable < 0) {
10941                throw new IllegalStateException("unstableCount < 0: " + unstable);
10942            }
10943
10944            if ((stable+unstable) <= 0) {
10945                throw new IllegalStateException("ref counts can't go to zero here: stable="
10946                        + stable + " unstable=" + unstable);
10947            }
10948            conn.stableCount = stable;
10949            conn.unstableCount = unstable;
10950            return !conn.dead;
10951        }
10952    }
10953
10954    public void unstableProviderDied(IBinder connection) {
10955        ContentProviderConnection conn;
10956        try {
10957            conn = (ContentProviderConnection)connection;
10958        } catch (ClassCastException e) {
10959            String msg ="refContentProvider: " + connection
10960                    + " not a ContentProviderConnection";
10961            Slog.w(TAG, msg);
10962            throw new IllegalArgumentException(msg);
10963        }
10964        if (conn == null) {
10965            throw new NullPointerException("connection is null");
10966        }
10967
10968        // Safely retrieve the content provider associated with the connection.
10969        IContentProvider provider;
10970        synchronized (this) {
10971            provider = conn.provider.provider;
10972        }
10973
10974        if (provider == null) {
10975            // Um, yeah, we're way ahead of you.
10976            return;
10977        }
10978
10979        // Make sure the caller is being honest with us.
10980        if (provider.asBinder().pingBinder()) {
10981            // Er, no, still looks good to us.
10982            synchronized (this) {
10983                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10984                        + " says " + conn + " died, but we don't agree");
10985                return;
10986            }
10987        }
10988
10989        // Well look at that!  It's dead!
10990        synchronized (this) {
10991            if (conn.provider.provider != provider) {
10992                // But something changed...  good enough.
10993                return;
10994            }
10995
10996            ProcessRecord proc = conn.provider.proc;
10997            if (proc == null || proc.thread == null) {
10998                // Seems like the process is already cleaned up.
10999                return;
11000            }
11001
11002            // As far as we're concerned, this is just like receiving a
11003            // death notification...  just a bit prematurely.
11004            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11005                    + ") early provider death");
11006            final long ident = Binder.clearCallingIdentity();
11007            try {
11008                appDiedLocked(proc);
11009            } finally {
11010                Binder.restoreCallingIdentity(ident);
11011            }
11012        }
11013    }
11014
11015    @Override
11016    public void appNotRespondingViaProvider(IBinder connection) {
11017        enforceCallingPermission(
11018                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11019
11020        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11021        if (conn == null) {
11022            Slog.w(TAG, "ContentProviderConnection is null");
11023            return;
11024        }
11025
11026        final ProcessRecord host = conn.provider.proc;
11027        if (host == null) {
11028            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11029            return;
11030        }
11031
11032        mHandler.post(new Runnable() {
11033            @Override
11034            public void run() {
11035                mAppErrors.appNotResponding(host, null, null, false,
11036                        "ContentProvider not responding");
11037            }
11038        });
11039    }
11040
11041    public final void installSystemProviders() {
11042        List<ProviderInfo> providers;
11043        synchronized (this) {
11044            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11045            providers = generateApplicationProvidersLocked(app);
11046            if (providers != null) {
11047                for (int i=providers.size()-1; i>=0; i--) {
11048                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11049                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11050                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11051                                + ": not system .apk");
11052                        providers.remove(i);
11053                    }
11054                }
11055            }
11056        }
11057        if (providers != null) {
11058            mSystemThread.installSystemProviders(providers);
11059        }
11060
11061        mCoreSettingsObserver = new CoreSettingsObserver(this);
11062        mFontScaleSettingObserver = new FontScaleSettingObserver();
11063
11064        //mUsageStatsService.monitorPackages();
11065    }
11066
11067    private void startPersistentApps(int matchFlags) {
11068        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11069
11070        synchronized (this) {
11071            try {
11072                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11073                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11074                for (ApplicationInfo app : apps) {
11075                    if (!"android".equals(app.packageName)) {
11076                        addAppLocked(app, false, null /* ABI override */);
11077                    }
11078                }
11079            } catch (RemoteException ex) {
11080            }
11081        }
11082    }
11083
11084    /**
11085     * When a user is unlocked, we need to install encryption-unaware providers
11086     * belonging to any running apps.
11087     */
11088    private void installEncryptionUnawareProviders(int userId) {
11089        // We're only interested in providers that are encryption unaware, and
11090        // we don't care about uninstalled apps, since there's no way they're
11091        // running at this point.
11092        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11093
11094        synchronized (this) {
11095            final int NP = mProcessNames.getMap().size();
11096            for (int ip = 0; ip < NP; ip++) {
11097                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11098                final int NA = apps.size();
11099                for (int ia = 0; ia < NA; ia++) {
11100                    final ProcessRecord app = apps.valueAt(ia);
11101                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11102
11103                    final int NG = app.pkgList.size();
11104                    for (int ig = 0; ig < NG; ig++) {
11105                        try {
11106                            final String pkgName = app.pkgList.keyAt(ig);
11107                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11108                                    .getPackageInfo(pkgName, matchFlags, userId);
11109                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11110                                for (ProviderInfo provInfo : pkgInfo.providers) {
11111                                    Log.v(TAG, "Installing " + provInfo);
11112                                    app.thread.scheduleInstallProvider(provInfo);
11113                                }
11114                            }
11115                        } catch (RemoteException ignored) {
11116                        }
11117                    }
11118                }
11119            }
11120        }
11121    }
11122
11123    /**
11124     * Allows apps to retrieve the MIME type of a URI.
11125     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11126     * users, then it does not need permission to access the ContentProvider.
11127     * Either, it needs cross-user uri grants.
11128     *
11129     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11130     *
11131     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11132     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11133     */
11134    public String getProviderMimeType(Uri uri, int userId) {
11135        enforceNotIsolatedCaller("getProviderMimeType");
11136        final String name = uri.getAuthority();
11137        int callingUid = Binder.getCallingUid();
11138        int callingPid = Binder.getCallingPid();
11139        long ident = 0;
11140        boolean clearedIdentity = false;
11141        synchronized (this) {
11142            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11143        }
11144        if (canClearIdentity(callingPid, callingUid, userId)) {
11145            clearedIdentity = true;
11146            ident = Binder.clearCallingIdentity();
11147        }
11148        ContentProviderHolder holder = null;
11149        try {
11150            holder = getContentProviderExternalUnchecked(name, null, userId);
11151            if (holder != null) {
11152                return holder.provider.getType(uri);
11153            }
11154        } catch (RemoteException e) {
11155            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11156            return null;
11157        } finally {
11158            // We need to clear the identity to call removeContentProviderExternalUnchecked
11159            if (!clearedIdentity) {
11160                ident = Binder.clearCallingIdentity();
11161            }
11162            try {
11163                if (holder != null) {
11164                    removeContentProviderExternalUnchecked(name, null, userId);
11165                }
11166            } finally {
11167                Binder.restoreCallingIdentity(ident);
11168            }
11169        }
11170
11171        return null;
11172    }
11173
11174    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11175        if (UserHandle.getUserId(callingUid) == userId) {
11176            return true;
11177        }
11178        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11179                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11180                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11181                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11182                return true;
11183        }
11184        return false;
11185    }
11186
11187    // =========================================================
11188    // GLOBAL MANAGEMENT
11189    // =========================================================
11190
11191    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11192            boolean isolated, int isolatedUid) {
11193        String proc = customProcess != null ? customProcess : info.processName;
11194        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11195        final int userId = UserHandle.getUserId(info.uid);
11196        int uid = info.uid;
11197        if (isolated) {
11198            if (isolatedUid == 0) {
11199                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11200                while (true) {
11201                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11202                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11203                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11204                    }
11205                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11206                    mNextIsolatedProcessUid++;
11207                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11208                        // No process for this uid, use it.
11209                        break;
11210                    }
11211                    stepsLeft--;
11212                    if (stepsLeft <= 0) {
11213                        return null;
11214                    }
11215                }
11216            } else {
11217                // Special case for startIsolatedProcess (internal only), where
11218                // the uid of the isolated process is specified by the caller.
11219                uid = isolatedUid;
11220            }
11221        }
11222        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11223        if (!mBooted && !mBooting
11224                && userId == UserHandle.USER_SYSTEM
11225                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11226            r.persistent = true;
11227        }
11228        addProcessNameLocked(r);
11229        return r;
11230    }
11231
11232    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11233            String abiOverride) {
11234        ProcessRecord app;
11235        if (!isolated) {
11236            app = getProcessRecordLocked(info.processName, info.uid, true);
11237        } else {
11238            app = null;
11239        }
11240
11241        if (app == null) {
11242            app = newProcessRecordLocked(info, null, isolated, 0);
11243            updateLruProcessLocked(app, false, null);
11244            updateOomAdjLocked();
11245        }
11246
11247        // This package really, really can not be stopped.
11248        try {
11249            AppGlobals.getPackageManager().setPackageStoppedState(
11250                    info.packageName, false, UserHandle.getUserId(app.uid));
11251        } catch (RemoteException e) {
11252        } catch (IllegalArgumentException e) {
11253            Slog.w(TAG, "Failed trying to unstop package "
11254                    + info.packageName + ": " + e);
11255        }
11256
11257        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11258            app.persistent = true;
11259            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11260        }
11261        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11262            mPersistentStartingProcesses.add(app);
11263            startProcessLocked(app, "added application", app.processName, abiOverride,
11264                    null /* entryPoint */, null /* entryPointArgs */);
11265        }
11266
11267        return app;
11268    }
11269
11270    public void unhandledBack() {
11271        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11272                "unhandledBack()");
11273
11274        synchronized(this) {
11275            final long origId = Binder.clearCallingIdentity();
11276            try {
11277                getFocusedStack().unhandledBackLocked();
11278            } finally {
11279                Binder.restoreCallingIdentity(origId);
11280            }
11281        }
11282    }
11283
11284    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11285        enforceNotIsolatedCaller("openContentUri");
11286        final int userId = UserHandle.getCallingUserId();
11287        String name = uri.getAuthority();
11288        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11289        ParcelFileDescriptor pfd = null;
11290        if (cph != null) {
11291            // We record the binder invoker's uid in thread-local storage before
11292            // going to the content provider to open the file.  Later, in the code
11293            // that handles all permissions checks, we look for this uid and use
11294            // that rather than the Activity Manager's own uid.  The effect is that
11295            // we do the check against the caller's permissions even though it looks
11296            // to the content provider like the Activity Manager itself is making
11297            // the request.
11298            Binder token = new Binder();
11299            sCallerIdentity.set(new Identity(
11300                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11301            try {
11302                pfd = cph.provider.openFile(null, uri, "r", null, token);
11303            } catch (FileNotFoundException e) {
11304                // do nothing; pfd will be returned null
11305            } finally {
11306                // Ensure that whatever happens, we clean up the identity state
11307                sCallerIdentity.remove();
11308                // Ensure we're done with the provider.
11309                removeContentProviderExternalUnchecked(name, null, userId);
11310            }
11311        } else {
11312            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11313        }
11314        return pfd;
11315    }
11316
11317    // Actually is sleeping or shutting down or whatever else in the future
11318    // is an inactive state.
11319    public boolean isSleepingOrShuttingDown() {
11320        return isSleeping() || mShuttingDown;
11321    }
11322
11323    public boolean isSleeping() {
11324        return mSleeping;
11325    }
11326
11327    void onWakefulnessChanged(int wakefulness) {
11328        synchronized(this) {
11329            mWakefulness = wakefulness;
11330            updateSleepIfNeededLocked();
11331        }
11332    }
11333
11334    void finishRunningVoiceLocked() {
11335        if (mRunningVoice != null) {
11336            mRunningVoice = null;
11337            mVoiceWakeLock.release();
11338            updateSleepIfNeededLocked();
11339        }
11340    }
11341
11342    void startTimeTrackingFocusedActivityLocked() {
11343        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11344            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11345        }
11346    }
11347
11348    void updateSleepIfNeededLocked() {
11349        if (mSleeping && !shouldSleepLocked()) {
11350            mSleeping = false;
11351            startTimeTrackingFocusedActivityLocked();
11352            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11353            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11354            updateOomAdjLocked();
11355        } else if (!mSleeping && shouldSleepLocked()) {
11356            mSleeping = true;
11357            if (mCurAppTimeTracker != null) {
11358                mCurAppTimeTracker.stop();
11359            }
11360            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11361            mStackSupervisor.goingToSleepLocked();
11362            updateOomAdjLocked();
11363
11364            // Initialize the wake times of all processes.
11365            checkExcessivePowerUsageLocked(false);
11366            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11367            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11368            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11369        }
11370    }
11371
11372    private boolean shouldSleepLocked() {
11373        // Resume applications while running a voice interactor.
11374        if (mRunningVoice != null) {
11375            return false;
11376        }
11377
11378        // TODO: Transform the lock screen state into a sleep token instead.
11379        switch (mWakefulness) {
11380            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11381            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11382            case PowerManagerInternal.WAKEFULNESS_DOZING:
11383                // Pause applications whenever the lock screen is shown or any sleep
11384                // tokens have been acquired.
11385                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11386            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11387            default:
11388                // If we're asleep then pause applications unconditionally.
11389                return true;
11390        }
11391    }
11392
11393    /** Pokes the task persister. */
11394    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11395        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11396    }
11397
11398    /** Notifies all listeners when the task stack has changed. */
11399    void notifyTaskStackChangedLocked() {
11400        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11401        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11402        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11403        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11404    }
11405
11406    /** Notifies all listeners when an Activity is pinned. */
11407    void notifyActivityPinnedLocked() {
11408        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11409        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11410    }
11411
11412    /**
11413     * Notifies all listeners when an attempt was made to start an an activity that is already
11414     * running in the pinned stack and the activity was not actually started, but the task is
11415     * either brought to the front or a new Intent is delivered to it.
11416     */
11417    void notifyPinnedActivityRestartAttemptLocked() {
11418        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11419        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11420    }
11421
11422    /** Notifies all listeners when the pinned stack animation ends. */
11423    @Override
11424    public void notifyPinnedStackAnimationEnded() {
11425        synchronized (this) {
11426            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11427            mHandler.obtainMessage(
11428                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11429        }
11430    }
11431
11432    @Override
11433    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11434        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11435    }
11436
11437    @Override
11438    public boolean shutdown(int timeout) {
11439        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11440                != PackageManager.PERMISSION_GRANTED) {
11441            throw new SecurityException("Requires permission "
11442                    + android.Manifest.permission.SHUTDOWN);
11443        }
11444
11445        boolean timedout = false;
11446
11447        synchronized(this) {
11448            mShuttingDown = true;
11449            updateEventDispatchingLocked();
11450            timedout = mStackSupervisor.shutdownLocked(timeout);
11451        }
11452
11453        mAppOpsService.shutdown();
11454        if (mUsageStatsService != null) {
11455            mUsageStatsService.prepareShutdown();
11456        }
11457        mBatteryStatsService.shutdown();
11458        synchronized (this) {
11459            mProcessStats.shutdownLocked();
11460            notifyTaskPersisterLocked(null, true);
11461        }
11462
11463        return timedout;
11464    }
11465
11466    public final void activitySlept(IBinder token) {
11467        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11468
11469        final long origId = Binder.clearCallingIdentity();
11470
11471        synchronized (this) {
11472            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11473            if (r != null) {
11474                mStackSupervisor.activitySleptLocked(r);
11475            }
11476        }
11477
11478        Binder.restoreCallingIdentity(origId);
11479    }
11480
11481    private String lockScreenShownToString() {
11482        switch (mLockScreenShown) {
11483            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11484            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11485            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11486            default: return "Unknown=" + mLockScreenShown;
11487        }
11488    }
11489
11490    void logLockScreen(String msg) {
11491        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11492                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11493                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11494                + " mSleeping=" + mSleeping);
11495    }
11496
11497    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11498        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11499        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11500        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11501            boolean wasRunningVoice = mRunningVoice != null;
11502            mRunningVoice = session;
11503            if (!wasRunningVoice) {
11504                mVoiceWakeLock.acquire();
11505                updateSleepIfNeededLocked();
11506            }
11507        }
11508    }
11509
11510    private void updateEventDispatchingLocked() {
11511        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11512    }
11513
11514    public void setLockScreenShown(boolean showing, boolean occluded) {
11515        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11516                != PackageManager.PERMISSION_GRANTED) {
11517            throw new SecurityException("Requires permission "
11518                    + android.Manifest.permission.DEVICE_POWER);
11519        }
11520
11521        synchronized(this) {
11522            long ident = Binder.clearCallingIdentity();
11523            try {
11524                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11525                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11526                if (showing && occluded) {
11527                    // The lock screen is currently showing, but is occluded by a window that can
11528                    // show on top of the lock screen. In this can we want to dismiss the docked
11529                    // stack since it will be complicated/risky to try to put the activity on top
11530                    // of the lock screen in the right fullscreen configuration.
11531                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11532                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11533                }
11534
11535                updateSleepIfNeededLocked();
11536            } finally {
11537                Binder.restoreCallingIdentity(ident);
11538            }
11539        }
11540    }
11541
11542    @Override
11543    public void notifyLockedProfile(@UserIdInt int userId) {
11544        try {
11545            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11546                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11547            }
11548        } catch (RemoteException ex) {
11549            throw new SecurityException("Fail to check is caller a privileged app", ex);
11550        }
11551
11552        synchronized (this) {
11553            if (mStackSupervisor.isUserLockedProfile(userId)) {
11554                final long ident = Binder.clearCallingIdentity();
11555                try {
11556                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11557                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11558                        // If there is no device lock, we will show the profile's credential page.
11559                        mActivityStarter.showConfirmDeviceCredential(userId);
11560                    } else {
11561                        // Showing launcher to avoid user entering credential twice.
11562                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11563                    }
11564                } finally {
11565                    Binder.restoreCallingIdentity(ident);
11566                }
11567            }
11568        }
11569    }
11570
11571    @Override
11572    public void startConfirmDeviceCredentialIntent(Intent intent) {
11573        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11574        synchronized (this) {
11575            final long ident = Binder.clearCallingIdentity();
11576            try {
11577                mActivityStarter.startConfirmCredentialIntent(intent);
11578            } finally {
11579                Binder.restoreCallingIdentity(ident);
11580            }
11581        }
11582    }
11583
11584    @Override
11585    public void stopAppSwitches() {
11586        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11587                != PackageManager.PERMISSION_GRANTED) {
11588            throw new SecurityException("viewquires permission "
11589                    + android.Manifest.permission.STOP_APP_SWITCHES);
11590        }
11591
11592        synchronized(this) {
11593            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11594                    + APP_SWITCH_DELAY_TIME;
11595            mDidAppSwitch = false;
11596            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11597            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11598            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11599        }
11600    }
11601
11602    public void resumeAppSwitches() {
11603        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11604                != PackageManager.PERMISSION_GRANTED) {
11605            throw new SecurityException("Requires permission "
11606                    + android.Manifest.permission.STOP_APP_SWITCHES);
11607        }
11608
11609        synchronized(this) {
11610            // Note that we don't execute any pending app switches... we will
11611            // let those wait until either the timeout, or the next start
11612            // activity request.
11613            mAppSwitchesAllowedTime = 0;
11614        }
11615    }
11616
11617    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11618            int callingPid, int callingUid, String name) {
11619        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11620            return true;
11621        }
11622
11623        int perm = checkComponentPermission(
11624                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11625                sourceUid, -1, true);
11626        if (perm == PackageManager.PERMISSION_GRANTED) {
11627            return true;
11628        }
11629
11630        // If the actual IPC caller is different from the logical source, then
11631        // also see if they are allowed to control app switches.
11632        if (callingUid != -1 && callingUid != sourceUid) {
11633            perm = checkComponentPermission(
11634                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11635                    callingUid, -1, true);
11636            if (perm == PackageManager.PERMISSION_GRANTED) {
11637                return true;
11638            }
11639        }
11640
11641        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11642        return false;
11643    }
11644
11645    public void setDebugApp(String packageName, boolean waitForDebugger,
11646            boolean persistent) {
11647        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11648                "setDebugApp()");
11649
11650        long ident = Binder.clearCallingIdentity();
11651        try {
11652            // Note that this is not really thread safe if there are multiple
11653            // callers into it at the same time, but that's not a situation we
11654            // care about.
11655            if (persistent) {
11656                final ContentResolver resolver = mContext.getContentResolver();
11657                Settings.Global.putString(
11658                    resolver, Settings.Global.DEBUG_APP,
11659                    packageName);
11660                Settings.Global.putInt(
11661                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11662                    waitForDebugger ? 1 : 0);
11663            }
11664
11665            synchronized (this) {
11666                if (!persistent) {
11667                    mOrigDebugApp = mDebugApp;
11668                    mOrigWaitForDebugger = mWaitForDebugger;
11669                }
11670                mDebugApp = packageName;
11671                mWaitForDebugger = waitForDebugger;
11672                mDebugTransient = !persistent;
11673                if (packageName != null) {
11674                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11675                            false, UserHandle.USER_ALL, "set debug app");
11676                }
11677            }
11678        } finally {
11679            Binder.restoreCallingIdentity(ident);
11680        }
11681    }
11682
11683    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11684        synchronized (this) {
11685            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11686            if (!isDebuggable) {
11687                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11688                    throw new SecurityException("Process not debuggable: " + app.packageName);
11689                }
11690            }
11691
11692            mTrackAllocationApp = processName;
11693        }
11694    }
11695
11696    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11697        synchronized (this) {
11698            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11699            if (!isDebuggable) {
11700                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11701                    throw new SecurityException("Process not debuggable: " + app.packageName);
11702                }
11703            }
11704            mProfileApp = processName;
11705            mProfileFile = profilerInfo.profileFile;
11706            if (mProfileFd != null) {
11707                try {
11708                    mProfileFd.close();
11709                } catch (IOException e) {
11710                }
11711                mProfileFd = null;
11712            }
11713            mProfileFd = profilerInfo.profileFd;
11714            mSamplingInterval = profilerInfo.samplingInterval;
11715            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11716            mProfileType = 0;
11717        }
11718    }
11719
11720    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11721        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11722        if (!isDebuggable) {
11723            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11724                throw new SecurityException("Process not debuggable: " + app.packageName);
11725            }
11726        }
11727        mNativeDebuggingApp = processName;
11728    }
11729
11730    @Override
11731    public void setAlwaysFinish(boolean enabled) {
11732        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11733                "setAlwaysFinish()");
11734
11735        long ident = Binder.clearCallingIdentity();
11736        try {
11737            Settings.Global.putInt(
11738                    mContext.getContentResolver(),
11739                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11740
11741            synchronized (this) {
11742                mAlwaysFinishActivities = enabled;
11743            }
11744        } finally {
11745            Binder.restoreCallingIdentity(ident);
11746        }
11747    }
11748
11749    @Override
11750    public void setLenientBackgroundCheck(boolean enabled) {
11751        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11752                "setLenientBackgroundCheck()");
11753
11754        long ident = Binder.clearCallingIdentity();
11755        try {
11756            Settings.Global.putInt(
11757                    mContext.getContentResolver(),
11758                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11759
11760            synchronized (this) {
11761                mLenientBackgroundCheck = enabled;
11762            }
11763        } finally {
11764            Binder.restoreCallingIdentity(ident);
11765        }
11766    }
11767
11768    @Override
11769    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11770        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11771                "setActivityController()");
11772        synchronized (this) {
11773            mController = controller;
11774            mControllerIsAMonkey = imAMonkey;
11775            Watchdog.getInstance().setActivityController(controller);
11776        }
11777    }
11778
11779    @Override
11780    public void setUserIsMonkey(boolean userIsMonkey) {
11781        synchronized (this) {
11782            synchronized (mPidsSelfLocked) {
11783                final int callingPid = Binder.getCallingPid();
11784                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11785                if (precessRecord == null) {
11786                    throw new SecurityException("Unknown process: " + callingPid);
11787                }
11788                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11789                    throw new SecurityException("Only an instrumentation process "
11790                            + "with a UiAutomation can call setUserIsMonkey");
11791                }
11792            }
11793            mUserIsMonkey = userIsMonkey;
11794        }
11795    }
11796
11797    @Override
11798    public boolean isUserAMonkey() {
11799        synchronized (this) {
11800            // If there is a controller also implies the user is a monkey.
11801            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11802        }
11803    }
11804
11805    public void requestBugReport(int bugreportType) {
11806        String service = null;
11807        switch (bugreportType) {
11808            case ActivityManager.BUGREPORT_OPTION_FULL:
11809                service = "bugreport";
11810                break;
11811            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11812                service = "bugreportplus";
11813                break;
11814            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11815                service = "bugreportremote";
11816                break;
11817        }
11818        if (service == null) {
11819            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11820                    + bugreportType);
11821        }
11822        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11823        SystemProperties.set("ctl.start", service);
11824    }
11825
11826    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11827        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11828    }
11829
11830    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11831        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11832            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11833        }
11834        return KEY_DISPATCHING_TIMEOUT;
11835    }
11836
11837    @Override
11838    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11839        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11840                != PackageManager.PERMISSION_GRANTED) {
11841            throw new SecurityException("Requires permission "
11842                    + android.Manifest.permission.FILTER_EVENTS);
11843        }
11844        ProcessRecord proc;
11845        long timeout;
11846        synchronized (this) {
11847            synchronized (mPidsSelfLocked) {
11848                proc = mPidsSelfLocked.get(pid);
11849            }
11850            timeout = getInputDispatchingTimeoutLocked(proc);
11851        }
11852
11853        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11854            return -1;
11855        }
11856
11857        return timeout;
11858    }
11859
11860    /**
11861     * Handle input dispatching timeouts.
11862     * Returns whether input dispatching should be aborted or not.
11863     */
11864    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11865            final ActivityRecord activity, final ActivityRecord parent,
11866            final boolean aboveSystem, String reason) {
11867        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11868                != PackageManager.PERMISSION_GRANTED) {
11869            throw new SecurityException("Requires permission "
11870                    + android.Manifest.permission.FILTER_EVENTS);
11871        }
11872
11873        final String annotation;
11874        if (reason == null) {
11875            annotation = "Input dispatching timed out";
11876        } else {
11877            annotation = "Input dispatching timed out (" + reason + ")";
11878        }
11879
11880        if (proc != null) {
11881            synchronized (this) {
11882                if (proc.debugging) {
11883                    return false;
11884                }
11885
11886                if (mDidDexOpt) {
11887                    // Give more time since we were dexopting.
11888                    mDidDexOpt = false;
11889                    return false;
11890                }
11891
11892                if (proc.instrumentationClass != null) {
11893                    Bundle info = new Bundle();
11894                    info.putString("shortMsg", "keyDispatchingTimedOut");
11895                    info.putString("longMsg", annotation);
11896                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11897                    return true;
11898                }
11899            }
11900            mHandler.post(new Runnable() {
11901                @Override
11902                public void run() {
11903                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11904                }
11905            });
11906        }
11907
11908        return true;
11909    }
11910
11911    @Override
11912    public Bundle getAssistContextExtras(int requestType) {
11913        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11914                null, null, true /* focused */, true /* newSessionId */,
11915                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11916        if (pae == null) {
11917            return null;
11918        }
11919        synchronized (pae) {
11920            while (!pae.haveResult) {
11921                try {
11922                    pae.wait();
11923                } catch (InterruptedException e) {
11924                }
11925            }
11926        }
11927        synchronized (this) {
11928            buildAssistBundleLocked(pae, pae.result);
11929            mPendingAssistExtras.remove(pae);
11930            mUiHandler.removeCallbacks(pae);
11931        }
11932        return pae.extras;
11933    }
11934
11935    @Override
11936    public boolean isAssistDataAllowedOnCurrentActivity() {
11937        int userId;
11938        synchronized (this) {
11939            userId = mUserController.getCurrentUserIdLocked();
11940            ActivityRecord activity = getFocusedStack().topActivity();
11941            if (activity == null) {
11942                return false;
11943            }
11944            userId = activity.userId;
11945        }
11946        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11947                Context.DEVICE_POLICY_SERVICE);
11948        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11949    }
11950
11951    @Override
11952    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11953        long ident = Binder.clearCallingIdentity();
11954        try {
11955            synchronized (this) {
11956                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11957                ActivityRecord top = getFocusedStack().topActivity();
11958                if (top != caller) {
11959                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11960                            + " is not current top " + top);
11961                    return false;
11962                }
11963                if (!top.nowVisible) {
11964                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11965                            + " is not visible");
11966                    return false;
11967                }
11968            }
11969            AssistUtils utils = new AssistUtils(mContext);
11970            return utils.showSessionForActiveService(args,
11971                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11972        } finally {
11973            Binder.restoreCallingIdentity(ident);
11974        }
11975    }
11976
11977    @Override
11978    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11979            Bundle receiverExtras,
11980            IBinder activityToken, boolean focused, boolean newSessionId) {
11981        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11982                activityToken, focused, newSessionId,
11983                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11984                != null;
11985    }
11986
11987    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11988            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
11989            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
11990        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11991                "enqueueAssistContext()");
11992        synchronized (this) {
11993            ActivityRecord activity = getFocusedStack().topActivity();
11994            if (activity == null) {
11995                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11996                return null;
11997            }
11998            if (activity.app == null || activity.app.thread == null) {
11999                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12000                return null;
12001            }
12002            if (focused) {
12003                if (activityToken != null) {
12004                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12005                    if (activity != caller) {
12006                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12007                                + " is not current top " + activity);
12008                        return null;
12009                    }
12010                }
12011            } else {
12012                activity = ActivityRecord.forTokenLocked(activityToken);
12013                if (activity == null) {
12014                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12015                            + " couldn't be found");
12016                    return null;
12017                }
12018            }
12019
12020            PendingAssistExtras pae;
12021            Bundle extras = new Bundle();
12022            if (args != null) {
12023                extras.putAll(args);
12024            }
12025            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12026            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12027            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12028                    userHandle);
12029            // Increment the sessionId if necessary
12030            if (newSessionId) {
12031                mViSessionId++;
12032            }
12033            try {
12034                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12035                        requestType, mViSessionId);
12036                mPendingAssistExtras.add(pae);
12037                mUiHandler.postDelayed(pae, timeout);
12038            } catch (RemoteException e) {
12039                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12040                return null;
12041            }
12042            return pae;
12043        }
12044    }
12045
12046    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12047        IResultReceiver receiver;
12048        synchronized (this) {
12049            mPendingAssistExtras.remove(pae);
12050            receiver = pae.receiver;
12051        }
12052        if (receiver != null) {
12053            // Caller wants result sent back to them.
12054            Bundle sendBundle = new Bundle();
12055            // At least return the receiver extras
12056            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12057                    pae.receiverExtras);
12058            try {
12059                pae.receiver.send(0, sendBundle);
12060            } catch (RemoteException e) {
12061            }
12062        }
12063    }
12064
12065    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12066        if (result != null) {
12067            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12068        }
12069        if (pae.hint != null) {
12070            pae.extras.putBoolean(pae.hint, true);
12071        }
12072    }
12073
12074    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12075            AssistContent content, Uri referrer) {
12076        PendingAssistExtras pae = (PendingAssistExtras)token;
12077        synchronized (pae) {
12078            pae.result = extras;
12079            pae.structure = structure;
12080            pae.content = content;
12081            if (referrer != null) {
12082                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12083            }
12084            pae.haveResult = true;
12085            pae.notifyAll();
12086            if (pae.intent == null && pae.receiver == null) {
12087                // Caller is just waiting for the result.
12088                return;
12089            }
12090        }
12091
12092        // We are now ready to launch the assist activity.
12093        IResultReceiver sendReceiver = null;
12094        Bundle sendBundle = null;
12095        synchronized (this) {
12096            buildAssistBundleLocked(pae, extras);
12097            boolean exists = mPendingAssistExtras.remove(pae);
12098            mUiHandler.removeCallbacks(pae);
12099            if (!exists) {
12100                // Timed out.
12101                return;
12102            }
12103            if ((sendReceiver=pae.receiver) != null) {
12104                // Caller wants result sent back to them.
12105                sendBundle = new Bundle();
12106                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12107                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12108                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12109                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12110                        pae.receiverExtras);
12111            }
12112        }
12113        if (sendReceiver != null) {
12114            try {
12115                sendReceiver.send(0, sendBundle);
12116            } catch (RemoteException e) {
12117            }
12118            return;
12119        }
12120
12121        long ident = Binder.clearCallingIdentity();
12122        try {
12123            pae.intent.replaceExtras(pae.extras);
12124            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12125                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12126                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12127            closeSystemDialogs("assist");
12128            try {
12129                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12130            } catch (ActivityNotFoundException e) {
12131                Slog.w(TAG, "No activity to handle assist action.", e);
12132            }
12133        } finally {
12134            Binder.restoreCallingIdentity(ident);
12135        }
12136    }
12137
12138    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12139            Bundle args) {
12140        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12141                true /* focused */, true /* newSessionId */,
12142                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12143    }
12144
12145    public void registerProcessObserver(IProcessObserver observer) {
12146        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12147                "registerProcessObserver()");
12148        synchronized (this) {
12149            mProcessObservers.register(observer);
12150        }
12151    }
12152
12153    @Override
12154    public void unregisterProcessObserver(IProcessObserver observer) {
12155        synchronized (this) {
12156            mProcessObservers.unregister(observer);
12157        }
12158    }
12159
12160    @Override
12161    public void registerUidObserver(IUidObserver observer, int which) {
12162        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12163                "registerUidObserver()");
12164        synchronized (this) {
12165            mUidObservers.register(observer, which);
12166        }
12167    }
12168
12169    @Override
12170    public void unregisterUidObserver(IUidObserver observer) {
12171        synchronized (this) {
12172            mUidObservers.unregister(observer);
12173        }
12174    }
12175
12176    @Override
12177    public boolean convertFromTranslucent(IBinder token) {
12178        final long origId = Binder.clearCallingIdentity();
12179        try {
12180            synchronized (this) {
12181                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12182                if (r == null) {
12183                    return false;
12184                }
12185                final boolean translucentChanged = r.changeWindowTranslucency(true);
12186                if (translucentChanged) {
12187                    r.task.stack.releaseBackgroundResources(r);
12188                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12189                }
12190                mWindowManager.setAppFullscreen(token, true);
12191                return translucentChanged;
12192            }
12193        } finally {
12194            Binder.restoreCallingIdentity(origId);
12195        }
12196    }
12197
12198    @Override
12199    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12200        final long origId = Binder.clearCallingIdentity();
12201        try {
12202            synchronized (this) {
12203                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12204                if (r == null) {
12205                    return false;
12206                }
12207                int index = r.task.mActivities.lastIndexOf(r);
12208                if (index > 0) {
12209                    ActivityRecord under = r.task.mActivities.get(index - 1);
12210                    under.returningOptions = options;
12211                }
12212                final boolean translucentChanged = r.changeWindowTranslucency(false);
12213                if (translucentChanged) {
12214                    r.task.stack.convertActivityToTranslucent(r);
12215                }
12216                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12217                mWindowManager.setAppFullscreen(token, false);
12218                return translucentChanged;
12219            }
12220        } finally {
12221            Binder.restoreCallingIdentity(origId);
12222        }
12223    }
12224
12225    @Override
12226    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12227        final long origId = Binder.clearCallingIdentity();
12228        try {
12229            synchronized (this) {
12230                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12231                if (r != null) {
12232                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12233                }
12234            }
12235            return false;
12236        } finally {
12237            Binder.restoreCallingIdentity(origId);
12238        }
12239    }
12240
12241    @Override
12242    public boolean isBackgroundVisibleBehind(IBinder token) {
12243        final long origId = Binder.clearCallingIdentity();
12244        try {
12245            synchronized (this) {
12246                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12247                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12248                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12249                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12250                return visible;
12251            }
12252        } finally {
12253            Binder.restoreCallingIdentity(origId);
12254        }
12255    }
12256
12257    @Override
12258    public ActivityOptions getActivityOptions(IBinder token) {
12259        final long origId = Binder.clearCallingIdentity();
12260        try {
12261            synchronized (this) {
12262                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12263                if (r != null) {
12264                    final ActivityOptions activityOptions = r.pendingOptions;
12265                    r.pendingOptions = null;
12266                    return activityOptions;
12267                }
12268                return null;
12269            }
12270        } finally {
12271            Binder.restoreCallingIdentity(origId);
12272        }
12273    }
12274
12275    @Override
12276    public void setImmersive(IBinder token, boolean immersive) {
12277        synchronized(this) {
12278            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12279            if (r == null) {
12280                throw new IllegalArgumentException();
12281            }
12282            r.immersive = immersive;
12283
12284            // update associated state if we're frontmost
12285            if (r == mFocusedActivity) {
12286                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12287                applyUpdateLockStateLocked(r);
12288            }
12289        }
12290    }
12291
12292    @Override
12293    public boolean isImmersive(IBinder token) {
12294        synchronized (this) {
12295            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12296            if (r == null) {
12297                throw new IllegalArgumentException();
12298            }
12299            return r.immersive;
12300        }
12301    }
12302
12303    @Override
12304    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12305        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12306            throw new UnsupportedOperationException("VR mode not supported on this device!");
12307        }
12308
12309        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12310
12311        ActivityRecord r;
12312        synchronized (this) {
12313            r = ActivityRecord.isInStackLocked(token);
12314        }
12315
12316        if (r == null) {
12317            throw new IllegalArgumentException();
12318        }
12319
12320        int err;
12321        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12322                VrManagerInternal.NO_ERROR) {
12323            return err;
12324        }
12325
12326        synchronized(this) {
12327            r.requestedVrComponent = (enabled) ? packageName : null;
12328
12329            // Update associated state if this activity is currently focused
12330            if (r == mFocusedActivity) {
12331                applyUpdateVrModeLocked(r);
12332            }
12333            return 0;
12334        }
12335    }
12336
12337    @Override
12338    public boolean isVrModePackageEnabled(ComponentName packageName) {
12339        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12340            throw new UnsupportedOperationException("VR mode not supported on this device!");
12341        }
12342
12343        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12344
12345        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12346                VrManagerInternal.NO_ERROR;
12347    }
12348
12349    public boolean isTopActivityImmersive() {
12350        enforceNotIsolatedCaller("startActivity");
12351        synchronized (this) {
12352            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12353            return (r != null) ? r.immersive : false;
12354        }
12355    }
12356
12357    @Override
12358    public boolean isTopOfTask(IBinder token) {
12359        synchronized (this) {
12360            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12361            if (r == null) {
12362                throw new IllegalArgumentException();
12363            }
12364            return r.task.getTopActivity() == r;
12365        }
12366    }
12367
12368    public final void enterSafeMode() {
12369        synchronized(this) {
12370            // It only makes sense to do this before the system is ready
12371            // and started launching other packages.
12372            if (!mSystemReady) {
12373                try {
12374                    AppGlobals.getPackageManager().enterSafeMode();
12375                } catch (RemoteException e) {
12376                }
12377            }
12378
12379            mSafeMode = true;
12380        }
12381    }
12382
12383    public final void showSafeModeOverlay() {
12384        View v = LayoutInflater.from(mContext).inflate(
12385                com.android.internal.R.layout.safe_mode, null);
12386        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12387        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12388        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12389        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12390        lp.gravity = Gravity.BOTTOM | Gravity.START;
12391        lp.format = v.getBackground().getOpacity();
12392        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12393                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12394        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12395        ((WindowManager)mContext.getSystemService(
12396                Context.WINDOW_SERVICE)).addView(v, lp);
12397    }
12398
12399    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12400        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12401            return;
12402        }
12403        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12404        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12405        synchronized (stats) {
12406            if (mBatteryStatsService.isOnBattery()) {
12407                mBatteryStatsService.enforceCallingPermission();
12408                int MY_UID = Binder.getCallingUid();
12409                final int uid;
12410                if (sender == null) {
12411                    uid = sourceUid;
12412                } else {
12413                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12414                }
12415                BatteryStatsImpl.Uid.Pkg pkg =
12416                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12417                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12418                pkg.noteWakeupAlarmLocked(tag);
12419            }
12420        }
12421    }
12422
12423    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12424        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12425            return;
12426        }
12427        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12428        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12429        synchronized (stats) {
12430            mBatteryStatsService.enforceCallingPermission();
12431            int MY_UID = Binder.getCallingUid();
12432            final int uid;
12433            if (sender == null) {
12434                uid = sourceUid;
12435            } else {
12436                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12437            }
12438            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12439        }
12440    }
12441
12442    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12443        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12444            return;
12445        }
12446        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12447        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12448        synchronized (stats) {
12449            mBatteryStatsService.enforceCallingPermission();
12450            int MY_UID = Binder.getCallingUid();
12451            final int uid;
12452            if (sender == null) {
12453                uid = sourceUid;
12454            } else {
12455                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12456            }
12457            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12458        }
12459    }
12460
12461    public boolean killPids(int[] pids, String pReason, boolean secure) {
12462        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12463            throw new SecurityException("killPids only available to the system");
12464        }
12465        String reason = (pReason == null) ? "Unknown" : pReason;
12466        // XXX Note: don't acquire main activity lock here, because the window
12467        // manager calls in with its locks held.
12468
12469        boolean killed = false;
12470        synchronized (mPidsSelfLocked) {
12471            int worstType = 0;
12472            for (int i=0; i<pids.length; i++) {
12473                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12474                if (proc != null) {
12475                    int type = proc.setAdj;
12476                    if (type > worstType) {
12477                        worstType = type;
12478                    }
12479                }
12480            }
12481
12482            // If the worst oom_adj is somewhere in the cached proc LRU range,
12483            // then constrain it so we will kill all cached procs.
12484            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12485                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12486                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12487            }
12488
12489            // If this is not a secure call, don't let it kill processes that
12490            // are important.
12491            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12492                worstType = ProcessList.SERVICE_ADJ;
12493            }
12494
12495            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12496            for (int i=0; i<pids.length; i++) {
12497                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12498                if (proc == null) {
12499                    continue;
12500                }
12501                int adj = proc.setAdj;
12502                if (adj >= worstType && !proc.killedByAm) {
12503                    proc.kill(reason, true);
12504                    killed = true;
12505                }
12506            }
12507        }
12508        return killed;
12509    }
12510
12511    @Override
12512    public void killUid(int appId, int userId, String reason) {
12513        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12514        synchronized (this) {
12515            final long identity = Binder.clearCallingIdentity();
12516            try {
12517                killPackageProcessesLocked(null, appId, userId,
12518                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12519                        reason != null ? reason : "kill uid");
12520            } finally {
12521                Binder.restoreCallingIdentity(identity);
12522            }
12523        }
12524    }
12525
12526    @Override
12527    public boolean killProcessesBelowForeground(String reason) {
12528        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12529            throw new SecurityException("killProcessesBelowForeground() only available to system");
12530        }
12531
12532        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12533    }
12534
12535    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12536        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12537            throw new SecurityException("killProcessesBelowAdj() only available to system");
12538        }
12539
12540        boolean killed = false;
12541        synchronized (mPidsSelfLocked) {
12542            final int size = mPidsSelfLocked.size();
12543            for (int i = 0; i < size; i++) {
12544                final int pid = mPidsSelfLocked.keyAt(i);
12545                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12546                if (proc == null) continue;
12547
12548                final int adj = proc.setAdj;
12549                if (adj > belowAdj && !proc.killedByAm) {
12550                    proc.kill(reason, true);
12551                    killed = true;
12552                }
12553            }
12554        }
12555        return killed;
12556    }
12557
12558    @Override
12559    public void hang(final IBinder who, boolean allowRestart) {
12560        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12561                != PackageManager.PERMISSION_GRANTED) {
12562            throw new SecurityException("Requires permission "
12563                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12564        }
12565
12566        final IBinder.DeathRecipient death = new DeathRecipient() {
12567            @Override
12568            public void binderDied() {
12569                synchronized (this) {
12570                    notifyAll();
12571                }
12572            }
12573        };
12574
12575        try {
12576            who.linkToDeath(death, 0);
12577        } catch (RemoteException e) {
12578            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12579            return;
12580        }
12581
12582        synchronized (this) {
12583            Watchdog.getInstance().setAllowRestart(allowRestart);
12584            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12585            synchronized (death) {
12586                while (who.isBinderAlive()) {
12587                    try {
12588                        death.wait();
12589                    } catch (InterruptedException e) {
12590                    }
12591                }
12592            }
12593            Watchdog.getInstance().setAllowRestart(true);
12594        }
12595    }
12596
12597    @Override
12598    public void restart() {
12599        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12600                != PackageManager.PERMISSION_GRANTED) {
12601            throw new SecurityException("Requires permission "
12602                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12603        }
12604
12605        Log.i(TAG, "Sending shutdown broadcast...");
12606
12607        BroadcastReceiver br = new BroadcastReceiver() {
12608            @Override public void onReceive(Context context, Intent intent) {
12609                // Now the broadcast is done, finish up the low-level shutdown.
12610                Log.i(TAG, "Shutting down activity manager...");
12611                shutdown(10000);
12612                Log.i(TAG, "Shutdown complete, restarting!");
12613                Process.killProcess(Process.myPid());
12614                System.exit(10);
12615            }
12616        };
12617
12618        // First send the high-level shut down broadcast.
12619        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12620        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12621        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12622        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12623        mContext.sendOrderedBroadcastAsUser(intent,
12624                UserHandle.ALL, null, br, mHandler, 0, null, null);
12625        */
12626        br.onReceive(mContext, intent);
12627    }
12628
12629    private long getLowRamTimeSinceIdle(long now) {
12630        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12631    }
12632
12633    @Override
12634    public void performIdleMaintenance() {
12635        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12636                != PackageManager.PERMISSION_GRANTED) {
12637            throw new SecurityException("Requires permission "
12638                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12639        }
12640
12641        synchronized (this) {
12642            final long now = SystemClock.uptimeMillis();
12643            final long timeSinceLastIdle = now - mLastIdleTime;
12644            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12645            mLastIdleTime = now;
12646            mLowRamTimeSinceLastIdle = 0;
12647            if (mLowRamStartTime != 0) {
12648                mLowRamStartTime = now;
12649            }
12650
12651            StringBuilder sb = new StringBuilder(128);
12652            sb.append("Idle maintenance over ");
12653            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12654            sb.append(" low RAM for ");
12655            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12656            Slog.i(TAG, sb.toString());
12657
12658            // If at least 1/3 of our time since the last idle period has been spent
12659            // with RAM low, then we want to kill processes.
12660            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12661
12662            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12663                ProcessRecord proc = mLruProcesses.get(i);
12664                if (proc.notCachedSinceIdle) {
12665                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12666                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12667                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12668                        if (doKilling && proc.initialIdlePss != 0
12669                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12670                            sb = new StringBuilder(128);
12671                            sb.append("Kill");
12672                            sb.append(proc.processName);
12673                            sb.append(" in idle maint: pss=");
12674                            sb.append(proc.lastPss);
12675                            sb.append(", swapPss=");
12676                            sb.append(proc.lastSwapPss);
12677                            sb.append(", initialPss=");
12678                            sb.append(proc.initialIdlePss);
12679                            sb.append(", period=");
12680                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12681                            sb.append(", lowRamPeriod=");
12682                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12683                            Slog.wtfQuiet(TAG, sb.toString());
12684                            proc.kill("idle maint (pss " + proc.lastPss
12685                                    + " from " + proc.initialIdlePss + ")", true);
12686                        }
12687                    }
12688                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12689                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12690                    proc.notCachedSinceIdle = true;
12691                    proc.initialIdlePss = 0;
12692                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12693                            mTestPssMode, isSleeping(), now);
12694                }
12695            }
12696
12697            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12698            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12699        }
12700    }
12701
12702    @Override
12703    public void sendIdleJobTrigger() {
12704        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12705                != PackageManager.PERMISSION_GRANTED) {
12706            throw new SecurityException("Requires permission "
12707                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12708        }
12709
12710        final long ident = Binder.clearCallingIdentity();
12711        try {
12712            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12713                    .setPackage("android")
12714                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12715            broadcastIntent(null, intent, null, null, 0, null, null, null,
12716                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12717        } finally {
12718            Binder.restoreCallingIdentity(ident);
12719        }
12720    }
12721
12722    private void retrieveSettings() {
12723        final ContentResolver resolver = mContext.getContentResolver();
12724        final boolean freeformWindowManagement =
12725                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12726                        || Settings.Global.getInt(
12727                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12728        final boolean supportsPictureInPicture =
12729                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12730
12731        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12732        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12733        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12734        final boolean alwaysFinishActivities =
12735                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12736        final boolean lenientBackgroundCheck =
12737                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12738        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12739        final boolean forceResizable = Settings.Global.getInt(
12740                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12741        // Transfer any global setting for forcing RTL layout, into a System Property
12742        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12743
12744        final Configuration configuration = new Configuration();
12745        Settings.System.getConfiguration(resolver, configuration);
12746        if (forceRtl) {
12747            // This will take care of setting the correct layout direction flags
12748            configuration.setLayoutDirection(configuration.locale);
12749        }
12750
12751        synchronized (this) {
12752            mDebugApp = mOrigDebugApp = debugApp;
12753            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12754            mAlwaysFinishActivities = alwaysFinishActivities;
12755            mLenientBackgroundCheck = lenientBackgroundCheck;
12756            mForceResizableActivities = forceResizable;
12757            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12758            if (supportsMultiWindow || forceResizable) {
12759                mSupportsMultiWindow = true;
12760                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12761                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12762            } else {
12763                mSupportsMultiWindow = false;
12764                mSupportsFreeformWindowManagement = false;
12765                mSupportsPictureInPicture = false;
12766            }
12767            // This happens before any activities are started, so we can
12768            // change mConfiguration in-place.
12769            updateConfigurationLocked(configuration, null, true);
12770            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12771                    "Initial config: " + mConfiguration);
12772
12773            // Load resources only after the current configuration has been set.
12774            final Resources res = mContext.getResources();
12775            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12776            mThumbnailWidth = res.getDimensionPixelSize(
12777                    com.android.internal.R.dimen.thumbnail_width);
12778            mThumbnailHeight = res.getDimensionPixelSize(
12779                    com.android.internal.R.dimen.thumbnail_height);
12780            mFullscreenThumbnailScale = res.getFraction(
12781                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12782            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12783                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12784            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12785                    com.android.internal.R.string.config_appsNotReportingCrashes));
12786        }
12787    }
12788
12789    public boolean testIsSystemReady() {
12790        // no need to synchronize(this) just to read & return the value
12791        return mSystemReady;
12792    }
12793
12794    public void systemReady(final Runnable goingCallback) {
12795        synchronized(this) {
12796            if (mSystemReady) {
12797                // If we're done calling all the receivers, run the next "boot phase" passed in
12798                // by the SystemServer
12799                if (goingCallback != null) {
12800                    goingCallback.run();
12801                }
12802                return;
12803            }
12804
12805            mLocalDeviceIdleController
12806                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12807
12808            // Make sure we have the current profile info, since it is needed for security checks.
12809            mUserController.onSystemReady();
12810            mRecentTasks.onSystemReadyLocked();
12811            mAppOpsService.systemReady();
12812            mSystemReady = true;
12813        }
12814
12815        ArrayList<ProcessRecord> procsToKill = null;
12816        synchronized(mPidsSelfLocked) {
12817            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12818                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12819                if (!isAllowedWhileBooting(proc.info)){
12820                    if (procsToKill == null) {
12821                        procsToKill = new ArrayList<ProcessRecord>();
12822                    }
12823                    procsToKill.add(proc);
12824                }
12825            }
12826        }
12827
12828        synchronized(this) {
12829            if (procsToKill != null) {
12830                for (int i=procsToKill.size()-1; i>=0; i--) {
12831                    ProcessRecord proc = procsToKill.get(i);
12832                    Slog.i(TAG, "Removing system update proc: " + proc);
12833                    removeProcessLocked(proc, true, false, "system update done");
12834                }
12835            }
12836
12837            // Now that we have cleaned up any update processes, we
12838            // are ready to start launching real processes and know that
12839            // we won't trample on them any more.
12840            mProcessesReady = true;
12841        }
12842
12843        Slog.i(TAG, "System now ready");
12844        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12845            SystemClock.uptimeMillis());
12846
12847        synchronized(this) {
12848            // Make sure we have no pre-ready processes sitting around.
12849
12850            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12851                ResolveInfo ri = mContext.getPackageManager()
12852                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12853                                STOCK_PM_FLAGS);
12854                CharSequence errorMsg = null;
12855                if (ri != null) {
12856                    ActivityInfo ai = ri.activityInfo;
12857                    ApplicationInfo app = ai.applicationInfo;
12858                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12859                        mTopAction = Intent.ACTION_FACTORY_TEST;
12860                        mTopData = null;
12861                        mTopComponent = new ComponentName(app.packageName,
12862                                ai.name);
12863                    } else {
12864                        errorMsg = mContext.getResources().getText(
12865                                com.android.internal.R.string.factorytest_not_system);
12866                    }
12867                } else {
12868                    errorMsg = mContext.getResources().getText(
12869                            com.android.internal.R.string.factorytest_no_action);
12870                }
12871                if (errorMsg != null) {
12872                    mTopAction = null;
12873                    mTopData = null;
12874                    mTopComponent = null;
12875                    Message msg = Message.obtain();
12876                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12877                    msg.getData().putCharSequence("msg", errorMsg);
12878                    mUiHandler.sendMessage(msg);
12879                }
12880            }
12881        }
12882
12883        retrieveSettings();
12884        final int currentUserId;
12885        synchronized (this) {
12886            currentUserId = mUserController.getCurrentUserIdLocked();
12887            readGrantedUriPermissionsLocked();
12888        }
12889
12890        if (goingCallback != null) goingCallback.run();
12891
12892        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12893                Integer.toString(currentUserId), currentUserId);
12894        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12895                Integer.toString(currentUserId), currentUserId);
12896        mSystemServiceManager.startUser(currentUserId);
12897
12898        synchronized (this) {
12899            // Only start up encryption-aware persistent apps; once user is
12900            // unlocked we'll come back around and start unaware apps
12901            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12902
12903            // Start up initial activity.
12904            mBooting = true;
12905            // Enable home activity for system user, so that the system can always boot
12906            if (UserManager.isSplitSystemUser()) {
12907                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12908                try {
12909                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12910                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12911                            UserHandle.USER_SYSTEM);
12912                } catch (RemoteException e) {
12913                    throw e.rethrowAsRuntimeException();
12914                }
12915            }
12916            startHomeActivityLocked(currentUserId, "systemReady");
12917
12918            try {
12919                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12920                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12921                            + " data partition or your device will be unstable.");
12922                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12923                }
12924            } catch (RemoteException e) {
12925            }
12926
12927            if (!Build.isBuildConsistent()) {
12928                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12929                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12930            }
12931
12932            long ident = Binder.clearCallingIdentity();
12933            try {
12934                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12935                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12936                        | Intent.FLAG_RECEIVER_FOREGROUND);
12937                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12938                broadcastIntentLocked(null, null, intent,
12939                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12940                        null, false, false, MY_PID, Process.SYSTEM_UID,
12941                        currentUserId);
12942                intent = new Intent(Intent.ACTION_USER_STARTING);
12943                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12944                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12945                broadcastIntentLocked(null, null, intent,
12946                        null, new IIntentReceiver.Stub() {
12947                            @Override
12948                            public void performReceive(Intent intent, int resultCode, String data,
12949                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12950                                    throws RemoteException {
12951                            }
12952                        }, 0, null, null,
12953                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12954                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12955            } catch (Throwable t) {
12956                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12957            } finally {
12958                Binder.restoreCallingIdentity(ident);
12959            }
12960            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12961            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12962        }
12963    }
12964
12965    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12966        synchronized (this) {
12967            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12968        }
12969    }
12970
12971    void skipCurrentReceiverLocked(ProcessRecord app) {
12972        for (BroadcastQueue queue : mBroadcastQueues) {
12973            queue.skipCurrentReceiverLocked(app);
12974        }
12975    }
12976
12977    /**
12978     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12979     * The application process will exit immediately after this call returns.
12980     * @param app object of the crashing app, null for the system server
12981     * @param crashInfo describing the exception
12982     */
12983    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12984        ProcessRecord r = findAppProcess(app, "Crash");
12985        final String processName = app == null ? "system_server"
12986                : (r == null ? "unknown" : r.processName);
12987
12988        handleApplicationCrashInner("crash", r, processName, crashInfo);
12989    }
12990
12991    /* Native crash reporting uses this inner version because it needs to be somewhat
12992     * decoupled from the AM-managed cleanup lifecycle
12993     */
12994    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12995            ApplicationErrorReport.CrashInfo crashInfo) {
12996        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12997                UserHandle.getUserId(Binder.getCallingUid()), processName,
12998                r == null ? -1 : r.info.flags,
12999                crashInfo.exceptionClassName,
13000                crashInfo.exceptionMessage,
13001                crashInfo.throwFileName,
13002                crashInfo.throwLineNumber);
13003
13004        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13005
13006        mAppErrors.crashApplication(r, crashInfo);
13007    }
13008
13009    public void handleApplicationStrictModeViolation(
13010            IBinder app,
13011            int violationMask,
13012            StrictMode.ViolationInfo info) {
13013        ProcessRecord r = findAppProcess(app, "StrictMode");
13014        if (r == null) {
13015            return;
13016        }
13017
13018        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13019            Integer stackFingerprint = info.hashCode();
13020            boolean logIt = true;
13021            synchronized (mAlreadyLoggedViolatedStacks) {
13022                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13023                    logIt = false;
13024                    // TODO: sub-sample into EventLog for these, with
13025                    // the info.durationMillis?  Then we'd get
13026                    // the relative pain numbers, without logging all
13027                    // the stack traces repeatedly.  We'd want to do
13028                    // likewise in the client code, which also does
13029                    // dup suppression, before the Binder call.
13030                } else {
13031                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13032                        mAlreadyLoggedViolatedStacks.clear();
13033                    }
13034                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13035                }
13036            }
13037            if (logIt) {
13038                logStrictModeViolationToDropBox(r, info);
13039            }
13040        }
13041
13042        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13043            AppErrorResult result = new AppErrorResult();
13044            synchronized (this) {
13045                final long origId = Binder.clearCallingIdentity();
13046
13047                Message msg = Message.obtain();
13048                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13049                HashMap<String, Object> data = new HashMap<String, Object>();
13050                data.put("result", result);
13051                data.put("app", r);
13052                data.put("violationMask", violationMask);
13053                data.put("info", info);
13054                msg.obj = data;
13055                mUiHandler.sendMessage(msg);
13056
13057                Binder.restoreCallingIdentity(origId);
13058            }
13059            int res = result.get();
13060            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13061        }
13062    }
13063
13064    // Depending on the policy in effect, there could be a bunch of
13065    // these in quick succession so we try to batch these together to
13066    // minimize disk writes, number of dropbox entries, and maximize
13067    // compression, by having more fewer, larger records.
13068    private void logStrictModeViolationToDropBox(
13069            ProcessRecord process,
13070            StrictMode.ViolationInfo info) {
13071        if (info == null) {
13072            return;
13073        }
13074        final boolean isSystemApp = process == null ||
13075                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13076                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13077        final String processName = process == null ? "unknown" : process.processName;
13078        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13079        final DropBoxManager dbox = (DropBoxManager)
13080                mContext.getSystemService(Context.DROPBOX_SERVICE);
13081
13082        // Exit early if the dropbox isn't configured to accept this report type.
13083        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13084
13085        boolean bufferWasEmpty;
13086        boolean needsFlush;
13087        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13088        synchronized (sb) {
13089            bufferWasEmpty = sb.length() == 0;
13090            appendDropBoxProcessHeaders(process, processName, sb);
13091            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13092            sb.append("System-App: ").append(isSystemApp).append("\n");
13093            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13094            if (info.violationNumThisLoop != 0) {
13095                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13096            }
13097            if (info.numAnimationsRunning != 0) {
13098                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13099            }
13100            if (info.broadcastIntentAction != null) {
13101                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13102            }
13103            if (info.durationMillis != -1) {
13104                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13105            }
13106            if (info.numInstances != -1) {
13107                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13108            }
13109            if (info.tags != null) {
13110                for (String tag : info.tags) {
13111                    sb.append("Span-Tag: ").append(tag).append("\n");
13112                }
13113            }
13114            sb.append("\n");
13115            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13116                sb.append(info.crashInfo.stackTrace);
13117                sb.append("\n");
13118            }
13119            if (info.message != null) {
13120                sb.append(info.message);
13121                sb.append("\n");
13122            }
13123
13124            // Only buffer up to ~64k.  Various logging bits truncate
13125            // things at 128k.
13126            needsFlush = (sb.length() > 64 * 1024);
13127        }
13128
13129        // Flush immediately if the buffer's grown too large, or this
13130        // is a non-system app.  Non-system apps are isolated with a
13131        // different tag & policy and not batched.
13132        //
13133        // Batching is useful during internal testing with
13134        // StrictMode settings turned up high.  Without batching,
13135        // thousands of separate files could be created on boot.
13136        if (!isSystemApp || needsFlush) {
13137            new Thread("Error dump: " + dropboxTag) {
13138                @Override
13139                public void run() {
13140                    String report;
13141                    synchronized (sb) {
13142                        report = sb.toString();
13143                        sb.delete(0, sb.length());
13144                        sb.trimToSize();
13145                    }
13146                    if (report.length() != 0) {
13147                        dbox.addText(dropboxTag, report);
13148                    }
13149                }
13150            }.start();
13151            return;
13152        }
13153
13154        // System app batching:
13155        if (!bufferWasEmpty) {
13156            // An existing dropbox-writing thread is outstanding, so
13157            // we don't need to start it up.  The existing thread will
13158            // catch the buffer appends we just did.
13159            return;
13160        }
13161
13162        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13163        // (After this point, we shouldn't access AMS internal data structures.)
13164        new Thread("Error dump: " + dropboxTag) {
13165            @Override
13166            public void run() {
13167                // 5 second sleep to let stacks arrive and be batched together
13168                try {
13169                    Thread.sleep(5000);  // 5 seconds
13170                } catch (InterruptedException e) {}
13171
13172                String errorReport;
13173                synchronized (mStrictModeBuffer) {
13174                    errorReport = mStrictModeBuffer.toString();
13175                    if (errorReport.length() == 0) {
13176                        return;
13177                    }
13178                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13179                    mStrictModeBuffer.trimToSize();
13180                }
13181                dbox.addText(dropboxTag, errorReport);
13182            }
13183        }.start();
13184    }
13185
13186    /**
13187     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13188     * @param app object of the crashing app, null for the system server
13189     * @param tag reported by the caller
13190     * @param system whether this wtf is coming from the system
13191     * @param crashInfo describing the context of the error
13192     * @return true if the process should exit immediately (WTF is fatal)
13193     */
13194    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13195            final ApplicationErrorReport.CrashInfo crashInfo) {
13196        final int callingUid = Binder.getCallingUid();
13197        final int callingPid = Binder.getCallingPid();
13198
13199        if (system) {
13200            // If this is coming from the system, we could very well have low-level
13201            // system locks held, so we want to do this all asynchronously.  And we
13202            // never want this to become fatal, so there is that too.
13203            mHandler.post(new Runnable() {
13204                @Override public void run() {
13205                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13206                }
13207            });
13208            return false;
13209        }
13210
13211        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13212                crashInfo);
13213
13214        if (r != null && r.pid != Process.myPid() &&
13215                Settings.Global.getInt(mContext.getContentResolver(),
13216                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13217            mAppErrors.crashApplication(r, crashInfo);
13218            return true;
13219        } else {
13220            return false;
13221        }
13222    }
13223
13224    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13225            final ApplicationErrorReport.CrashInfo crashInfo) {
13226        final ProcessRecord r = findAppProcess(app, "WTF");
13227        final String processName = app == null ? "system_server"
13228                : (r == null ? "unknown" : r.processName);
13229
13230        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13231                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13232
13233        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13234
13235        return r;
13236    }
13237
13238    /**
13239     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13240     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13241     */
13242    private ProcessRecord findAppProcess(IBinder app, String reason) {
13243        if (app == null) {
13244            return null;
13245        }
13246
13247        synchronized (this) {
13248            final int NP = mProcessNames.getMap().size();
13249            for (int ip=0; ip<NP; ip++) {
13250                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13251                final int NA = apps.size();
13252                for (int ia=0; ia<NA; ia++) {
13253                    ProcessRecord p = apps.valueAt(ia);
13254                    if (p.thread != null && p.thread.asBinder() == app) {
13255                        return p;
13256                    }
13257                }
13258            }
13259
13260            Slog.w(TAG, "Can't find mystery application for " + reason
13261                    + " from pid=" + Binder.getCallingPid()
13262                    + " uid=" + Binder.getCallingUid() + ": " + app);
13263            return null;
13264        }
13265    }
13266
13267    /**
13268     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13269     * to append various headers to the dropbox log text.
13270     */
13271    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13272            StringBuilder sb) {
13273        // Watchdog thread ends up invoking this function (with
13274        // a null ProcessRecord) to add the stack file to dropbox.
13275        // Do not acquire a lock on this (am) in such cases, as it
13276        // could cause a potential deadlock, if and when watchdog
13277        // is invoked due to unavailability of lock on am and it
13278        // would prevent watchdog from killing system_server.
13279        if (process == null) {
13280            sb.append("Process: ").append(processName).append("\n");
13281            return;
13282        }
13283        // Note: ProcessRecord 'process' is guarded by the service
13284        // instance.  (notably process.pkgList, which could otherwise change
13285        // concurrently during execution of this method)
13286        synchronized (this) {
13287            sb.append("Process: ").append(processName).append("\n");
13288            int flags = process.info.flags;
13289            IPackageManager pm = AppGlobals.getPackageManager();
13290            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13291            for (int ip=0; ip<process.pkgList.size(); ip++) {
13292                String pkg = process.pkgList.keyAt(ip);
13293                sb.append("Package: ").append(pkg);
13294                try {
13295                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13296                    if (pi != null) {
13297                        sb.append(" v").append(pi.versionCode);
13298                        if (pi.versionName != null) {
13299                            sb.append(" (").append(pi.versionName).append(")");
13300                        }
13301                    }
13302                } catch (RemoteException e) {
13303                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13304                }
13305                sb.append("\n");
13306            }
13307        }
13308    }
13309
13310    private static String processClass(ProcessRecord process) {
13311        if (process == null || process.pid == MY_PID) {
13312            return "system_server";
13313        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13314            return "system_app";
13315        } else {
13316            return "data_app";
13317        }
13318    }
13319
13320    private volatile long mWtfClusterStart;
13321    private volatile int mWtfClusterCount;
13322
13323    /**
13324     * Write a description of an error (crash, WTF, ANR) to the drop box.
13325     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13326     * @param process which caused the error, null means the system server
13327     * @param activity which triggered the error, null if unknown
13328     * @param parent activity related to the error, null if unknown
13329     * @param subject line related to the error, null if absent
13330     * @param report in long form describing the error, null if absent
13331     * @param logFile to include in the report, null if none
13332     * @param crashInfo giving an application stack trace, null if absent
13333     */
13334    public void addErrorToDropBox(String eventType,
13335            ProcessRecord process, String processName, ActivityRecord activity,
13336            ActivityRecord parent, String subject,
13337            final String report, final File logFile,
13338            final ApplicationErrorReport.CrashInfo crashInfo) {
13339        // NOTE -- this must never acquire the ActivityManagerService lock,
13340        // otherwise the watchdog may be prevented from resetting the system.
13341
13342        final String dropboxTag = processClass(process) + "_" + eventType;
13343        final DropBoxManager dbox = (DropBoxManager)
13344                mContext.getSystemService(Context.DROPBOX_SERVICE);
13345
13346        // Exit early if the dropbox isn't configured to accept this report type.
13347        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13348
13349        // Rate-limit how often we're willing to do the heavy lifting below to
13350        // collect and record logs; currently 5 logs per 10 second period.
13351        final long now = SystemClock.elapsedRealtime();
13352        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13353            mWtfClusterStart = now;
13354            mWtfClusterCount = 1;
13355        } else {
13356            if (mWtfClusterCount++ >= 5) return;
13357        }
13358
13359        final StringBuilder sb = new StringBuilder(1024);
13360        appendDropBoxProcessHeaders(process, processName, sb);
13361        if (process != null) {
13362            sb.append("Foreground: ")
13363                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13364                    .append("\n");
13365        }
13366        if (activity != null) {
13367            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13368        }
13369        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13370            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13371        }
13372        if (parent != null && parent != activity) {
13373            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13374        }
13375        if (subject != null) {
13376            sb.append("Subject: ").append(subject).append("\n");
13377        }
13378        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13379        if (Debug.isDebuggerConnected()) {
13380            sb.append("Debugger: Connected\n");
13381        }
13382        sb.append("\n");
13383
13384        // Do the rest in a worker thread to avoid blocking the caller on I/O
13385        // (After this point, we shouldn't access AMS internal data structures.)
13386        Thread worker = new Thread("Error dump: " + dropboxTag) {
13387            @Override
13388            public void run() {
13389                if (report != null) {
13390                    sb.append(report);
13391                }
13392                if (logFile != null) {
13393                    try {
13394                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13395                                    "\n\n[[TRUNCATED]]"));
13396                    } catch (IOException e) {
13397                        Slog.e(TAG, "Error reading " + logFile, e);
13398                    }
13399                }
13400                if (crashInfo != null && crashInfo.stackTrace != null) {
13401                    sb.append(crashInfo.stackTrace);
13402                }
13403
13404                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13405                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13406                if (lines > 0) {
13407                    sb.append("\n");
13408
13409                    // Merge several logcat streams, and take the last N lines
13410                    InputStreamReader input = null;
13411                    try {
13412                        java.lang.Process logcat = new ProcessBuilder(
13413                                "/system/bin/timeout", "-k", "15s", "10s",
13414                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13415                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13416                                        .redirectErrorStream(true).start();
13417
13418                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13419                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13420                        input = new InputStreamReader(logcat.getInputStream());
13421
13422                        int num;
13423                        char[] buf = new char[8192];
13424                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13425                    } catch (IOException e) {
13426                        Slog.e(TAG, "Error running logcat", e);
13427                    } finally {
13428                        if (input != null) try { input.close(); } catch (IOException e) {}
13429                    }
13430                }
13431
13432                dbox.addText(dropboxTag, sb.toString());
13433            }
13434        };
13435
13436        if (process == null) {
13437            // If process is null, we are being called from some internal code
13438            // and may be about to die -- run this synchronously.
13439            worker.run();
13440        } else {
13441            worker.start();
13442        }
13443    }
13444
13445    @Override
13446    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13447        enforceNotIsolatedCaller("getProcessesInErrorState");
13448        // assume our apps are happy - lazy create the list
13449        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13450
13451        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13452                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13453        int userId = UserHandle.getUserId(Binder.getCallingUid());
13454
13455        synchronized (this) {
13456
13457            // iterate across all processes
13458            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13459                ProcessRecord app = mLruProcesses.get(i);
13460                if (!allUsers && app.userId != userId) {
13461                    continue;
13462                }
13463                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13464                    // This one's in trouble, so we'll generate a report for it
13465                    // crashes are higher priority (in case there's a crash *and* an anr)
13466                    ActivityManager.ProcessErrorStateInfo report = null;
13467                    if (app.crashing) {
13468                        report = app.crashingReport;
13469                    } else if (app.notResponding) {
13470                        report = app.notRespondingReport;
13471                    }
13472
13473                    if (report != null) {
13474                        if (errList == null) {
13475                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13476                        }
13477                        errList.add(report);
13478                    } else {
13479                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13480                                " crashing = " + app.crashing +
13481                                " notResponding = " + app.notResponding);
13482                    }
13483                }
13484            }
13485        }
13486
13487        return errList;
13488    }
13489
13490    static int procStateToImportance(int procState, int memAdj,
13491            ActivityManager.RunningAppProcessInfo currApp) {
13492        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13493        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13494            currApp.lru = memAdj;
13495        } else {
13496            currApp.lru = 0;
13497        }
13498        return imp;
13499    }
13500
13501    private void fillInProcMemInfo(ProcessRecord app,
13502            ActivityManager.RunningAppProcessInfo outInfo) {
13503        outInfo.pid = app.pid;
13504        outInfo.uid = app.info.uid;
13505        if (mHeavyWeightProcess == app) {
13506            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13507        }
13508        if (app.persistent) {
13509            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13510        }
13511        if (app.activities.size() > 0) {
13512            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13513        }
13514        outInfo.lastTrimLevel = app.trimMemoryLevel;
13515        int adj = app.curAdj;
13516        int procState = app.curProcState;
13517        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13518        outInfo.importanceReasonCode = app.adjTypeCode;
13519        outInfo.processState = app.curProcState;
13520    }
13521
13522    @Override
13523    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13524        enforceNotIsolatedCaller("getRunningAppProcesses");
13525
13526        final int callingUid = Binder.getCallingUid();
13527
13528        // Lazy instantiation of list
13529        List<ActivityManager.RunningAppProcessInfo> runList = null;
13530        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13531                callingUid) == PackageManager.PERMISSION_GRANTED;
13532        final int userId = UserHandle.getUserId(callingUid);
13533        final boolean allUids = isGetTasksAllowed(
13534                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13535
13536        synchronized (this) {
13537            // Iterate across all processes
13538            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13539                ProcessRecord app = mLruProcesses.get(i);
13540                if ((!allUsers && app.userId != userId)
13541                        || (!allUids && app.uid != callingUid)) {
13542                    continue;
13543                }
13544                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13545                    // Generate process state info for running application
13546                    ActivityManager.RunningAppProcessInfo currApp =
13547                        new ActivityManager.RunningAppProcessInfo(app.processName,
13548                                app.pid, app.getPackageList());
13549                    fillInProcMemInfo(app, currApp);
13550                    if (app.adjSource instanceof ProcessRecord) {
13551                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13552                        currApp.importanceReasonImportance =
13553                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13554                                        app.adjSourceProcState);
13555                    } else if (app.adjSource instanceof ActivityRecord) {
13556                        ActivityRecord r = (ActivityRecord)app.adjSource;
13557                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13558                    }
13559                    if (app.adjTarget instanceof ComponentName) {
13560                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13561                    }
13562                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13563                    //        + " lru=" + currApp.lru);
13564                    if (runList == null) {
13565                        runList = new ArrayList<>();
13566                    }
13567                    runList.add(currApp);
13568                }
13569            }
13570        }
13571        return runList;
13572    }
13573
13574    @Override
13575    public List<ApplicationInfo> getRunningExternalApplications() {
13576        enforceNotIsolatedCaller("getRunningExternalApplications");
13577        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13578        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13579        if (runningApps != null && runningApps.size() > 0) {
13580            Set<String> extList = new HashSet<String>();
13581            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13582                if (app.pkgList != null) {
13583                    for (String pkg : app.pkgList) {
13584                        extList.add(pkg);
13585                    }
13586                }
13587            }
13588            IPackageManager pm = AppGlobals.getPackageManager();
13589            for (String pkg : extList) {
13590                try {
13591                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13592                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13593                        retList.add(info);
13594                    }
13595                } catch (RemoteException e) {
13596                }
13597            }
13598        }
13599        return retList;
13600    }
13601
13602    @Override
13603    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13604        enforceNotIsolatedCaller("getMyMemoryState");
13605        synchronized (this) {
13606            ProcessRecord proc;
13607            synchronized (mPidsSelfLocked) {
13608                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13609            }
13610            fillInProcMemInfo(proc, outInfo);
13611        }
13612    }
13613
13614    @Override
13615    public int getMemoryTrimLevel() {
13616        enforceNotIsolatedCaller("getMyMemoryState");
13617        synchronized (this) {
13618            return mLastMemoryLevel;
13619        }
13620    }
13621
13622    @Override
13623    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13624            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13625        (new ActivityManagerShellCommand(this, false)).exec(
13626                this, in, out, err, args, resultReceiver);
13627    }
13628
13629    @Override
13630    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13631        if (checkCallingPermission(android.Manifest.permission.DUMP)
13632                != PackageManager.PERMISSION_GRANTED) {
13633            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13634                    + Binder.getCallingPid()
13635                    + ", uid=" + Binder.getCallingUid()
13636                    + " without permission "
13637                    + android.Manifest.permission.DUMP);
13638            return;
13639        }
13640
13641        boolean dumpAll = false;
13642        boolean dumpClient = false;
13643        String dumpPackage = null;
13644
13645        int opti = 0;
13646        while (opti < args.length) {
13647            String opt = args[opti];
13648            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13649                break;
13650            }
13651            opti++;
13652            if ("-a".equals(opt)) {
13653                dumpAll = true;
13654            } else if ("-c".equals(opt)) {
13655                dumpClient = true;
13656            } else if ("-p".equals(opt)) {
13657                if (opti < args.length) {
13658                    dumpPackage = args[opti];
13659                    opti++;
13660                } else {
13661                    pw.println("Error: -p option requires package argument");
13662                    return;
13663                }
13664                dumpClient = true;
13665            } else if ("-h".equals(opt)) {
13666                ActivityManagerShellCommand.dumpHelp(pw, true);
13667                return;
13668            } else {
13669                pw.println("Unknown argument: " + opt + "; use -h for help");
13670            }
13671        }
13672
13673        long origId = Binder.clearCallingIdentity();
13674        boolean more = false;
13675        // Is the caller requesting to dump a particular piece of data?
13676        if (opti < args.length) {
13677            String cmd = args[opti];
13678            opti++;
13679            if ("activities".equals(cmd) || "a".equals(cmd)) {
13680                synchronized (this) {
13681                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13682                }
13683            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13684                synchronized (this) {
13685                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13686                }
13687            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13688                String[] newArgs;
13689                String name;
13690                if (opti >= args.length) {
13691                    name = null;
13692                    newArgs = EMPTY_STRING_ARRAY;
13693                } else {
13694                    dumpPackage = args[opti];
13695                    opti++;
13696                    newArgs = new String[args.length - opti];
13697                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13698                            args.length - opti);
13699                }
13700                synchronized (this) {
13701                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13702                }
13703            } else if ("intents".equals(cmd) || "i".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                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13718                }
13719            } else if ("processes".equals(cmd) || "p".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                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13734                }
13735            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13736                synchronized (this) {
13737                    dumpOomLocked(fd, pw, args, opti, true);
13738                }
13739            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13740                synchronized (this) {
13741                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13742                }
13743            } else if ("provider".equals(cmd)) {
13744                String[] newArgs;
13745                String name;
13746                if (opti >= args.length) {
13747                    name = null;
13748                    newArgs = EMPTY_STRING_ARRAY;
13749                } else {
13750                    name = args[opti];
13751                    opti++;
13752                    newArgs = new String[args.length - opti];
13753                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13754                }
13755                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13756                    pw.println("No providers match: " + name);
13757                    pw.println("Use -h for help.");
13758                }
13759            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13760                synchronized (this) {
13761                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13762                }
13763            } else if ("service".equals(cmd)) {
13764                String[] newArgs;
13765                String name;
13766                if (opti >= args.length) {
13767                    name = null;
13768                    newArgs = EMPTY_STRING_ARRAY;
13769                } else {
13770                    name = args[opti];
13771                    opti++;
13772                    newArgs = new String[args.length - opti];
13773                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13774                            args.length - opti);
13775                }
13776                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13777                    pw.println("No services match: " + name);
13778                    pw.println("Use -h for help.");
13779                }
13780            } else if ("package".equals(cmd)) {
13781                String[] newArgs;
13782                if (opti >= args.length) {
13783                    pw.println("package: no package name specified");
13784                    pw.println("Use -h for help.");
13785                } else {
13786                    dumpPackage = 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                    args = newArgs;
13792                    opti = 0;
13793                    more = true;
13794                }
13795            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13796                synchronized (this) {
13797                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13798                }
13799            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13800                synchronized (this) {
13801                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13802                }
13803            } else if ("locks".equals(cmd)) {
13804                LockGuard.dump(fd, pw, args);
13805            } else {
13806                // Dumping a single activity?
13807                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13808                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13809                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13810                    if (res < 0) {
13811                        pw.println("Bad activity command, or no activities match: " + cmd);
13812                        pw.println("Use -h for help.");
13813                    }
13814                }
13815            }
13816            if (!more) {
13817                Binder.restoreCallingIdentity(origId);
13818                return;
13819            }
13820        }
13821
13822        // No piece of data specified, dump everything.
13823        synchronized (this) {
13824            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13825            pw.println();
13826            if (dumpAll) {
13827                pw.println("-------------------------------------------------------------------------------");
13828            }
13829            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13830            pw.println();
13831            if (dumpAll) {
13832                pw.println("-------------------------------------------------------------------------------");
13833            }
13834            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13835            pw.println();
13836            if (dumpAll) {
13837                pw.println("-------------------------------------------------------------------------------");
13838            }
13839            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13840            pw.println();
13841            if (dumpAll) {
13842                pw.println("-------------------------------------------------------------------------------");
13843            }
13844            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13845            pw.println();
13846            if (dumpAll) {
13847                pw.println("-------------------------------------------------------------------------------");
13848            }
13849            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13850            pw.println();
13851            if (dumpAll) {
13852                pw.println("-------------------------------------------------------------------------------");
13853            }
13854            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13855            if (mAssociations.size() > 0) {
13856                pw.println();
13857                if (dumpAll) {
13858                    pw.println("-------------------------------------------------------------------------------");
13859                }
13860                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13861            }
13862            pw.println();
13863            if (dumpAll) {
13864                pw.println("-------------------------------------------------------------------------------");
13865            }
13866            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13867        }
13868        Binder.restoreCallingIdentity(origId);
13869    }
13870
13871    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13872            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13873        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13874
13875        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13876                dumpPackage);
13877        boolean needSep = printedAnything;
13878
13879        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13880                dumpPackage, needSep, "  mFocusedActivity: ");
13881        if (printed) {
13882            printedAnything = true;
13883            needSep = false;
13884        }
13885
13886        if (dumpPackage == null) {
13887            if (needSep) {
13888                pw.println();
13889            }
13890            needSep = true;
13891            printedAnything = true;
13892            mStackSupervisor.dump(pw, "  ");
13893        }
13894
13895        if (!printedAnything) {
13896            pw.println("  (nothing)");
13897        }
13898    }
13899
13900    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13901            int opti, boolean dumpAll, String dumpPackage) {
13902        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13903
13904        boolean printedAnything = false;
13905
13906        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13907            boolean printedHeader = false;
13908
13909            final int N = mRecentTasks.size();
13910            for (int i=0; i<N; i++) {
13911                TaskRecord tr = mRecentTasks.get(i);
13912                if (dumpPackage != null) {
13913                    if (tr.realActivity == null ||
13914                            !dumpPackage.equals(tr.realActivity)) {
13915                        continue;
13916                    }
13917                }
13918                if (!printedHeader) {
13919                    pw.println("  Recent tasks:");
13920                    printedHeader = true;
13921                    printedAnything = true;
13922                }
13923                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13924                        pw.println(tr);
13925                if (dumpAll) {
13926                    mRecentTasks.get(i).dump(pw, "    ");
13927                }
13928            }
13929        }
13930
13931        if (!printedAnything) {
13932            pw.println("  (nothing)");
13933        }
13934    }
13935
13936    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13937            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13938        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13939
13940        int dumpUid = 0;
13941        if (dumpPackage != null) {
13942            IPackageManager pm = AppGlobals.getPackageManager();
13943            try {
13944                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13945            } catch (RemoteException e) {
13946            }
13947        }
13948
13949        boolean printedAnything = false;
13950
13951        final long now = SystemClock.uptimeMillis();
13952
13953        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13954            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13955                    = mAssociations.valueAt(i1);
13956            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13957                SparseArray<ArrayMap<String, Association>> sourceUids
13958                        = targetComponents.valueAt(i2);
13959                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13960                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13961                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13962                        Association ass = sourceProcesses.valueAt(i4);
13963                        if (dumpPackage != null) {
13964                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13965                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13966                                continue;
13967                            }
13968                        }
13969                        printedAnything = true;
13970                        pw.print("  ");
13971                        pw.print(ass.mTargetProcess);
13972                        pw.print("/");
13973                        UserHandle.formatUid(pw, ass.mTargetUid);
13974                        pw.print(" <- ");
13975                        pw.print(ass.mSourceProcess);
13976                        pw.print("/");
13977                        UserHandle.formatUid(pw, ass.mSourceUid);
13978                        pw.println();
13979                        pw.print("    via ");
13980                        pw.print(ass.mTargetComponent.flattenToShortString());
13981                        pw.println();
13982                        pw.print("    ");
13983                        long dur = ass.mTime;
13984                        if (ass.mNesting > 0) {
13985                            dur += now - ass.mStartTime;
13986                        }
13987                        TimeUtils.formatDuration(dur, pw);
13988                        pw.print(" (");
13989                        pw.print(ass.mCount);
13990                        pw.print(" times)");
13991                        pw.print("  ");
13992                        for (int i=0; i<ass.mStateTimes.length; i++) {
13993                            long amt = ass.mStateTimes[i];
13994                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13995                                amt += now - ass.mLastStateUptime;
13996                            }
13997                            if (amt != 0) {
13998                                pw.print(" ");
13999                                pw.print(ProcessList.makeProcStateString(
14000                                            i + ActivityManager.MIN_PROCESS_STATE));
14001                                pw.print("=");
14002                                TimeUtils.formatDuration(amt, pw);
14003                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14004                                    pw.print("*");
14005                                }
14006                            }
14007                        }
14008                        pw.println();
14009                        if (ass.mNesting > 0) {
14010                            pw.print("    Currently active: ");
14011                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14012                            pw.println();
14013                        }
14014                    }
14015                }
14016            }
14017
14018        }
14019
14020        if (!printedAnything) {
14021            pw.println("  (nothing)");
14022        }
14023    }
14024
14025    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14026            String header, boolean needSep) {
14027        boolean printed = false;
14028        int whichAppId = -1;
14029        if (dumpPackage != null) {
14030            try {
14031                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14032                        dumpPackage, 0);
14033                whichAppId = UserHandle.getAppId(info.uid);
14034            } catch (NameNotFoundException e) {
14035                e.printStackTrace();
14036            }
14037        }
14038        for (int i=0; i<uids.size(); i++) {
14039            UidRecord uidRec = uids.valueAt(i);
14040            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14041                continue;
14042            }
14043            if (!printed) {
14044                printed = true;
14045                if (needSep) {
14046                    pw.println();
14047                }
14048                pw.print("  ");
14049                pw.println(header);
14050                needSep = true;
14051            }
14052            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14053            pw.print(": "); pw.println(uidRec);
14054        }
14055        return printed;
14056    }
14057
14058    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14059            int opti, boolean dumpAll, String dumpPackage) {
14060        boolean needSep = false;
14061        boolean printedAnything = false;
14062        int numPers = 0;
14063
14064        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14065
14066        if (dumpAll) {
14067            final int NP = mProcessNames.getMap().size();
14068            for (int ip=0; ip<NP; ip++) {
14069                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14070                final int NA = procs.size();
14071                for (int ia=0; ia<NA; ia++) {
14072                    ProcessRecord r = procs.valueAt(ia);
14073                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14074                        continue;
14075                    }
14076                    if (!needSep) {
14077                        pw.println("  All known processes:");
14078                        needSep = true;
14079                        printedAnything = true;
14080                    }
14081                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14082                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14083                        pw.print(" "); pw.println(r);
14084                    r.dump(pw, "    ");
14085                    if (r.persistent) {
14086                        numPers++;
14087                    }
14088                }
14089            }
14090        }
14091
14092        if (mIsolatedProcesses.size() > 0) {
14093            boolean printed = false;
14094            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14095                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14096                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14097                    continue;
14098                }
14099                if (!printed) {
14100                    if (needSep) {
14101                        pw.println();
14102                    }
14103                    pw.println("  Isolated process list (sorted by uid):");
14104                    printedAnything = true;
14105                    printed = true;
14106                    needSep = true;
14107                }
14108                pw.println(String.format("%sIsolated #%2d: %s",
14109                        "    ", i, r.toString()));
14110            }
14111        }
14112
14113        if (mActiveUids.size() > 0) {
14114            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14115                printedAnything = needSep = true;
14116            }
14117        }
14118        if (mValidateUids.size() > 0) {
14119            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14120                printedAnything = needSep = true;
14121            }
14122        }
14123
14124        if (mLruProcesses.size() > 0) {
14125            if (needSep) {
14126                pw.println();
14127            }
14128            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14129                    pw.print(" total, non-act at ");
14130                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14131                    pw.print(", non-svc at ");
14132                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14133                    pw.println("):");
14134            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14135            needSep = true;
14136            printedAnything = true;
14137        }
14138
14139        if (dumpAll || dumpPackage != null) {
14140            synchronized (mPidsSelfLocked) {
14141                boolean printed = false;
14142                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14143                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14144                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14145                        continue;
14146                    }
14147                    if (!printed) {
14148                        if (needSep) pw.println();
14149                        needSep = true;
14150                        pw.println("  PID mappings:");
14151                        printed = true;
14152                        printedAnything = true;
14153                    }
14154                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14155                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14156                }
14157            }
14158        }
14159
14160        if (mForegroundProcesses.size() > 0) {
14161            synchronized (mPidsSelfLocked) {
14162                boolean printed = false;
14163                for (int i=0; i<mForegroundProcesses.size(); i++) {
14164                    ProcessRecord r = mPidsSelfLocked.get(
14165                            mForegroundProcesses.valueAt(i).pid);
14166                    if (dumpPackage != null && (r == null
14167                            || !r.pkgList.containsKey(dumpPackage))) {
14168                        continue;
14169                    }
14170                    if (!printed) {
14171                        if (needSep) pw.println();
14172                        needSep = true;
14173                        pw.println("  Foreground Processes:");
14174                        printed = true;
14175                        printedAnything = true;
14176                    }
14177                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14178                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14179                }
14180            }
14181        }
14182
14183        if (mPersistentStartingProcesses.size() > 0) {
14184            if (needSep) pw.println();
14185            needSep = true;
14186            printedAnything = true;
14187            pw.println("  Persisent processes that are starting:");
14188            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14189                    "Starting Norm", "Restarting PERS", dumpPackage);
14190        }
14191
14192        if (mRemovedProcesses.size() > 0) {
14193            if (needSep) pw.println();
14194            needSep = true;
14195            printedAnything = true;
14196            pw.println("  Processes that are being removed:");
14197            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14198                    "Removed Norm", "Removed PERS", dumpPackage);
14199        }
14200
14201        if (mProcessesOnHold.size() > 0) {
14202            if (needSep) pw.println();
14203            needSep = true;
14204            printedAnything = true;
14205            pw.println("  Processes that are on old until the system is ready:");
14206            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14207                    "OnHold Norm", "OnHold PERS", dumpPackage);
14208        }
14209
14210        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14211
14212        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14213        if (needSep) {
14214            printedAnything = true;
14215        }
14216
14217        if (dumpPackage == null) {
14218            pw.println();
14219            needSep = false;
14220            mUserController.dump(pw, dumpAll);
14221        }
14222        if (mHomeProcess != null && (dumpPackage == null
14223                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14224            if (needSep) {
14225                pw.println();
14226                needSep = false;
14227            }
14228            pw.println("  mHomeProcess: " + mHomeProcess);
14229        }
14230        if (mPreviousProcess != null && (dumpPackage == null
14231                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14232            if (needSep) {
14233                pw.println();
14234                needSep = false;
14235            }
14236            pw.println("  mPreviousProcess: " + mPreviousProcess);
14237        }
14238        if (dumpAll) {
14239            StringBuilder sb = new StringBuilder(128);
14240            sb.append("  mPreviousProcessVisibleTime: ");
14241            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14242            pw.println(sb);
14243        }
14244        if (mHeavyWeightProcess != null && (dumpPackage == null
14245                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14246            if (needSep) {
14247                pw.println();
14248                needSep = false;
14249            }
14250            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14251        }
14252        if (dumpPackage == null) {
14253            pw.println("  mConfiguration: " + mConfiguration);
14254        }
14255        if (dumpAll) {
14256            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14257            if (mCompatModePackages.getPackages().size() > 0) {
14258                boolean printed = false;
14259                for (Map.Entry<String, Integer> entry
14260                        : mCompatModePackages.getPackages().entrySet()) {
14261                    String pkg = entry.getKey();
14262                    int mode = entry.getValue();
14263                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14264                        continue;
14265                    }
14266                    if (!printed) {
14267                        pw.println("  mScreenCompatPackages:");
14268                        printed = true;
14269                    }
14270                    pw.print("    "); pw.print(pkg); pw.print(": ");
14271                            pw.print(mode); pw.println();
14272                }
14273            }
14274        }
14275        if (dumpPackage == null) {
14276            pw.println("  mWakefulness="
14277                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14278            pw.println("  mSleepTokens=" + mSleepTokens);
14279            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14280                    + lockScreenShownToString());
14281            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14282            if (mRunningVoice != null) {
14283                pw.println("  mRunningVoice=" + mRunningVoice);
14284                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14285            }
14286        }
14287        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14288                || mOrigWaitForDebugger) {
14289            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14290                    || dumpPackage.equals(mOrigDebugApp)) {
14291                if (needSep) {
14292                    pw.println();
14293                    needSep = false;
14294                }
14295                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14296                        + " mDebugTransient=" + mDebugTransient
14297                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14298            }
14299        }
14300        if (mCurAppTimeTracker != null) {
14301            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14302        }
14303        if (mMemWatchProcesses.getMap().size() > 0) {
14304            pw.println("  Mem watch processes:");
14305            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14306                    = mMemWatchProcesses.getMap();
14307            for (int i=0; i<procs.size(); i++) {
14308                final String proc = procs.keyAt(i);
14309                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14310                for (int j=0; j<uids.size(); j++) {
14311                    if (needSep) {
14312                        pw.println();
14313                        needSep = false;
14314                    }
14315                    StringBuilder sb = new StringBuilder();
14316                    sb.append("    ").append(proc).append('/');
14317                    UserHandle.formatUid(sb, uids.keyAt(j));
14318                    Pair<Long, String> val = uids.valueAt(j);
14319                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14320                    if (val.second != null) {
14321                        sb.append(", report to ").append(val.second);
14322                    }
14323                    pw.println(sb.toString());
14324                }
14325            }
14326            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14327            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14328            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14329                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14330        }
14331        if (mTrackAllocationApp != null) {
14332            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14333                if (needSep) {
14334                    pw.println();
14335                    needSep = false;
14336                }
14337                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14338            }
14339        }
14340        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14341                || mProfileFd != null) {
14342            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14343                if (needSep) {
14344                    pw.println();
14345                    needSep = false;
14346                }
14347                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14348                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14349                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14350                        + mAutoStopProfiler);
14351                pw.println("  mProfileType=" + mProfileType);
14352            }
14353        }
14354        if (mNativeDebuggingApp != null) {
14355            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14356                if (needSep) {
14357                    pw.println();
14358                    needSep = false;
14359                }
14360                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14361            }
14362        }
14363        if (dumpPackage == null) {
14364            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14365                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14366                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14367            }
14368            if (mController != null) {
14369                pw.println("  mController=" + mController
14370                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14371            }
14372            if (dumpAll) {
14373                pw.println("  Total persistent processes: " + numPers);
14374                pw.println("  mProcessesReady=" + mProcessesReady
14375                        + " mSystemReady=" + mSystemReady
14376                        + " mBooted=" + mBooted
14377                        + " mFactoryTest=" + mFactoryTest);
14378                pw.println("  mBooting=" + mBooting
14379                        + " mCallFinishBooting=" + mCallFinishBooting
14380                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14381                pw.print("  mLastPowerCheckRealtime=");
14382                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14383                        pw.println("");
14384                pw.print("  mLastPowerCheckUptime=");
14385                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14386                        pw.println("");
14387                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14388                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14389                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14390                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14391                        + " (" + mLruProcesses.size() + " total)"
14392                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14393                        + " mNumServiceProcs=" + mNumServiceProcs
14394                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14395                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14396                        + " mLastMemoryLevel=" + mLastMemoryLevel
14397                        + " mLastNumProcesses=" + mLastNumProcesses);
14398                long now = SystemClock.uptimeMillis();
14399                pw.print("  mLastIdleTime=");
14400                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14401                        pw.print(" mLowRamSinceLastIdle=");
14402                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14403                        pw.println();
14404            }
14405        }
14406
14407        if (!printedAnything) {
14408            pw.println("  (nothing)");
14409        }
14410    }
14411
14412    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14413            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14414        if (mProcessesToGc.size() > 0) {
14415            boolean printed = false;
14416            long now = SystemClock.uptimeMillis();
14417            for (int i=0; i<mProcessesToGc.size(); i++) {
14418                ProcessRecord proc = mProcessesToGc.get(i);
14419                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14420                    continue;
14421                }
14422                if (!printed) {
14423                    if (needSep) pw.println();
14424                    needSep = true;
14425                    pw.println("  Processes that are waiting to GC:");
14426                    printed = true;
14427                }
14428                pw.print("    Process "); pw.println(proc);
14429                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14430                        pw.print(", last gced=");
14431                        pw.print(now-proc.lastRequestedGc);
14432                        pw.print(" ms ago, last lowMem=");
14433                        pw.print(now-proc.lastLowMemory);
14434                        pw.println(" ms ago");
14435
14436            }
14437        }
14438        return needSep;
14439    }
14440
14441    void printOomLevel(PrintWriter pw, String name, int adj) {
14442        pw.print("    ");
14443        if (adj >= 0) {
14444            pw.print(' ');
14445            if (adj < 10) pw.print(' ');
14446        } else {
14447            if (adj > -10) pw.print(' ');
14448        }
14449        pw.print(adj);
14450        pw.print(": ");
14451        pw.print(name);
14452        pw.print(" (");
14453        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14454        pw.println(")");
14455    }
14456
14457    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14458            int opti, boolean dumpAll) {
14459        boolean needSep = false;
14460
14461        if (mLruProcesses.size() > 0) {
14462            if (needSep) pw.println();
14463            needSep = true;
14464            pw.println("  OOM levels:");
14465            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14466            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14467            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14468            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14469            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14470            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14471            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14472            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14473            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14474            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14475            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14476            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14477            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14478            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14479
14480            if (needSep) pw.println();
14481            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14482                    pw.print(" total, non-act at ");
14483                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14484                    pw.print(", non-svc at ");
14485                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14486                    pw.println("):");
14487            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14488            needSep = true;
14489        }
14490
14491        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14492
14493        pw.println();
14494        pw.println("  mHomeProcess: " + mHomeProcess);
14495        pw.println("  mPreviousProcess: " + mPreviousProcess);
14496        if (mHeavyWeightProcess != null) {
14497            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14498        }
14499
14500        return true;
14501    }
14502
14503    /**
14504     * There are three ways to call this:
14505     *  - no provider specified: dump all the providers
14506     *  - a flattened component name that matched an existing provider was specified as the
14507     *    first arg: dump that one provider
14508     *  - the first arg isn't the flattened component name of an existing provider:
14509     *    dump all providers whose component contains the first arg as a substring
14510     */
14511    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14512            int opti, boolean dumpAll) {
14513        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14514    }
14515
14516    static class ItemMatcher {
14517        ArrayList<ComponentName> components;
14518        ArrayList<String> strings;
14519        ArrayList<Integer> objects;
14520        boolean all;
14521
14522        ItemMatcher() {
14523            all = true;
14524        }
14525
14526        void build(String name) {
14527            ComponentName componentName = ComponentName.unflattenFromString(name);
14528            if (componentName != null) {
14529                if (components == null) {
14530                    components = new ArrayList<ComponentName>();
14531                }
14532                components.add(componentName);
14533                all = false;
14534            } else {
14535                int objectId = 0;
14536                // Not a '/' separated full component name; maybe an object ID?
14537                try {
14538                    objectId = Integer.parseInt(name, 16);
14539                    if (objects == null) {
14540                        objects = new ArrayList<Integer>();
14541                    }
14542                    objects.add(objectId);
14543                    all = false;
14544                } catch (RuntimeException e) {
14545                    // Not an integer; just do string match.
14546                    if (strings == null) {
14547                        strings = new ArrayList<String>();
14548                    }
14549                    strings.add(name);
14550                    all = false;
14551                }
14552            }
14553        }
14554
14555        int build(String[] args, int opti) {
14556            for (; opti<args.length; opti++) {
14557                String name = args[opti];
14558                if ("--".equals(name)) {
14559                    return opti+1;
14560                }
14561                build(name);
14562            }
14563            return opti;
14564        }
14565
14566        boolean match(Object object, ComponentName comp) {
14567            if (all) {
14568                return true;
14569            }
14570            if (components != null) {
14571                for (int i=0; i<components.size(); i++) {
14572                    if (components.get(i).equals(comp)) {
14573                        return true;
14574                    }
14575                }
14576            }
14577            if (objects != null) {
14578                for (int i=0; i<objects.size(); i++) {
14579                    if (System.identityHashCode(object) == objects.get(i)) {
14580                        return true;
14581                    }
14582                }
14583            }
14584            if (strings != null) {
14585                String flat = comp.flattenToString();
14586                for (int i=0; i<strings.size(); i++) {
14587                    if (flat.contains(strings.get(i))) {
14588                        return true;
14589                    }
14590                }
14591            }
14592            return false;
14593        }
14594    }
14595
14596    /**
14597     * There are three things that cmd can be:
14598     *  - a flattened component name that matches an existing activity
14599     *  - the cmd arg isn't the flattened component name of an existing activity:
14600     *    dump all activity whose component contains the cmd as a substring
14601     *  - A hex number of the ActivityRecord object instance.
14602     */
14603    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14604            int opti, boolean dumpAll) {
14605        ArrayList<ActivityRecord> activities;
14606
14607        synchronized (this) {
14608            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14609        }
14610
14611        if (activities.size() <= 0) {
14612            return false;
14613        }
14614
14615        String[] newArgs = new String[args.length - opti];
14616        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14617
14618        TaskRecord lastTask = null;
14619        boolean needSep = false;
14620        for (int i=activities.size()-1; i>=0; i--) {
14621            ActivityRecord r = activities.get(i);
14622            if (needSep) {
14623                pw.println();
14624            }
14625            needSep = true;
14626            synchronized (this) {
14627                if (lastTask != r.task) {
14628                    lastTask = r.task;
14629                    pw.print("TASK "); pw.print(lastTask.affinity);
14630                            pw.print(" id="); pw.println(lastTask.taskId);
14631                    if (dumpAll) {
14632                        lastTask.dump(pw, "  ");
14633                    }
14634                }
14635            }
14636            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14637        }
14638        return true;
14639    }
14640
14641    /**
14642     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14643     * there is a thread associated with the activity.
14644     */
14645    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14646            final ActivityRecord r, String[] args, boolean dumpAll) {
14647        String innerPrefix = prefix + "  ";
14648        synchronized (this) {
14649            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14650                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14651                    pw.print(" pid=");
14652                    if (r.app != null) pw.println(r.app.pid);
14653                    else pw.println("(not running)");
14654            if (dumpAll) {
14655                r.dump(pw, innerPrefix);
14656            }
14657        }
14658        if (r.app != null && r.app.thread != null) {
14659            // flush anything that is already in the PrintWriter since the thread is going
14660            // to write to the file descriptor directly
14661            pw.flush();
14662            try {
14663                TransferPipe tp = new TransferPipe();
14664                try {
14665                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14666                            r.appToken, innerPrefix, args);
14667                    tp.go(fd);
14668                } finally {
14669                    tp.kill();
14670                }
14671            } catch (IOException e) {
14672                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14673            } catch (RemoteException e) {
14674                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14675            }
14676        }
14677    }
14678
14679    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14680            int opti, boolean dumpAll, String dumpPackage) {
14681        boolean needSep = false;
14682        boolean onlyHistory = false;
14683        boolean printedAnything = false;
14684
14685        if ("history".equals(dumpPackage)) {
14686            if (opti < args.length && "-s".equals(args[opti])) {
14687                dumpAll = false;
14688            }
14689            onlyHistory = true;
14690            dumpPackage = null;
14691        }
14692
14693        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14694        if (!onlyHistory && dumpAll) {
14695            if (mRegisteredReceivers.size() > 0) {
14696                boolean printed = false;
14697                Iterator it = mRegisteredReceivers.values().iterator();
14698                while (it.hasNext()) {
14699                    ReceiverList r = (ReceiverList)it.next();
14700                    if (dumpPackage != null && (r.app == null ||
14701                            !dumpPackage.equals(r.app.info.packageName))) {
14702                        continue;
14703                    }
14704                    if (!printed) {
14705                        pw.println("  Registered Receivers:");
14706                        needSep = true;
14707                        printed = true;
14708                        printedAnything = true;
14709                    }
14710                    pw.print("  * "); pw.println(r);
14711                    r.dump(pw, "    ");
14712                }
14713            }
14714
14715            if (mReceiverResolver.dump(pw, needSep ?
14716                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14717                    "    ", dumpPackage, false, false)) {
14718                needSep = true;
14719                printedAnything = true;
14720            }
14721        }
14722
14723        for (BroadcastQueue q : mBroadcastQueues) {
14724            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14725            printedAnything |= needSep;
14726        }
14727
14728        needSep = true;
14729
14730        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14731            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14732                if (needSep) {
14733                    pw.println();
14734                }
14735                needSep = true;
14736                printedAnything = true;
14737                pw.print("  Sticky broadcasts for user ");
14738                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14739                StringBuilder sb = new StringBuilder(128);
14740                for (Map.Entry<String, ArrayList<Intent>> ent
14741                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14742                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14743                    if (dumpAll) {
14744                        pw.println(":");
14745                        ArrayList<Intent> intents = ent.getValue();
14746                        final int N = intents.size();
14747                        for (int i=0; i<N; i++) {
14748                            sb.setLength(0);
14749                            sb.append("    Intent: ");
14750                            intents.get(i).toShortString(sb, false, true, false, false);
14751                            pw.println(sb.toString());
14752                            Bundle bundle = intents.get(i).getExtras();
14753                            if (bundle != null) {
14754                                pw.print("      ");
14755                                pw.println(bundle.toString());
14756                            }
14757                        }
14758                    } else {
14759                        pw.println("");
14760                    }
14761                }
14762            }
14763        }
14764
14765        if (!onlyHistory && dumpAll) {
14766            pw.println();
14767            for (BroadcastQueue queue : mBroadcastQueues) {
14768                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14769                        + queue.mBroadcastsScheduled);
14770            }
14771            pw.println("  mHandler:");
14772            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14773            needSep = true;
14774            printedAnything = true;
14775        }
14776
14777        if (!printedAnything) {
14778            pw.println("  (nothing)");
14779        }
14780    }
14781
14782    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14783            int opti, boolean dumpAll, String dumpPackage) {
14784        boolean needSep;
14785        boolean printedAnything = false;
14786
14787        ItemMatcher matcher = new ItemMatcher();
14788        matcher.build(args, opti);
14789
14790        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14791
14792        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14793        printedAnything |= needSep;
14794
14795        if (mLaunchingProviders.size() > 0) {
14796            boolean printed = false;
14797            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14798                ContentProviderRecord r = mLaunchingProviders.get(i);
14799                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14800                    continue;
14801                }
14802                if (!printed) {
14803                    if (needSep) pw.println();
14804                    needSep = true;
14805                    pw.println("  Launching content providers:");
14806                    printed = true;
14807                    printedAnything = true;
14808                }
14809                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14810                        pw.println(r);
14811            }
14812        }
14813
14814        if (!printedAnything) {
14815            pw.println("  (nothing)");
14816        }
14817    }
14818
14819    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14820            int opti, boolean dumpAll, String dumpPackage) {
14821        boolean needSep = false;
14822        boolean printedAnything = false;
14823
14824        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14825
14826        if (mGrantedUriPermissions.size() > 0) {
14827            boolean printed = false;
14828            int dumpUid = -2;
14829            if (dumpPackage != null) {
14830                try {
14831                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14832                            MATCH_UNINSTALLED_PACKAGES, 0);
14833                } catch (NameNotFoundException e) {
14834                    dumpUid = -1;
14835                }
14836            }
14837            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14838                int uid = mGrantedUriPermissions.keyAt(i);
14839                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14840                    continue;
14841                }
14842                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14843                if (!printed) {
14844                    if (needSep) pw.println();
14845                    needSep = true;
14846                    pw.println("  Granted Uri Permissions:");
14847                    printed = true;
14848                    printedAnything = true;
14849                }
14850                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14851                for (UriPermission perm : perms.values()) {
14852                    pw.print("    "); pw.println(perm);
14853                    if (dumpAll) {
14854                        perm.dump(pw, "      ");
14855                    }
14856                }
14857            }
14858        }
14859
14860        if (!printedAnything) {
14861            pw.println("  (nothing)");
14862        }
14863    }
14864
14865    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14866            int opti, boolean dumpAll, String dumpPackage) {
14867        boolean printed = false;
14868
14869        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14870
14871        if (mIntentSenderRecords.size() > 0) {
14872            Iterator<WeakReference<PendingIntentRecord>> it
14873                    = mIntentSenderRecords.values().iterator();
14874            while (it.hasNext()) {
14875                WeakReference<PendingIntentRecord> ref = it.next();
14876                PendingIntentRecord rec = ref != null ? ref.get(): null;
14877                if (dumpPackage != null && (rec == null
14878                        || !dumpPackage.equals(rec.key.packageName))) {
14879                    continue;
14880                }
14881                printed = true;
14882                if (rec != null) {
14883                    pw.print("  * "); pw.println(rec);
14884                    if (dumpAll) {
14885                        rec.dump(pw, "    ");
14886                    }
14887                } else {
14888                    pw.print("  * "); pw.println(ref);
14889                }
14890            }
14891        }
14892
14893        if (!printed) {
14894            pw.println("  (nothing)");
14895        }
14896    }
14897
14898    private static final int dumpProcessList(PrintWriter pw,
14899            ActivityManagerService service, List list,
14900            String prefix, String normalLabel, String persistentLabel,
14901            String dumpPackage) {
14902        int numPers = 0;
14903        final int N = list.size()-1;
14904        for (int i=N; i>=0; i--) {
14905            ProcessRecord r = (ProcessRecord)list.get(i);
14906            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14907                continue;
14908            }
14909            pw.println(String.format("%s%s #%2d: %s",
14910                    prefix, (r.persistent ? persistentLabel : normalLabel),
14911                    i, r.toString()));
14912            if (r.persistent) {
14913                numPers++;
14914            }
14915        }
14916        return numPers;
14917    }
14918
14919    private static final boolean dumpProcessOomList(PrintWriter pw,
14920            ActivityManagerService service, List<ProcessRecord> origList,
14921            String prefix, String normalLabel, String persistentLabel,
14922            boolean inclDetails, String dumpPackage) {
14923
14924        ArrayList<Pair<ProcessRecord, Integer>> list
14925                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14926        for (int i=0; i<origList.size(); i++) {
14927            ProcessRecord r = origList.get(i);
14928            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14929                continue;
14930            }
14931            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14932        }
14933
14934        if (list.size() <= 0) {
14935            return false;
14936        }
14937
14938        Comparator<Pair<ProcessRecord, Integer>> comparator
14939                = new Comparator<Pair<ProcessRecord, Integer>>() {
14940            @Override
14941            public int compare(Pair<ProcessRecord, Integer> object1,
14942                    Pair<ProcessRecord, Integer> object2) {
14943                if (object1.first.setAdj != object2.first.setAdj) {
14944                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14945                }
14946                if (object1.first.setProcState != object2.first.setProcState) {
14947                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14948                }
14949                if (object1.second.intValue() != object2.second.intValue()) {
14950                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14951                }
14952                return 0;
14953            }
14954        };
14955
14956        Collections.sort(list, comparator);
14957
14958        final long curRealtime = SystemClock.elapsedRealtime();
14959        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14960        final long curUptime = SystemClock.uptimeMillis();
14961        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14962
14963        for (int i=list.size()-1; i>=0; i--) {
14964            ProcessRecord r = list.get(i).first;
14965            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14966            char schedGroup;
14967            switch (r.setSchedGroup) {
14968                case ProcessList.SCHED_GROUP_BACKGROUND:
14969                    schedGroup = 'B';
14970                    break;
14971                case ProcessList.SCHED_GROUP_DEFAULT:
14972                    schedGroup = 'F';
14973                    break;
14974                case ProcessList.SCHED_GROUP_TOP_APP:
14975                    schedGroup = 'T';
14976                    break;
14977                default:
14978                    schedGroup = '?';
14979                    break;
14980            }
14981            char foreground;
14982            if (r.foregroundActivities) {
14983                foreground = 'A';
14984            } else if (r.foregroundServices) {
14985                foreground = 'S';
14986            } else {
14987                foreground = ' ';
14988            }
14989            String procState = ProcessList.makeProcStateString(r.curProcState);
14990            pw.print(prefix);
14991            pw.print(r.persistent ? persistentLabel : normalLabel);
14992            pw.print(" #");
14993            int num = (origList.size()-1)-list.get(i).second;
14994            if (num < 10) pw.print(' ');
14995            pw.print(num);
14996            pw.print(": ");
14997            pw.print(oomAdj);
14998            pw.print(' ');
14999            pw.print(schedGroup);
15000            pw.print('/');
15001            pw.print(foreground);
15002            pw.print('/');
15003            pw.print(procState);
15004            pw.print(" trm:");
15005            if (r.trimMemoryLevel < 10) pw.print(' ');
15006            pw.print(r.trimMemoryLevel);
15007            pw.print(' ');
15008            pw.print(r.toShortString());
15009            pw.print(" (");
15010            pw.print(r.adjType);
15011            pw.println(')');
15012            if (r.adjSource != null || r.adjTarget != null) {
15013                pw.print(prefix);
15014                pw.print("    ");
15015                if (r.adjTarget instanceof ComponentName) {
15016                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15017                } else if (r.adjTarget != null) {
15018                    pw.print(r.adjTarget.toString());
15019                } else {
15020                    pw.print("{null}");
15021                }
15022                pw.print("<=");
15023                if (r.adjSource instanceof ProcessRecord) {
15024                    pw.print("Proc{");
15025                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15026                    pw.println("}");
15027                } else if (r.adjSource != null) {
15028                    pw.println(r.adjSource.toString());
15029                } else {
15030                    pw.println("{null}");
15031                }
15032            }
15033            if (inclDetails) {
15034                pw.print(prefix);
15035                pw.print("    ");
15036                pw.print("oom: max="); pw.print(r.maxAdj);
15037                pw.print(" curRaw="); pw.print(r.curRawAdj);
15038                pw.print(" setRaw="); pw.print(r.setRawAdj);
15039                pw.print(" cur="); pw.print(r.curAdj);
15040                pw.print(" set="); pw.println(r.setAdj);
15041                pw.print(prefix);
15042                pw.print("    ");
15043                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15044                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15045                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15046                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15047                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15048                pw.println();
15049                pw.print(prefix);
15050                pw.print("    ");
15051                pw.print("cached="); pw.print(r.cached);
15052                pw.print(" empty="); pw.print(r.empty);
15053                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15054
15055                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15056                    if (r.lastWakeTime != 0) {
15057                        long wtime;
15058                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15059                        synchronized (stats) {
15060                            wtime = stats.getProcessWakeTime(r.info.uid,
15061                                    r.pid, curRealtime);
15062                        }
15063                        long timeUsed = wtime - r.lastWakeTime;
15064                        pw.print(prefix);
15065                        pw.print("    ");
15066                        pw.print("keep awake over ");
15067                        TimeUtils.formatDuration(realtimeSince, pw);
15068                        pw.print(" used ");
15069                        TimeUtils.formatDuration(timeUsed, pw);
15070                        pw.print(" (");
15071                        pw.print((timeUsed*100)/realtimeSince);
15072                        pw.println("%)");
15073                    }
15074                    if (r.lastCpuTime != 0) {
15075                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15076                        pw.print(prefix);
15077                        pw.print("    ");
15078                        pw.print("run cpu over ");
15079                        TimeUtils.formatDuration(uptimeSince, pw);
15080                        pw.print(" used ");
15081                        TimeUtils.formatDuration(timeUsed, pw);
15082                        pw.print(" (");
15083                        pw.print((timeUsed*100)/uptimeSince);
15084                        pw.println("%)");
15085                    }
15086                }
15087            }
15088        }
15089        return true;
15090    }
15091
15092    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15093            String[] args) {
15094        ArrayList<ProcessRecord> procs;
15095        synchronized (this) {
15096            if (args != null && args.length > start
15097                    && args[start].charAt(0) != '-') {
15098                procs = new ArrayList<ProcessRecord>();
15099                int pid = -1;
15100                try {
15101                    pid = Integer.parseInt(args[start]);
15102                } catch (NumberFormatException e) {
15103                }
15104                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15105                    ProcessRecord proc = mLruProcesses.get(i);
15106                    if (proc.pid == pid) {
15107                        procs.add(proc);
15108                    } else if (allPkgs && proc.pkgList != null
15109                            && proc.pkgList.containsKey(args[start])) {
15110                        procs.add(proc);
15111                    } else if (proc.processName.equals(args[start])) {
15112                        procs.add(proc);
15113                    }
15114                }
15115                if (procs.size() <= 0) {
15116                    return null;
15117                }
15118            } else {
15119                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15120            }
15121        }
15122        return procs;
15123    }
15124
15125    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15126            PrintWriter pw, String[] args) {
15127        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15128        if (procs == null) {
15129            pw.println("No process found for: " + args[0]);
15130            return;
15131        }
15132
15133        long uptime = SystemClock.uptimeMillis();
15134        long realtime = SystemClock.elapsedRealtime();
15135        pw.println("Applications Graphics Acceleration Info:");
15136        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15137
15138        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15139            ProcessRecord r = procs.get(i);
15140            if (r.thread != null) {
15141                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15142                pw.flush();
15143                try {
15144                    TransferPipe tp = new TransferPipe();
15145                    try {
15146                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15147                        tp.go(fd);
15148                    } finally {
15149                        tp.kill();
15150                    }
15151                } catch (IOException e) {
15152                    pw.println("Failure while dumping the app: " + r);
15153                    pw.flush();
15154                } catch (RemoteException e) {
15155                    pw.println("Got a RemoteException while dumping the app " + r);
15156                    pw.flush();
15157                }
15158            }
15159        }
15160    }
15161
15162    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15163        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15164        if (procs == null) {
15165            pw.println("No process found for: " + args[0]);
15166            return;
15167        }
15168
15169        pw.println("Applications Database Info:");
15170
15171        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15172            ProcessRecord r = procs.get(i);
15173            if (r.thread != null) {
15174                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15175                pw.flush();
15176                try {
15177                    TransferPipe tp = new TransferPipe();
15178                    try {
15179                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15180                        tp.go(fd);
15181                    } finally {
15182                        tp.kill();
15183                    }
15184                } catch (IOException e) {
15185                    pw.println("Failure while dumping the app: " + r);
15186                    pw.flush();
15187                } catch (RemoteException e) {
15188                    pw.println("Got a RemoteException while dumping the app " + r);
15189                    pw.flush();
15190                }
15191            }
15192        }
15193    }
15194
15195    final static class MemItem {
15196        final boolean isProc;
15197        final String label;
15198        final String shortLabel;
15199        final long pss;
15200        final long swapPss;
15201        final int id;
15202        final boolean hasActivities;
15203        ArrayList<MemItem> subitems;
15204
15205        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15206                boolean _hasActivities) {
15207            isProc = true;
15208            label = _label;
15209            shortLabel = _shortLabel;
15210            pss = _pss;
15211            swapPss = _swapPss;
15212            id = _id;
15213            hasActivities = _hasActivities;
15214        }
15215
15216        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15217            isProc = false;
15218            label = _label;
15219            shortLabel = _shortLabel;
15220            pss = _pss;
15221            swapPss = _swapPss;
15222            id = _id;
15223            hasActivities = false;
15224        }
15225    }
15226
15227    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15228            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15229        if (sort && !isCompact) {
15230            Collections.sort(items, new Comparator<MemItem>() {
15231                @Override
15232                public int compare(MemItem lhs, MemItem rhs) {
15233                    if (lhs.pss < rhs.pss) {
15234                        return 1;
15235                    } else if (lhs.pss > rhs.pss) {
15236                        return -1;
15237                    }
15238                    return 0;
15239                }
15240            });
15241        }
15242
15243        for (int i=0; i<items.size(); i++) {
15244            MemItem mi = items.get(i);
15245            if (!isCompact) {
15246                if (dumpSwapPss) {
15247                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15248                            mi.label, stringifyKBSize(mi.swapPss));
15249                } else {
15250                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15251                }
15252            } else if (mi.isProc) {
15253                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15254                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15255                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15256                pw.println(mi.hasActivities ? ",a" : ",e");
15257            } else {
15258                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15259                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15260            }
15261            if (mi.subitems != null) {
15262                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15263                        true, isCompact, dumpSwapPss);
15264            }
15265        }
15266    }
15267
15268    // These are in KB.
15269    static final long[] DUMP_MEM_BUCKETS = new long[] {
15270        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15271        120*1024, 160*1024, 200*1024,
15272        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15273        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15274    };
15275
15276    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15277            boolean stackLike) {
15278        int start = label.lastIndexOf('.');
15279        if (start >= 0) start++;
15280        else start = 0;
15281        int end = label.length();
15282        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15283            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15284                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15285                out.append(bucket);
15286                out.append(stackLike ? "MB." : "MB ");
15287                out.append(label, start, end);
15288                return;
15289            }
15290        }
15291        out.append(memKB/1024);
15292        out.append(stackLike ? "MB." : "MB ");
15293        out.append(label, start, end);
15294    }
15295
15296    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15297            ProcessList.NATIVE_ADJ,
15298            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15299            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15300            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15301            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15302            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15303            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15304    };
15305    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15306            "Native",
15307            "System", "Persistent", "Persistent Service", "Foreground",
15308            "Visible", "Perceptible",
15309            "Heavy Weight", "Backup",
15310            "A Services", "Home",
15311            "Previous", "B Services", "Cached"
15312    };
15313    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15314            "native",
15315            "sys", "pers", "persvc", "fore",
15316            "vis", "percept",
15317            "heavy", "backup",
15318            "servicea", "home",
15319            "prev", "serviceb", "cached"
15320    };
15321
15322    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15323            long realtime, boolean isCheckinRequest, boolean isCompact) {
15324        if (isCompact) {
15325            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15326        }
15327        if (isCheckinRequest || isCompact) {
15328            // short checkin version
15329            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15330        } else {
15331            pw.println("Applications Memory Usage (in Kilobytes):");
15332            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15333        }
15334    }
15335
15336    private static final int KSM_SHARED = 0;
15337    private static final int KSM_SHARING = 1;
15338    private static final int KSM_UNSHARED = 2;
15339    private static final int KSM_VOLATILE = 3;
15340
15341    private final long[] getKsmInfo() {
15342        long[] longOut = new long[4];
15343        final int[] SINGLE_LONG_FORMAT = new int[] {
15344            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15345        };
15346        long[] longTmp = new long[1];
15347        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15348                SINGLE_LONG_FORMAT, null, longTmp, null);
15349        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15350        longTmp[0] = 0;
15351        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15352                SINGLE_LONG_FORMAT, null, longTmp, null);
15353        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15354        longTmp[0] = 0;
15355        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15356                SINGLE_LONG_FORMAT, null, longTmp, null);
15357        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15358        longTmp[0] = 0;
15359        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15360                SINGLE_LONG_FORMAT, null, longTmp, null);
15361        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15362        return longOut;
15363    }
15364
15365    private static String stringifySize(long size, int order) {
15366        Locale locale = Locale.US;
15367        switch (order) {
15368            case 1:
15369                return String.format(locale, "%,13d", size);
15370            case 1024:
15371                return String.format(locale, "%,9dK", size / 1024);
15372            case 1024 * 1024:
15373                return String.format(locale, "%,5dM", size / 1024 / 1024);
15374            case 1024 * 1024 * 1024:
15375                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15376            default:
15377                throw new IllegalArgumentException("Invalid size order");
15378        }
15379    }
15380
15381    private static String stringifyKBSize(long size) {
15382        return stringifySize(size * 1024, 1024);
15383    }
15384
15385    // Update this version number in case you change the 'compact' format
15386    private static final int MEMINFO_COMPACT_VERSION = 1;
15387
15388    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15389            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15390        boolean dumpDetails = false;
15391        boolean dumpFullDetails = false;
15392        boolean dumpDalvik = false;
15393        boolean dumpSummaryOnly = false;
15394        boolean dumpUnreachable = false;
15395        boolean oomOnly = false;
15396        boolean isCompact = false;
15397        boolean localOnly = false;
15398        boolean packages = false;
15399        boolean isCheckinRequest = false;
15400        boolean dumpSwapPss = false;
15401
15402        int opti = 0;
15403        while (opti < args.length) {
15404            String opt = args[opti];
15405            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15406                break;
15407            }
15408            opti++;
15409            if ("-a".equals(opt)) {
15410                dumpDetails = true;
15411                dumpFullDetails = true;
15412                dumpDalvik = true;
15413                dumpSwapPss = true;
15414            } else if ("-d".equals(opt)) {
15415                dumpDalvik = true;
15416            } else if ("-c".equals(opt)) {
15417                isCompact = true;
15418            } else if ("-s".equals(opt)) {
15419                dumpDetails = true;
15420                dumpSummaryOnly = true;
15421            } else if ("-S".equals(opt)) {
15422                dumpSwapPss = true;
15423            } else if ("--unreachable".equals(opt)) {
15424                dumpUnreachable = true;
15425            } else if ("--oom".equals(opt)) {
15426                oomOnly = true;
15427            } else if ("--local".equals(opt)) {
15428                localOnly = true;
15429            } else if ("--package".equals(opt)) {
15430                packages = true;
15431            } else if ("--checkin".equals(opt)) {
15432                isCheckinRequest = true;
15433
15434            } else if ("-h".equals(opt)) {
15435                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15436                pw.println("  -a: include all available information for each process.");
15437                pw.println("  -d: include dalvik details.");
15438                pw.println("  -c: dump in a compact machine-parseable representation.");
15439                pw.println("  -s: dump only summary of application memory usage.");
15440                pw.println("  -S: dump also SwapPss.");
15441                pw.println("  --oom: only show processes organized by oom adj.");
15442                pw.println("  --local: only collect details locally, don't call process.");
15443                pw.println("  --package: interpret process arg as package, dumping all");
15444                pw.println("             processes that have loaded that package.");
15445                pw.println("  --checkin: dump data for a checkin");
15446                pw.println("If [process] is specified it can be the name or ");
15447                pw.println("pid of a specific process to dump.");
15448                return;
15449            } else {
15450                pw.println("Unknown argument: " + opt + "; use -h for help");
15451            }
15452        }
15453
15454        long uptime = SystemClock.uptimeMillis();
15455        long realtime = SystemClock.elapsedRealtime();
15456        final long[] tmpLong = new long[1];
15457
15458        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15459        if (procs == null) {
15460            // No Java processes.  Maybe they want to print a native process.
15461            if (args != null && args.length > opti
15462                    && args[opti].charAt(0) != '-') {
15463                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15464                        = new ArrayList<ProcessCpuTracker.Stats>();
15465                updateCpuStatsNow();
15466                int findPid = -1;
15467                try {
15468                    findPid = Integer.parseInt(args[opti]);
15469                } catch (NumberFormatException e) {
15470                }
15471                synchronized (mProcessCpuTracker) {
15472                    final int N = mProcessCpuTracker.countStats();
15473                    for (int i=0; i<N; i++) {
15474                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15475                        if (st.pid == findPid || (st.baseName != null
15476                                && st.baseName.equals(args[opti]))) {
15477                            nativeProcs.add(st);
15478                        }
15479                    }
15480                }
15481                if (nativeProcs.size() > 0) {
15482                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15483                            isCompact);
15484                    Debug.MemoryInfo mi = null;
15485                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15486                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15487                        final int pid = r.pid;
15488                        if (!isCheckinRequest && dumpDetails) {
15489                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15490                        }
15491                        if (mi == null) {
15492                            mi = new Debug.MemoryInfo();
15493                        }
15494                        if (dumpDetails || (!brief && !oomOnly)) {
15495                            Debug.getMemoryInfo(pid, mi);
15496                        } else {
15497                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15498                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15499                        }
15500                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15501                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15502                        if (isCheckinRequest) {
15503                            pw.println();
15504                        }
15505                    }
15506                    return;
15507                }
15508            }
15509            pw.println("No process found for: " + args[opti]);
15510            return;
15511        }
15512
15513        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15514            dumpDetails = true;
15515        }
15516
15517        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15518
15519        String[] innerArgs = new String[args.length-opti];
15520        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15521
15522        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15523        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15524        long nativePss = 0;
15525        long nativeSwapPss = 0;
15526        long dalvikPss = 0;
15527        long dalvikSwapPss = 0;
15528        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15529                EmptyArray.LONG;
15530        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15531                EmptyArray.LONG;
15532        long otherPss = 0;
15533        long otherSwapPss = 0;
15534        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15535        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15536
15537        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15538        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15539        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15540                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15541
15542        long totalPss = 0;
15543        long totalSwapPss = 0;
15544        long cachedPss = 0;
15545        long cachedSwapPss = 0;
15546        boolean hasSwapPss = false;
15547
15548        Debug.MemoryInfo mi = null;
15549        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15550            final ProcessRecord r = procs.get(i);
15551            final IApplicationThread thread;
15552            final int pid;
15553            final int oomAdj;
15554            final boolean hasActivities;
15555            synchronized (this) {
15556                thread = r.thread;
15557                pid = r.pid;
15558                oomAdj = r.getSetAdjWithServices();
15559                hasActivities = r.activities.size() > 0;
15560            }
15561            if (thread != null) {
15562                if (!isCheckinRequest && dumpDetails) {
15563                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15564                }
15565                if (mi == null) {
15566                    mi = new Debug.MemoryInfo();
15567                }
15568                if (dumpDetails || (!brief && !oomOnly)) {
15569                    Debug.getMemoryInfo(pid, mi);
15570                    hasSwapPss = mi.hasSwappedOutPss;
15571                } else {
15572                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15573                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15574                }
15575                if (dumpDetails) {
15576                    if (localOnly) {
15577                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15578                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15579                        if (isCheckinRequest) {
15580                            pw.println();
15581                        }
15582                    } else {
15583                        try {
15584                            pw.flush();
15585                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15586                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15587                        } catch (RemoteException e) {
15588                            if (!isCheckinRequest) {
15589                                pw.println("Got RemoteException!");
15590                                pw.flush();
15591                            }
15592                        }
15593                    }
15594                }
15595
15596                final long myTotalPss = mi.getTotalPss();
15597                final long myTotalUss = mi.getTotalUss();
15598                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15599
15600                synchronized (this) {
15601                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15602                        // Record this for posterity if the process has been stable.
15603                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15604                    }
15605                }
15606
15607                if (!isCheckinRequest && mi != null) {
15608                    totalPss += myTotalPss;
15609                    totalSwapPss += myTotalSwapPss;
15610                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15611                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15612                            myTotalSwapPss, pid, hasActivities);
15613                    procMems.add(pssItem);
15614                    procMemsMap.put(pid, pssItem);
15615
15616                    nativePss += mi.nativePss;
15617                    nativeSwapPss += mi.nativeSwappedOutPss;
15618                    dalvikPss += mi.dalvikPss;
15619                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15620                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15621                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15622                        dalvikSubitemSwapPss[j] +=
15623                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15624                    }
15625                    otherPss += mi.otherPss;
15626                    otherSwapPss += mi.otherSwappedOutPss;
15627                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15628                        long mem = mi.getOtherPss(j);
15629                        miscPss[j] += mem;
15630                        otherPss -= mem;
15631                        mem = mi.getOtherSwappedOutPss(j);
15632                        miscSwapPss[j] += mem;
15633                        otherSwapPss -= mem;
15634                    }
15635
15636                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15637                        cachedPss += myTotalPss;
15638                        cachedSwapPss += myTotalSwapPss;
15639                    }
15640
15641                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15642                        if (oomIndex == (oomPss.length - 1)
15643                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15644                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15645                            oomPss[oomIndex] += myTotalPss;
15646                            oomSwapPss[oomIndex] += myTotalSwapPss;
15647                            if (oomProcs[oomIndex] == null) {
15648                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15649                            }
15650                            oomProcs[oomIndex].add(pssItem);
15651                            break;
15652                        }
15653                    }
15654                }
15655            }
15656        }
15657
15658        long nativeProcTotalPss = 0;
15659
15660        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15661            // If we are showing aggregations, also look for native processes to
15662            // include so that our aggregations are more accurate.
15663            updateCpuStatsNow();
15664            mi = null;
15665            synchronized (mProcessCpuTracker) {
15666                final int N = mProcessCpuTracker.countStats();
15667                for (int i=0; i<N; i++) {
15668                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15669                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15670                        if (mi == null) {
15671                            mi = new Debug.MemoryInfo();
15672                        }
15673                        if (!brief && !oomOnly) {
15674                            Debug.getMemoryInfo(st.pid, mi);
15675                        } else {
15676                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15677                            mi.nativePrivateDirty = (int)tmpLong[0];
15678                        }
15679
15680                        final long myTotalPss = mi.getTotalPss();
15681                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15682                        totalPss += myTotalPss;
15683                        nativeProcTotalPss += myTotalPss;
15684
15685                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15686                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15687                        procMems.add(pssItem);
15688
15689                        nativePss += mi.nativePss;
15690                        nativeSwapPss += mi.nativeSwappedOutPss;
15691                        dalvikPss += mi.dalvikPss;
15692                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15693                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15694                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15695                            dalvikSubitemSwapPss[j] +=
15696                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15697                        }
15698                        otherPss += mi.otherPss;
15699                        otherSwapPss += mi.otherSwappedOutPss;
15700                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15701                            long mem = mi.getOtherPss(j);
15702                            miscPss[j] += mem;
15703                            otherPss -= mem;
15704                            mem = mi.getOtherSwappedOutPss(j);
15705                            miscSwapPss[j] += mem;
15706                            otherSwapPss -= mem;
15707                        }
15708                        oomPss[0] += myTotalPss;
15709                        oomSwapPss[0] += myTotalSwapPss;
15710                        if (oomProcs[0] == null) {
15711                            oomProcs[0] = new ArrayList<MemItem>();
15712                        }
15713                        oomProcs[0].add(pssItem);
15714                    }
15715                }
15716            }
15717
15718            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15719
15720            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15721            final MemItem dalvikItem =
15722                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15723            if (dalvikSubitemPss.length > 0) {
15724                dalvikItem.subitems = new ArrayList<MemItem>();
15725                for (int j=0; j<dalvikSubitemPss.length; j++) {
15726                    final String name = Debug.MemoryInfo.getOtherLabel(
15727                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15728                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15729                                    dalvikSubitemSwapPss[j], j));
15730                }
15731            }
15732            catMems.add(dalvikItem);
15733            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15734            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15735                String label = Debug.MemoryInfo.getOtherLabel(j);
15736                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15737            }
15738
15739            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15740            for (int j=0; j<oomPss.length; j++) {
15741                if (oomPss[j] != 0) {
15742                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15743                            : DUMP_MEM_OOM_LABEL[j];
15744                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15745                            DUMP_MEM_OOM_ADJ[j]);
15746                    item.subitems = oomProcs[j];
15747                    oomMems.add(item);
15748                }
15749            }
15750
15751            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15752            if (!brief && !oomOnly && !isCompact) {
15753                pw.println();
15754                pw.println("Total PSS by process:");
15755                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15756                pw.println();
15757            }
15758            if (!isCompact) {
15759                pw.println("Total PSS by OOM adjustment:");
15760            }
15761            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15762            if (!brief && !oomOnly) {
15763                PrintWriter out = categoryPw != null ? categoryPw : pw;
15764                if (!isCompact) {
15765                    out.println();
15766                    out.println("Total PSS by category:");
15767                }
15768                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15769            }
15770            if (!isCompact) {
15771                pw.println();
15772            }
15773            MemInfoReader memInfo = new MemInfoReader();
15774            memInfo.readMemInfo();
15775            if (nativeProcTotalPss > 0) {
15776                synchronized (this) {
15777                    final long cachedKb = memInfo.getCachedSizeKb();
15778                    final long freeKb = memInfo.getFreeSizeKb();
15779                    final long zramKb = memInfo.getZramTotalSizeKb();
15780                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15781                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15782                            kernelKb*1024, nativeProcTotalPss*1024);
15783                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15784                            nativeProcTotalPss);
15785                }
15786            }
15787            if (!brief) {
15788                if (!isCompact) {
15789                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15790                    pw.print(" (status ");
15791                    switch (mLastMemoryLevel) {
15792                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15793                            pw.println("normal)");
15794                            break;
15795                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15796                            pw.println("moderate)");
15797                            break;
15798                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15799                            pw.println("low)");
15800                            break;
15801                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15802                            pw.println("critical)");
15803                            break;
15804                        default:
15805                            pw.print(mLastMemoryLevel);
15806                            pw.println(")");
15807                            break;
15808                    }
15809                    pw.print(" Free RAM: ");
15810                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15811                            + memInfo.getFreeSizeKb()));
15812                    pw.print(" (");
15813                    pw.print(stringifyKBSize(cachedPss));
15814                    pw.print(" cached pss + ");
15815                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15816                    pw.print(" cached kernel + ");
15817                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15818                    pw.println(" free)");
15819                } else {
15820                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15821                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15822                            + memInfo.getFreeSizeKb()); pw.print(",");
15823                    pw.println(totalPss - cachedPss);
15824                }
15825            }
15826            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15827                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15828                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15829            if (!isCompact) {
15830                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15831                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15832                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15833                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15834                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15835            } else {
15836                pw.print("lostram,"); pw.println(lostRAM);
15837            }
15838            if (!brief) {
15839                if (memInfo.getZramTotalSizeKb() != 0) {
15840                    if (!isCompact) {
15841                        pw.print("     ZRAM: ");
15842                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15843                                pw.print(" physical used for ");
15844                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15845                                        - memInfo.getSwapFreeSizeKb()));
15846                                pw.print(" in swap (");
15847                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15848                                pw.println(" total swap)");
15849                    } else {
15850                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15851                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15852                                pw.println(memInfo.getSwapFreeSizeKb());
15853                    }
15854                }
15855                final long[] ksm = getKsmInfo();
15856                if (!isCompact) {
15857                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15858                            || ksm[KSM_VOLATILE] != 0) {
15859                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15860                                pw.print(" saved from shared ");
15861                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15862                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15863                                pw.print(" unshared; ");
15864                                pw.print(stringifyKBSize(
15865                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15866                    }
15867                    pw.print("   Tuning: ");
15868                    pw.print(ActivityManager.staticGetMemoryClass());
15869                    pw.print(" (large ");
15870                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15871                    pw.print("), oom ");
15872                    pw.print(stringifySize(
15873                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15874                    pw.print(", restore limit ");
15875                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15876                    if (ActivityManager.isLowRamDeviceStatic()) {
15877                        pw.print(" (low-ram)");
15878                    }
15879                    if (ActivityManager.isHighEndGfx()) {
15880                        pw.print(" (high-end-gfx)");
15881                    }
15882                    pw.println();
15883                } else {
15884                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15885                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15886                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15887                    pw.print("tuning,");
15888                    pw.print(ActivityManager.staticGetMemoryClass());
15889                    pw.print(',');
15890                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15891                    pw.print(',');
15892                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15893                    if (ActivityManager.isLowRamDeviceStatic()) {
15894                        pw.print(",low-ram");
15895                    }
15896                    if (ActivityManager.isHighEndGfx()) {
15897                        pw.print(",high-end-gfx");
15898                    }
15899                    pw.println();
15900                }
15901            }
15902        }
15903    }
15904
15905    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15906            long memtrack, String name) {
15907        sb.append("  ");
15908        sb.append(ProcessList.makeOomAdjString(oomAdj));
15909        sb.append(' ');
15910        sb.append(ProcessList.makeProcStateString(procState));
15911        sb.append(' ');
15912        ProcessList.appendRamKb(sb, pss);
15913        sb.append(": ");
15914        sb.append(name);
15915        if (memtrack > 0) {
15916            sb.append(" (");
15917            sb.append(stringifyKBSize(memtrack));
15918            sb.append(" memtrack)");
15919        }
15920    }
15921
15922    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15923        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15924        sb.append(" (pid ");
15925        sb.append(mi.pid);
15926        sb.append(") ");
15927        sb.append(mi.adjType);
15928        sb.append('\n');
15929        if (mi.adjReason != null) {
15930            sb.append("                      ");
15931            sb.append(mi.adjReason);
15932            sb.append('\n');
15933        }
15934    }
15935
15936    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15937        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15938        for (int i=0, N=memInfos.size(); i<N; i++) {
15939            ProcessMemInfo mi = memInfos.get(i);
15940            infoMap.put(mi.pid, mi);
15941        }
15942        updateCpuStatsNow();
15943        long[] memtrackTmp = new long[1];
15944        synchronized (mProcessCpuTracker) {
15945            final int N = mProcessCpuTracker.countStats();
15946            for (int i=0; i<N; i++) {
15947                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15948                if (st.vsize > 0) {
15949                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15950                    if (pss > 0) {
15951                        if (infoMap.indexOfKey(st.pid) < 0) {
15952                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15953                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15954                            mi.pss = pss;
15955                            mi.memtrack = memtrackTmp[0];
15956                            memInfos.add(mi);
15957                        }
15958                    }
15959                }
15960            }
15961        }
15962
15963        long totalPss = 0;
15964        long totalMemtrack = 0;
15965        for (int i=0, N=memInfos.size(); i<N; i++) {
15966            ProcessMemInfo mi = memInfos.get(i);
15967            if (mi.pss == 0) {
15968                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15969                mi.memtrack = memtrackTmp[0];
15970            }
15971            totalPss += mi.pss;
15972            totalMemtrack += mi.memtrack;
15973        }
15974        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15975            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15976                if (lhs.oomAdj != rhs.oomAdj) {
15977                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15978                }
15979                if (lhs.pss != rhs.pss) {
15980                    return lhs.pss < rhs.pss ? 1 : -1;
15981                }
15982                return 0;
15983            }
15984        });
15985
15986        StringBuilder tag = new StringBuilder(128);
15987        StringBuilder stack = new StringBuilder(128);
15988        tag.append("Low on memory -- ");
15989        appendMemBucket(tag, totalPss, "total", false);
15990        appendMemBucket(stack, totalPss, "total", true);
15991
15992        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15993        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15994        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15995
15996        boolean firstLine = true;
15997        int lastOomAdj = Integer.MIN_VALUE;
15998        long extraNativeRam = 0;
15999        long extraNativeMemtrack = 0;
16000        long cachedPss = 0;
16001        for (int i=0, N=memInfos.size(); i<N; i++) {
16002            ProcessMemInfo mi = memInfos.get(i);
16003
16004            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16005                cachedPss += mi.pss;
16006            }
16007
16008            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16009                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16010                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16011                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16012                if (lastOomAdj != mi.oomAdj) {
16013                    lastOomAdj = mi.oomAdj;
16014                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16015                        tag.append(" / ");
16016                    }
16017                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16018                        if (firstLine) {
16019                            stack.append(":");
16020                            firstLine = false;
16021                        }
16022                        stack.append("\n\t at ");
16023                    } else {
16024                        stack.append("$");
16025                    }
16026                } else {
16027                    tag.append(" ");
16028                    stack.append("$");
16029                }
16030                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16031                    appendMemBucket(tag, mi.pss, mi.name, false);
16032                }
16033                appendMemBucket(stack, mi.pss, mi.name, true);
16034                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16035                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16036                    stack.append("(");
16037                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16038                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16039                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16040                            stack.append(":");
16041                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16042                        }
16043                    }
16044                    stack.append(")");
16045                }
16046            }
16047
16048            appendMemInfo(fullNativeBuilder, mi);
16049            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16050                // The short form only has native processes that are >= 512K.
16051                if (mi.pss >= 512) {
16052                    appendMemInfo(shortNativeBuilder, mi);
16053                } else {
16054                    extraNativeRam += mi.pss;
16055                    extraNativeMemtrack += mi.memtrack;
16056                }
16057            } else {
16058                // Short form has all other details, but if we have collected RAM
16059                // from smaller native processes let's dump a summary of that.
16060                if (extraNativeRam > 0) {
16061                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16062                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16063                    shortNativeBuilder.append('\n');
16064                    extraNativeRam = 0;
16065                }
16066                appendMemInfo(fullJavaBuilder, mi);
16067            }
16068        }
16069
16070        fullJavaBuilder.append("           ");
16071        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16072        fullJavaBuilder.append(": TOTAL");
16073        if (totalMemtrack > 0) {
16074            fullJavaBuilder.append(" (");
16075            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16076            fullJavaBuilder.append(" memtrack)");
16077        } else {
16078        }
16079        fullJavaBuilder.append("\n");
16080
16081        MemInfoReader memInfo = new MemInfoReader();
16082        memInfo.readMemInfo();
16083        final long[] infos = memInfo.getRawInfo();
16084
16085        StringBuilder memInfoBuilder = new StringBuilder(1024);
16086        Debug.getMemInfo(infos);
16087        memInfoBuilder.append("  MemInfo: ");
16088        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16089        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16090        memInfoBuilder.append(stringifyKBSize(
16091                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16092        memInfoBuilder.append(stringifyKBSize(
16093                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16094        memInfoBuilder.append(stringifyKBSize(
16095                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16096        memInfoBuilder.append("           ");
16097        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16098        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16099        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16100        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16101        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16102            memInfoBuilder.append("  ZRAM: ");
16103            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16104            memInfoBuilder.append(" RAM, ");
16105            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16106            memInfoBuilder.append(" swap total, ");
16107            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16108            memInfoBuilder.append(" swap free\n");
16109        }
16110        final long[] ksm = getKsmInfo();
16111        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16112                || ksm[KSM_VOLATILE] != 0) {
16113            memInfoBuilder.append("  KSM: ");
16114            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16115            memInfoBuilder.append(" saved from shared ");
16116            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16117            memInfoBuilder.append("\n       ");
16118            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16119            memInfoBuilder.append(" unshared; ");
16120            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16121            memInfoBuilder.append(" volatile\n");
16122        }
16123        memInfoBuilder.append("  Free RAM: ");
16124        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16125                + memInfo.getFreeSizeKb()));
16126        memInfoBuilder.append("\n");
16127        memInfoBuilder.append("  Used RAM: ");
16128        memInfoBuilder.append(stringifyKBSize(
16129                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16130        memInfoBuilder.append("\n");
16131        memInfoBuilder.append("  Lost RAM: ");
16132        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16133                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16134                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16135        memInfoBuilder.append("\n");
16136        Slog.i(TAG, "Low on memory:");
16137        Slog.i(TAG, shortNativeBuilder.toString());
16138        Slog.i(TAG, fullJavaBuilder.toString());
16139        Slog.i(TAG, memInfoBuilder.toString());
16140
16141        StringBuilder dropBuilder = new StringBuilder(1024);
16142        /*
16143        StringWriter oomSw = new StringWriter();
16144        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16145        StringWriter catSw = new StringWriter();
16146        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16147        String[] emptyArgs = new String[] { };
16148        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16149        oomPw.flush();
16150        String oomString = oomSw.toString();
16151        */
16152        dropBuilder.append("Low on memory:");
16153        dropBuilder.append(stack);
16154        dropBuilder.append('\n');
16155        dropBuilder.append(fullNativeBuilder);
16156        dropBuilder.append(fullJavaBuilder);
16157        dropBuilder.append('\n');
16158        dropBuilder.append(memInfoBuilder);
16159        dropBuilder.append('\n');
16160        /*
16161        dropBuilder.append(oomString);
16162        dropBuilder.append('\n');
16163        */
16164        StringWriter catSw = new StringWriter();
16165        synchronized (ActivityManagerService.this) {
16166            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16167            String[] emptyArgs = new String[] { };
16168            catPw.println();
16169            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16170            catPw.println();
16171            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16172                    false, false, null);
16173            catPw.println();
16174            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16175            catPw.flush();
16176        }
16177        dropBuilder.append(catSw.toString());
16178        addErrorToDropBox("lowmem", null, "system_server", null,
16179                null, tag.toString(), dropBuilder.toString(), null, null);
16180        //Slog.i(TAG, "Sent to dropbox:");
16181        //Slog.i(TAG, dropBuilder.toString());
16182        synchronized (ActivityManagerService.this) {
16183            long now = SystemClock.uptimeMillis();
16184            if (mLastMemUsageReportTime < now) {
16185                mLastMemUsageReportTime = now;
16186            }
16187        }
16188    }
16189
16190    /**
16191     * Searches array of arguments for the specified string
16192     * @param args array of argument strings
16193     * @param value value to search for
16194     * @return true if the value is contained in the array
16195     */
16196    private static boolean scanArgs(String[] args, String value) {
16197        if (args != null) {
16198            for (String arg : args) {
16199                if (value.equals(arg)) {
16200                    return true;
16201                }
16202            }
16203        }
16204        return false;
16205    }
16206
16207    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16208            ContentProviderRecord cpr, boolean always) {
16209        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16210
16211        if (!inLaunching || always) {
16212            synchronized (cpr) {
16213                cpr.launchingApp = null;
16214                cpr.notifyAll();
16215            }
16216            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16217            String names[] = cpr.info.authority.split(";");
16218            for (int j = 0; j < names.length; j++) {
16219                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16220            }
16221        }
16222
16223        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16224            ContentProviderConnection conn = cpr.connections.get(i);
16225            if (conn.waiting) {
16226                // If this connection is waiting for the provider, then we don't
16227                // need to mess with its process unless we are always removing
16228                // or for some reason the provider is not currently launching.
16229                if (inLaunching && !always) {
16230                    continue;
16231                }
16232            }
16233            ProcessRecord capp = conn.client;
16234            conn.dead = true;
16235            if (conn.stableCount > 0) {
16236                if (!capp.persistent && capp.thread != null
16237                        && capp.pid != 0
16238                        && capp.pid != MY_PID) {
16239                    capp.kill("depends on provider "
16240                            + cpr.name.flattenToShortString()
16241                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16242                }
16243            } else if (capp.thread != null && conn.provider.provider != null) {
16244                try {
16245                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16246                } catch (RemoteException e) {
16247                }
16248                // In the protocol here, we don't expect the client to correctly
16249                // clean up this connection, we'll just remove it.
16250                cpr.connections.remove(i);
16251                if (conn.client.conProviders.remove(conn)) {
16252                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16253                }
16254            }
16255        }
16256
16257        if (inLaunching && always) {
16258            mLaunchingProviders.remove(cpr);
16259        }
16260        return inLaunching;
16261    }
16262
16263    /**
16264     * Main code for cleaning up a process when it has gone away.  This is
16265     * called both as a result of the process dying, or directly when stopping
16266     * a process when running in single process mode.
16267     *
16268     * @return Returns true if the given process has been restarted, so the
16269     * app that was passed in must remain on the process lists.
16270     */
16271    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16272            boolean restarting, boolean allowRestart, int index) {
16273        if (index >= 0) {
16274            removeLruProcessLocked(app);
16275            ProcessList.remove(app.pid);
16276        }
16277
16278        mProcessesToGc.remove(app);
16279        mPendingPssProcesses.remove(app);
16280
16281        // Dismiss any open dialogs.
16282        if (app.crashDialog != null && !app.forceCrashReport) {
16283            app.crashDialog.dismiss();
16284            app.crashDialog = null;
16285        }
16286        if (app.anrDialog != null) {
16287            app.anrDialog.dismiss();
16288            app.anrDialog = null;
16289        }
16290        if (app.waitDialog != null) {
16291            app.waitDialog.dismiss();
16292            app.waitDialog = null;
16293        }
16294
16295        app.crashing = false;
16296        app.notResponding = false;
16297
16298        app.resetPackageList(mProcessStats);
16299        app.unlinkDeathRecipient();
16300        app.makeInactive(mProcessStats);
16301        app.waitingToKill = null;
16302        app.forcingToForeground = null;
16303        updateProcessForegroundLocked(app, false, false);
16304        app.foregroundActivities = false;
16305        app.hasShownUi = false;
16306        app.treatLikeActivity = false;
16307        app.hasAboveClient = false;
16308        app.hasClientActivities = false;
16309
16310        mServices.killServicesLocked(app, allowRestart);
16311
16312        boolean restart = false;
16313
16314        // Remove published content providers.
16315        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16316            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16317            final boolean always = app.bad || !allowRestart;
16318            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16319            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16320                // We left the provider in the launching list, need to
16321                // restart it.
16322                restart = true;
16323            }
16324
16325            cpr.provider = null;
16326            cpr.proc = null;
16327        }
16328        app.pubProviders.clear();
16329
16330        // Take care of any launching providers waiting for this process.
16331        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16332            restart = true;
16333        }
16334
16335        // Unregister from connected content providers.
16336        if (!app.conProviders.isEmpty()) {
16337            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16338                ContentProviderConnection conn = app.conProviders.get(i);
16339                conn.provider.connections.remove(conn);
16340                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16341                        conn.provider.name);
16342            }
16343            app.conProviders.clear();
16344        }
16345
16346        // At this point there may be remaining entries in mLaunchingProviders
16347        // where we were the only one waiting, so they are no longer of use.
16348        // Look for these and clean up if found.
16349        // XXX Commented out for now.  Trying to figure out a way to reproduce
16350        // the actual situation to identify what is actually going on.
16351        if (false) {
16352            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16353                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16354                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16355                    synchronized (cpr) {
16356                        cpr.launchingApp = null;
16357                        cpr.notifyAll();
16358                    }
16359                }
16360            }
16361        }
16362
16363        skipCurrentReceiverLocked(app);
16364
16365        // Unregister any receivers.
16366        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16367            removeReceiverLocked(app.receivers.valueAt(i));
16368        }
16369        app.receivers.clear();
16370
16371        // If the app is undergoing backup, tell the backup manager about it
16372        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16373            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16374                    + mBackupTarget.appInfo + " died during backup");
16375            try {
16376                IBackupManager bm = IBackupManager.Stub.asInterface(
16377                        ServiceManager.getService(Context.BACKUP_SERVICE));
16378                bm.agentDisconnected(app.info.packageName);
16379            } catch (RemoteException e) {
16380                // can't happen; backup manager is local
16381            }
16382        }
16383
16384        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16385            ProcessChangeItem item = mPendingProcessChanges.get(i);
16386            if (item.pid == app.pid) {
16387                mPendingProcessChanges.remove(i);
16388                mAvailProcessChanges.add(item);
16389            }
16390        }
16391        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16392                null).sendToTarget();
16393
16394        // If the caller is restarting this app, then leave it in its
16395        // current lists and let the caller take care of it.
16396        if (restarting) {
16397            return false;
16398        }
16399
16400        if (!app.persistent || app.isolated) {
16401            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16402                    "Removing non-persistent process during cleanup: " + app);
16403            removeProcessNameLocked(app.processName, app.uid);
16404            if (mHeavyWeightProcess == app) {
16405                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16406                        mHeavyWeightProcess.userId, 0));
16407                mHeavyWeightProcess = null;
16408            }
16409        } else if (!app.removed) {
16410            // This app is persistent, so we need to keep its record around.
16411            // If it is not already on the pending app list, add it there
16412            // and start a new process for it.
16413            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16414                mPersistentStartingProcesses.add(app);
16415                restart = true;
16416            }
16417        }
16418        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16419                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16420        mProcessesOnHold.remove(app);
16421
16422        if (app == mHomeProcess) {
16423            mHomeProcess = null;
16424        }
16425        if (app == mPreviousProcess) {
16426            mPreviousProcess = null;
16427        }
16428
16429        if (restart && !app.isolated) {
16430            // We have components that still need to be running in the
16431            // process, so re-launch it.
16432            if (index < 0) {
16433                ProcessList.remove(app.pid);
16434            }
16435            addProcessNameLocked(app);
16436            startProcessLocked(app, "restart", app.processName);
16437            return true;
16438        } else if (app.pid > 0 && app.pid != MY_PID) {
16439            // Goodbye!
16440            boolean removed;
16441            synchronized (mPidsSelfLocked) {
16442                mPidsSelfLocked.remove(app.pid);
16443                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16444            }
16445            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16446            if (app.isolated) {
16447                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16448            }
16449            app.setPid(0);
16450        }
16451        return false;
16452    }
16453
16454    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16455        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16456            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16457            if (cpr.launchingApp == app) {
16458                return true;
16459            }
16460        }
16461        return false;
16462    }
16463
16464    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16465        // Look through the content providers we are waiting to have launched,
16466        // and if any run in this process then either schedule a restart of
16467        // the process or kill the client waiting for it if this process has
16468        // gone bad.
16469        boolean restart = false;
16470        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16471            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16472            if (cpr.launchingApp == app) {
16473                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16474                    restart = true;
16475                } else {
16476                    removeDyingProviderLocked(app, cpr, true);
16477                }
16478            }
16479        }
16480        return restart;
16481    }
16482
16483    // =========================================================
16484    // SERVICES
16485    // =========================================================
16486
16487    @Override
16488    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16489            int flags) {
16490        enforceNotIsolatedCaller("getServices");
16491        synchronized (this) {
16492            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16493        }
16494    }
16495
16496    @Override
16497    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16498        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16499        synchronized (this) {
16500            return mServices.getRunningServiceControlPanelLocked(name);
16501        }
16502    }
16503
16504    @Override
16505    public ComponentName startService(IApplicationThread caller, Intent service,
16506            String resolvedType, String callingPackage, int userId)
16507            throws TransactionTooLargeException {
16508        enforceNotIsolatedCaller("startService");
16509        // Refuse possible leaked file descriptors
16510        if (service != null && service.hasFileDescriptors() == true) {
16511            throw new IllegalArgumentException("File descriptors passed in Intent");
16512        }
16513
16514        if (callingPackage == null) {
16515            throw new IllegalArgumentException("callingPackage cannot be null");
16516        }
16517
16518        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16519                "startService: " + service + " type=" + resolvedType);
16520        synchronized(this) {
16521            final int callingPid = Binder.getCallingPid();
16522            final int callingUid = Binder.getCallingUid();
16523            final long origId = Binder.clearCallingIdentity();
16524            ComponentName res = mServices.startServiceLocked(caller, service,
16525                    resolvedType, callingPid, callingUid, callingPackage, userId);
16526            Binder.restoreCallingIdentity(origId);
16527            return res;
16528        }
16529    }
16530
16531    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16532            String callingPackage, int userId)
16533            throws TransactionTooLargeException {
16534        synchronized(this) {
16535            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16536                    "startServiceInPackage: " + service + " type=" + resolvedType);
16537            final long origId = Binder.clearCallingIdentity();
16538            ComponentName res = mServices.startServiceLocked(null, service,
16539                    resolvedType, -1, uid, callingPackage, userId);
16540            Binder.restoreCallingIdentity(origId);
16541            return res;
16542        }
16543    }
16544
16545    @Override
16546    public int stopService(IApplicationThread caller, Intent service,
16547            String resolvedType, int userId) {
16548        enforceNotIsolatedCaller("stopService");
16549        // Refuse possible leaked file descriptors
16550        if (service != null && service.hasFileDescriptors() == true) {
16551            throw new IllegalArgumentException("File descriptors passed in Intent");
16552        }
16553
16554        synchronized(this) {
16555            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16556        }
16557    }
16558
16559    @Override
16560    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16561        enforceNotIsolatedCaller("peekService");
16562        // Refuse possible leaked file descriptors
16563        if (service != null && service.hasFileDescriptors() == true) {
16564            throw new IllegalArgumentException("File descriptors passed in Intent");
16565        }
16566
16567        if (callingPackage == null) {
16568            throw new IllegalArgumentException("callingPackage cannot be null");
16569        }
16570
16571        synchronized(this) {
16572            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16573        }
16574    }
16575
16576    @Override
16577    public boolean stopServiceToken(ComponentName className, IBinder token,
16578            int startId) {
16579        synchronized(this) {
16580            return mServices.stopServiceTokenLocked(className, token, startId);
16581        }
16582    }
16583
16584    @Override
16585    public void setServiceForeground(ComponentName className, IBinder token,
16586            int id, Notification notification, int flags) {
16587        synchronized(this) {
16588            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16589        }
16590    }
16591
16592    @Override
16593    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16594            boolean requireFull, String name, String callerPackage) {
16595        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16596                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16597    }
16598
16599    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16600            String className, int flags) {
16601        boolean result = false;
16602        // For apps that don't have pre-defined UIDs, check for permission
16603        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16604            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16605                if (ActivityManager.checkUidPermission(
16606                        INTERACT_ACROSS_USERS,
16607                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16608                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16609                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16610                            + " requests FLAG_SINGLE_USER, but app does not hold "
16611                            + INTERACT_ACROSS_USERS;
16612                    Slog.w(TAG, msg);
16613                    throw new SecurityException(msg);
16614                }
16615                // Permission passed
16616                result = true;
16617            }
16618        } else if ("system".equals(componentProcessName)) {
16619            result = true;
16620        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16621            // Phone app and persistent apps are allowed to export singleuser providers.
16622            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16623                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16624        }
16625        if (DEBUG_MU) Slog.v(TAG_MU,
16626                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16627                + Integer.toHexString(flags) + ") = " + result);
16628        return result;
16629    }
16630
16631    /**
16632     * Checks to see if the caller is in the same app as the singleton
16633     * component, or the component is in a special app. It allows special apps
16634     * to export singleton components but prevents exporting singleton
16635     * components for regular apps.
16636     */
16637    boolean isValidSingletonCall(int callingUid, int componentUid) {
16638        int componentAppId = UserHandle.getAppId(componentUid);
16639        return UserHandle.isSameApp(callingUid, componentUid)
16640                || componentAppId == Process.SYSTEM_UID
16641                || componentAppId == Process.PHONE_UID
16642                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16643                        == PackageManager.PERMISSION_GRANTED;
16644    }
16645
16646    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16647            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16648            int userId) throws TransactionTooLargeException {
16649        enforceNotIsolatedCaller("bindService");
16650
16651        // Refuse possible leaked file descriptors
16652        if (service != null && service.hasFileDescriptors() == true) {
16653            throw new IllegalArgumentException("File descriptors passed in Intent");
16654        }
16655
16656        if (callingPackage == null) {
16657            throw new IllegalArgumentException("callingPackage cannot be null");
16658        }
16659
16660        synchronized(this) {
16661            return mServices.bindServiceLocked(caller, token, service,
16662                    resolvedType, connection, flags, callingPackage, userId);
16663        }
16664    }
16665
16666    public boolean unbindService(IServiceConnection connection) {
16667        synchronized (this) {
16668            return mServices.unbindServiceLocked(connection);
16669        }
16670    }
16671
16672    public void publishService(IBinder token, Intent intent, IBinder service) {
16673        // Refuse possible leaked file descriptors
16674        if (intent != null && intent.hasFileDescriptors() == true) {
16675            throw new IllegalArgumentException("File descriptors passed in Intent");
16676        }
16677
16678        synchronized(this) {
16679            if (!(token instanceof ServiceRecord)) {
16680                throw new IllegalArgumentException("Invalid service token");
16681            }
16682            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16683        }
16684    }
16685
16686    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16687        // Refuse possible leaked file descriptors
16688        if (intent != null && intent.hasFileDescriptors() == true) {
16689            throw new IllegalArgumentException("File descriptors passed in Intent");
16690        }
16691
16692        synchronized(this) {
16693            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16694        }
16695    }
16696
16697    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16698        synchronized(this) {
16699            if (!(token instanceof ServiceRecord)) {
16700                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16701                throw new IllegalArgumentException("Invalid service token");
16702            }
16703            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16704        }
16705    }
16706
16707    // =========================================================
16708    // BACKUP AND RESTORE
16709    // =========================================================
16710
16711    // Cause the target app to be launched if necessary and its backup agent
16712    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16713    // activity manager to announce its creation.
16714    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16715        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16716                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16717        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16718
16719        synchronized(this) {
16720            // !!! TODO: currently no check here that we're already bound
16721            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16722            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16723            synchronized (stats) {
16724                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16725            }
16726
16727            // Backup agent is now in use, its package can't be stopped.
16728            try {
16729                AppGlobals.getPackageManager().setPackageStoppedState(
16730                        app.packageName, false, UserHandle.getUserId(app.uid));
16731            } catch (RemoteException e) {
16732            } catch (IllegalArgumentException e) {
16733                Slog.w(TAG, "Failed trying to unstop package "
16734                        + app.packageName + ": " + e);
16735            }
16736
16737            BackupRecord r = new BackupRecord(ss, app, backupMode);
16738            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16739                    ? new ComponentName(app.packageName, app.backupAgentName)
16740                    : new ComponentName("android", "FullBackupAgent");
16741            // startProcessLocked() returns existing proc's record if it's already running
16742            ProcessRecord proc = startProcessLocked(app.processName, app,
16743                    false, 0, "backup", hostingName, false, false, false);
16744            if (proc == null) {
16745                Slog.e(TAG, "Unable to start backup agent process " + r);
16746                return false;
16747            }
16748
16749            r.app = proc;
16750            mBackupTarget = r;
16751            mBackupAppName = app.packageName;
16752
16753            // Try not to kill the process during backup
16754            updateOomAdjLocked(proc);
16755
16756            // If the process is already attached, schedule the creation of the backup agent now.
16757            // If it is not yet live, this will be done when it attaches to the framework.
16758            if (proc.thread != null) {
16759                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16760                try {
16761                    proc.thread.scheduleCreateBackupAgent(app,
16762                            compatibilityInfoForPackageLocked(app), backupMode);
16763                } catch (RemoteException e) {
16764                    // Will time out on the backup manager side
16765                }
16766            } else {
16767                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16768            }
16769            // Invariants: at this point, the target app process exists and the application
16770            // is either already running or in the process of coming up.  mBackupTarget and
16771            // mBackupAppName describe the app, so that when it binds back to the AM we
16772            // know that it's scheduled for a backup-agent operation.
16773        }
16774
16775        return true;
16776    }
16777
16778    @Override
16779    public void clearPendingBackup() {
16780        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16781        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16782
16783        synchronized (this) {
16784            mBackupTarget = null;
16785            mBackupAppName = null;
16786        }
16787    }
16788
16789    // A backup agent has just come up
16790    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16791        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16792                + " = " + agent);
16793
16794        synchronized(this) {
16795            if (!agentPackageName.equals(mBackupAppName)) {
16796                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16797                return;
16798            }
16799        }
16800
16801        long oldIdent = Binder.clearCallingIdentity();
16802        try {
16803            IBackupManager bm = IBackupManager.Stub.asInterface(
16804                    ServiceManager.getService(Context.BACKUP_SERVICE));
16805            bm.agentConnected(agentPackageName, agent);
16806        } catch (RemoteException e) {
16807            // can't happen; the backup manager service is local
16808        } catch (Exception e) {
16809            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16810            e.printStackTrace();
16811        } finally {
16812            Binder.restoreCallingIdentity(oldIdent);
16813        }
16814    }
16815
16816    // done with this agent
16817    public void unbindBackupAgent(ApplicationInfo appInfo) {
16818        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16819        if (appInfo == null) {
16820            Slog.w(TAG, "unbind backup agent for null app");
16821            return;
16822        }
16823
16824        synchronized(this) {
16825            try {
16826                if (mBackupAppName == null) {
16827                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16828                    return;
16829                }
16830
16831                if (!mBackupAppName.equals(appInfo.packageName)) {
16832                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16833                    return;
16834                }
16835
16836                // Not backing this app up any more; reset its OOM adjustment
16837                final ProcessRecord proc = mBackupTarget.app;
16838                updateOomAdjLocked(proc);
16839
16840                // If the app crashed during backup, 'thread' will be null here
16841                if (proc.thread != null) {
16842                    try {
16843                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16844                                compatibilityInfoForPackageLocked(appInfo));
16845                    } catch (Exception e) {
16846                        Slog.e(TAG, "Exception when unbinding backup agent:");
16847                        e.printStackTrace();
16848                    }
16849                }
16850            } finally {
16851                mBackupTarget = null;
16852                mBackupAppName = null;
16853            }
16854        }
16855    }
16856    // =========================================================
16857    // BROADCASTS
16858    // =========================================================
16859
16860    boolean isPendingBroadcastProcessLocked(int pid) {
16861        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16862                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16863    }
16864
16865    void skipPendingBroadcastLocked(int pid) {
16866            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16867            for (BroadcastQueue queue : mBroadcastQueues) {
16868                queue.skipPendingBroadcastLocked(pid);
16869            }
16870    }
16871
16872    // The app just attached; send any pending broadcasts that it should receive
16873    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16874        boolean didSomething = false;
16875        for (BroadcastQueue queue : mBroadcastQueues) {
16876            didSomething |= queue.sendPendingBroadcastsLocked(app);
16877        }
16878        return didSomething;
16879    }
16880
16881    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16882            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16883        enforceNotIsolatedCaller("registerReceiver");
16884        ArrayList<Intent> stickyIntents = null;
16885        ProcessRecord callerApp = null;
16886        int callingUid;
16887        int callingPid;
16888        synchronized(this) {
16889            if (caller != null) {
16890                callerApp = getRecordForAppLocked(caller);
16891                if (callerApp == null) {
16892                    throw new SecurityException(
16893                            "Unable to find app for caller " + caller
16894                            + " (pid=" + Binder.getCallingPid()
16895                            + ") when registering receiver " + receiver);
16896                }
16897                if (callerApp.info.uid != Process.SYSTEM_UID &&
16898                        !callerApp.pkgList.containsKey(callerPackage) &&
16899                        !"android".equals(callerPackage)) {
16900                    throw new SecurityException("Given caller package " + callerPackage
16901                            + " is not running in process " + callerApp);
16902                }
16903                callingUid = callerApp.info.uid;
16904                callingPid = callerApp.pid;
16905            } else {
16906                callerPackage = null;
16907                callingUid = Binder.getCallingUid();
16908                callingPid = Binder.getCallingPid();
16909            }
16910
16911            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16912                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16913
16914            Iterator<String> actions = filter.actionsIterator();
16915            if (actions == null) {
16916                ArrayList<String> noAction = new ArrayList<String>(1);
16917                noAction.add(null);
16918                actions = noAction.iterator();
16919            }
16920
16921            // Collect stickies of users
16922            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16923            while (actions.hasNext()) {
16924                String action = actions.next();
16925                for (int id : userIds) {
16926                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16927                    if (stickies != null) {
16928                        ArrayList<Intent> intents = stickies.get(action);
16929                        if (intents != null) {
16930                            if (stickyIntents == null) {
16931                                stickyIntents = new ArrayList<Intent>();
16932                            }
16933                            stickyIntents.addAll(intents);
16934                        }
16935                    }
16936                }
16937            }
16938        }
16939
16940        ArrayList<Intent> allSticky = null;
16941        if (stickyIntents != null) {
16942            final ContentResolver resolver = mContext.getContentResolver();
16943            // Look for any matching sticky broadcasts...
16944            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16945                Intent intent = stickyIntents.get(i);
16946                // If intent has scheme "content", it will need to acccess
16947                // provider that needs to lock mProviderMap in ActivityThread
16948                // and also it may need to wait application response, so we
16949                // cannot lock ActivityManagerService here.
16950                if (filter.match(resolver, intent, true, TAG) >= 0) {
16951                    if (allSticky == null) {
16952                        allSticky = new ArrayList<Intent>();
16953                    }
16954                    allSticky.add(intent);
16955                }
16956            }
16957        }
16958
16959        // The first sticky in the list is returned directly back to the client.
16960        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16961        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16962        if (receiver == null) {
16963            return sticky;
16964        }
16965
16966        synchronized (this) {
16967            if (callerApp != null && (callerApp.thread == null
16968                    || callerApp.thread.asBinder() != caller.asBinder())) {
16969                // Original caller already died
16970                return null;
16971            }
16972            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16973            if (rl == null) {
16974                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16975                        userId, receiver);
16976                if (rl.app != null) {
16977                    rl.app.receivers.add(rl);
16978                } else {
16979                    try {
16980                        receiver.asBinder().linkToDeath(rl, 0);
16981                    } catch (RemoteException e) {
16982                        return sticky;
16983                    }
16984                    rl.linkedToDeath = true;
16985                }
16986                mRegisteredReceivers.put(receiver.asBinder(), rl);
16987            } else if (rl.uid != callingUid) {
16988                throw new IllegalArgumentException(
16989                        "Receiver requested to register for uid " + callingUid
16990                        + " was previously registered for uid " + rl.uid);
16991            } else if (rl.pid != callingPid) {
16992                throw new IllegalArgumentException(
16993                        "Receiver requested to register for pid " + callingPid
16994                        + " was previously registered for pid " + rl.pid);
16995            } else if (rl.userId != userId) {
16996                throw new IllegalArgumentException(
16997                        "Receiver requested to register for user " + userId
16998                        + " was previously registered for user " + rl.userId);
16999            }
17000            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17001                    permission, callingUid, userId);
17002            rl.add(bf);
17003            if (!bf.debugCheck()) {
17004                Slog.w(TAG, "==> For Dynamic broadcast");
17005            }
17006            mReceiverResolver.addFilter(bf);
17007
17008            // Enqueue broadcasts for all existing stickies that match
17009            // this filter.
17010            if (allSticky != null) {
17011                ArrayList receivers = new ArrayList();
17012                receivers.add(bf);
17013
17014                final int stickyCount = allSticky.size();
17015                for (int i = 0; i < stickyCount; i++) {
17016                    Intent intent = allSticky.get(i);
17017                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17018                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17019                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17020                            null, 0, null, null, false, true, true, -1);
17021                    queue.enqueueParallelBroadcastLocked(r);
17022                    queue.scheduleBroadcastsLocked();
17023                }
17024            }
17025
17026            return sticky;
17027        }
17028    }
17029
17030    public void unregisterReceiver(IIntentReceiver receiver) {
17031        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17032
17033        final long origId = Binder.clearCallingIdentity();
17034        try {
17035            boolean doTrim = false;
17036
17037            synchronized(this) {
17038                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17039                if (rl != null) {
17040                    final BroadcastRecord r = rl.curBroadcast;
17041                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17042                        final boolean doNext = r.queue.finishReceiverLocked(
17043                                r, r.resultCode, r.resultData, r.resultExtras,
17044                                r.resultAbort, false);
17045                        if (doNext) {
17046                            doTrim = true;
17047                            r.queue.processNextBroadcast(false);
17048                        }
17049                    }
17050
17051                    if (rl.app != null) {
17052                        rl.app.receivers.remove(rl);
17053                    }
17054                    removeReceiverLocked(rl);
17055                    if (rl.linkedToDeath) {
17056                        rl.linkedToDeath = false;
17057                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17058                    }
17059                }
17060            }
17061
17062            // If we actually concluded any broadcasts, we might now be able
17063            // to trim the recipients' apps from our working set
17064            if (doTrim) {
17065                trimApplications();
17066                return;
17067            }
17068
17069        } finally {
17070            Binder.restoreCallingIdentity(origId);
17071        }
17072    }
17073
17074    void removeReceiverLocked(ReceiverList rl) {
17075        mRegisteredReceivers.remove(rl.receiver.asBinder());
17076        for (int i = rl.size() - 1; i >= 0; i--) {
17077            mReceiverResolver.removeFilter(rl.get(i));
17078        }
17079    }
17080
17081    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17082        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17083            ProcessRecord r = mLruProcesses.get(i);
17084            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17085                try {
17086                    r.thread.dispatchPackageBroadcast(cmd, packages);
17087                } catch (RemoteException ex) {
17088                }
17089            }
17090        }
17091    }
17092
17093    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17094            int callingUid, int[] users) {
17095        // TODO: come back and remove this assumption to triage all broadcasts
17096        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17097
17098        List<ResolveInfo> receivers = null;
17099        try {
17100            HashSet<ComponentName> singleUserReceivers = null;
17101            boolean scannedFirstReceivers = false;
17102            for (int user : users) {
17103                // Skip users that have Shell restrictions, with exception of always permitted
17104                // Shell broadcasts
17105                if (callingUid == Process.SHELL_UID
17106                        && mUserController.hasUserRestriction(
17107                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17108                        && !isPermittedShellBroadcast(intent)) {
17109                    continue;
17110                }
17111                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17112                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17113                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17114                    // If this is not the system user, we need to check for
17115                    // any receivers that should be filtered out.
17116                    for (int i=0; i<newReceivers.size(); i++) {
17117                        ResolveInfo ri = newReceivers.get(i);
17118                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17119                            newReceivers.remove(i);
17120                            i--;
17121                        }
17122                    }
17123                }
17124                if (newReceivers != null && newReceivers.size() == 0) {
17125                    newReceivers = null;
17126                }
17127                if (receivers == null) {
17128                    receivers = newReceivers;
17129                } else if (newReceivers != null) {
17130                    // We need to concatenate the additional receivers
17131                    // found with what we have do far.  This would be easy,
17132                    // but we also need to de-dup any receivers that are
17133                    // singleUser.
17134                    if (!scannedFirstReceivers) {
17135                        // Collect any single user receivers we had already retrieved.
17136                        scannedFirstReceivers = true;
17137                        for (int i=0; i<receivers.size(); i++) {
17138                            ResolveInfo ri = receivers.get(i);
17139                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17140                                ComponentName cn = new ComponentName(
17141                                        ri.activityInfo.packageName, ri.activityInfo.name);
17142                                if (singleUserReceivers == null) {
17143                                    singleUserReceivers = new HashSet<ComponentName>();
17144                                }
17145                                singleUserReceivers.add(cn);
17146                            }
17147                        }
17148                    }
17149                    // Add the new results to the existing results, tracking
17150                    // and de-dupping single user receivers.
17151                    for (int i=0; i<newReceivers.size(); i++) {
17152                        ResolveInfo ri = newReceivers.get(i);
17153                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17154                            ComponentName cn = new ComponentName(
17155                                    ri.activityInfo.packageName, ri.activityInfo.name);
17156                            if (singleUserReceivers == null) {
17157                                singleUserReceivers = new HashSet<ComponentName>();
17158                            }
17159                            if (!singleUserReceivers.contains(cn)) {
17160                                singleUserReceivers.add(cn);
17161                                receivers.add(ri);
17162                            }
17163                        } else {
17164                            receivers.add(ri);
17165                        }
17166                    }
17167                }
17168            }
17169        } catch (RemoteException ex) {
17170            // pm is in same process, this will never happen.
17171        }
17172        return receivers;
17173    }
17174
17175    private boolean isPermittedShellBroadcast(Intent intent) {
17176        // remote bugreport should always be allowed to be taken
17177        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17178    }
17179
17180    final int broadcastIntentLocked(ProcessRecord callerApp,
17181            String callerPackage, Intent intent, String resolvedType,
17182            IIntentReceiver resultTo, int resultCode, String resultData,
17183            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17184            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17185        intent = new Intent(intent);
17186
17187        // By default broadcasts do not go to stopped apps.
17188        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17189
17190        // If we have not finished booting, don't allow this to launch new processes.
17191        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17192            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17193        }
17194
17195        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17196                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17197                + " ordered=" + ordered + " userid=" + userId);
17198        if ((resultTo != null) && !ordered) {
17199            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17200        }
17201
17202        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17203                ALLOW_NON_FULL, "broadcast", callerPackage);
17204
17205        // Make sure that the user who is receiving this broadcast is running.
17206        // If not, we will just skip it. Make an exception for shutdown broadcasts
17207        // and upgrade steps.
17208
17209        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17210            if ((callingUid != Process.SYSTEM_UID
17211                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17212                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17213                Slog.w(TAG, "Skipping broadcast of " + intent
17214                        + ": user " + userId + " is stopped");
17215                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17216            }
17217        }
17218
17219        BroadcastOptions brOptions = null;
17220        if (bOptions != null) {
17221            brOptions = new BroadcastOptions(bOptions);
17222            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17223                // See if the caller is allowed to do this.  Note we are checking against
17224                // the actual real caller (not whoever provided the operation as say a
17225                // PendingIntent), because that who is actually supplied the arguments.
17226                if (checkComponentPermission(
17227                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17228                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17229                        != PackageManager.PERMISSION_GRANTED) {
17230                    String msg = "Permission Denial: " + intent.getAction()
17231                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17232                            + ", uid=" + callingUid + ")"
17233                            + " requires "
17234                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17235                    Slog.w(TAG, msg);
17236                    throw new SecurityException(msg);
17237                }
17238            }
17239        }
17240
17241        // Verify that protected broadcasts are only being sent by system code,
17242        // and that system code is only sending protected broadcasts.
17243        final String action = intent.getAction();
17244        final boolean isProtectedBroadcast;
17245        try {
17246            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17247        } catch (RemoteException e) {
17248            Slog.w(TAG, "Remote exception", e);
17249            return ActivityManager.BROADCAST_SUCCESS;
17250        }
17251
17252        final boolean isCallerSystem;
17253        switch (UserHandle.getAppId(callingUid)) {
17254            case Process.ROOT_UID:
17255            case Process.SYSTEM_UID:
17256            case Process.PHONE_UID:
17257            case Process.BLUETOOTH_UID:
17258            case Process.NFC_UID:
17259                isCallerSystem = true;
17260                break;
17261            default:
17262                isCallerSystem = (callerApp != null) && callerApp.persistent;
17263                break;
17264        }
17265
17266        if (isCallerSystem) {
17267            if (isProtectedBroadcast
17268                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17269                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17270                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17271                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17272                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17273                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17274                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17275                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17276                // Broadcast is either protected, or it's a public action that
17277                // we've relaxed, so it's fine for system internals to send.
17278            } else {
17279                // The vast majority of broadcasts sent from system internals
17280                // should be protected to avoid security holes, so yell loudly
17281                // to ensure we examine these cases.
17282                Log.wtf(TAG, "Sending non-protected broadcast " + action
17283                        + " from system", new Throwable());
17284            }
17285
17286        } else {
17287            if (isProtectedBroadcast) {
17288                String msg = "Permission Denial: not allowed to send broadcast "
17289                        + action + " from pid="
17290                        + callingPid + ", uid=" + callingUid;
17291                Slog.w(TAG, msg);
17292                throw new SecurityException(msg);
17293
17294            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17295                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17296                // Special case for compatibility: we don't want apps to send this,
17297                // but historically it has not been protected and apps may be using it
17298                // to poke their own app widget.  So, instead of making it protected,
17299                // just limit it to the caller.
17300                if (callerPackage == null) {
17301                    String msg = "Permission Denial: not allowed to send broadcast "
17302                            + action + " from unknown caller.";
17303                    Slog.w(TAG, msg);
17304                    throw new SecurityException(msg);
17305                } else if (intent.getComponent() != null) {
17306                    // They are good enough to send to an explicit component...  verify
17307                    // it is being sent to the calling app.
17308                    if (!intent.getComponent().getPackageName().equals(
17309                            callerPackage)) {
17310                        String msg = "Permission Denial: not allowed to send broadcast "
17311                                + action + " to "
17312                                + intent.getComponent().getPackageName() + " from "
17313                                + callerPackage;
17314                        Slog.w(TAG, msg);
17315                        throw new SecurityException(msg);
17316                    }
17317                } else {
17318                    // Limit broadcast to their own package.
17319                    intent.setPackage(callerPackage);
17320                }
17321            }
17322        }
17323
17324        if (action != null) {
17325            switch (action) {
17326                case Intent.ACTION_UID_REMOVED:
17327                case Intent.ACTION_PACKAGE_REMOVED:
17328                case Intent.ACTION_PACKAGE_CHANGED:
17329                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17330                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17331                case Intent.ACTION_PACKAGES_SUSPENDED:
17332                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17333                    // Handle special intents: if this broadcast is from the package
17334                    // manager about a package being removed, we need to remove all of
17335                    // its activities from the history stack.
17336                    if (checkComponentPermission(
17337                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17338                            callingPid, callingUid, -1, true)
17339                            != PackageManager.PERMISSION_GRANTED) {
17340                        String msg = "Permission Denial: " + intent.getAction()
17341                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17342                                + ", uid=" + callingUid + ")"
17343                                + " requires "
17344                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17345                        Slog.w(TAG, msg);
17346                        throw new SecurityException(msg);
17347                    }
17348                    switch (action) {
17349                        case Intent.ACTION_UID_REMOVED:
17350                            final Bundle intentExtras = intent.getExtras();
17351                            final int uid = intentExtras != null
17352                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17353                            if (uid >= 0) {
17354                                mBatteryStatsService.removeUid(uid);
17355                                mAppOpsService.uidRemoved(uid);
17356                            }
17357                            break;
17358                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17359                            // If resources are unavailable just force stop all those packages
17360                            // and flush the attribute cache as well.
17361                            String list[] =
17362                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17363                            if (list != null && list.length > 0) {
17364                                for (int i = 0; i < list.length; i++) {
17365                                    forceStopPackageLocked(list[i], -1, false, true, true,
17366                                            false, false, userId, "storage unmount");
17367                                }
17368                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17369                                sendPackageBroadcastLocked(
17370                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17371                                        userId);
17372                            }
17373                            break;
17374                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17375                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17376                            break;
17377                        case Intent.ACTION_PACKAGE_REMOVED:
17378                        case Intent.ACTION_PACKAGE_CHANGED:
17379                            Uri data = intent.getData();
17380                            String ssp;
17381                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17382                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17383                                final boolean replacing =
17384                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17385                                final boolean killProcess =
17386                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17387                                final boolean fullUninstall = removed && !replacing;
17388                                if (killProcess) {
17389                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17390                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17391                                            false, true, true, false, fullUninstall, userId,
17392                                            removed ? "pkg removed" : "pkg changed");
17393                                }
17394                                if (removed) {
17395                                    final int cmd = killProcess
17396                                            ? IApplicationThread.PACKAGE_REMOVED
17397                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17398                                    sendPackageBroadcastLocked(cmd,
17399                                            new String[] {ssp}, userId);
17400                                    if (fullUninstall) {
17401                                        mAppOpsService.packageRemoved(
17402                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17403
17404                                        // Remove all permissions granted from/to this package
17405                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17406
17407                                        removeTasksByPackageNameLocked(ssp, userId);
17408                                        mBatteryStatsService.notePackageUninstalled(ssp);
17409                                    }
17410                                } else {
17411                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17412                                            intent.getStringArrayExtra(
17413                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17414                                }
17415                            }
17416                            break;
17417                        case Intent.ACTION_PACKAGES_SUSPENDED:
17418                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17419                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17420                                    intent.getAction());
17421                            final String[] packageNames = intent.getStringArrayExtra(
17422                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17423                            final int userHandle = intent.getIntExtra(
17424                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17425
17426                            synchronized(ActivityManagerService.this) {
17427                                mRecentTasks.onPackagesSuspendedChanged(
17428                                        packageNames, suspended, userHandle);
17429                            }
17430                            break;
17431                    }
17432                    break;
17433                case Intent.ACTION_PACKAGE_REPLACED:
17434                {
17435                    final Uri data = intent.getData();
17436                    final String ssp;
17437                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17438                        final ApplicationInfo aInfo =
17439                                getPackageManagerInternalLocked().getApplicationInfo(
17440                                        ssp,
17441                                        userId);
17442                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17443                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17444                                new String[] {ssp}, userId);
17445                    }
17446                    break;
17447                }
17448                case Intent.ACTION_PACKAGE_ADDED:
17449                {
17450                    // Special case for adding a package: by default turn on compatibility mode.
17451                    Uri data = intent.getData();
17452                    String ssp;
17453                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17454                        final boolean replacing =
17455                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17456                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17457
17458                        try {
17459                            ApplicationInfo ai = AppGlobals.getPackageManager().
17460                                    getApplicationInfo(ssp, 0, 0);
17461                            mBatteryStatsService.notePackageInstalled(ssp,
17462                                    ai != null ? ai.versionCode : 0);
17463                        } catch (RemoteException e) {
17464                        }
17465                    }
17466                    break;
17467                }
17468                case Intent.ACTION_TIMEZONE_CHANGED:
17469                    // If this is the time zone changed action, queue up a message that will reset
17470                    // the timezone of all currently running processes. This message will get
17471                    // queued up before the broadcast happens.
17472                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17473                    break;
17474                case Intent.ACTION_TIME_CHANGED:
17475                    // If the user set the time, let all running processes know.
17476                    final int is24Hour =
17477                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17478                                    : 0;
17479                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17480                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17481                    synchronized (stats) {
17482                        stats.noteCurrentTimeChangedLocked();
17483                    }
17484                    break;
17485                case Intent.ACTION_CLEAR_DNS_CACHE:
17486                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17487                    break;
17488                case Proxy.PROXY_CHANGE_ACTION:
17489                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17490                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17491                    break;
17492                case android.hardware.Camera.ACTION_NEW_PICTURE:
17493                case android.hardware.Camera.ACTION_NEW_VIDEO:
17494                    // These broadcasts are no longer allowed by the system, since they can
17495                    // cause significant thrashing at a crictical point (using the camera).
17496                    // Apps should use JobScehduler to monitor for media provider changes.
17497                    Slog.w(TAG, action + " no longer allowed; dropping from "
17498                            + UserHandle.formatUid(callingUid));
17499                    // Lie; we don't want to crash the app.
17500                    return ActivityManager.BROADCAST_SUCCESS;
17501            }
17502        }
17503
17504        // Add to the sticky list if requested.
17505        if (sticky) {
17506            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17507                    callingPid, callingUid)
17508                    != PackageManager.PERMISSION_GRANTED) {
17509                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17510                        + callingPid + ", uid=" + callingUid
17511                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17512                Slog.w(TAG, msg);
17513                throw new SecurityException(msg);
17514            }
17515            if (requiredPermissions != null && requiredPermissions.length > 0) {
17516                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17517                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17518                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17519            }
17520            if (intent.getComponent() != null) {
17521                throw new SecurityException(
17522                        "Sticky broadcasts can't target a specific component");
17523            }
17524            // We use userId directly here, since the "all" target is maintained
17525            // as a separate set of sticky broadcasts.
17526            if (userId != UserHandle.USER_ALL) {
17527                // But first, if this is not a broadcast to all users, then
17528                // make sure it doesn't conflict with an existing broadcast to
17529                // all users.
17530                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17531                        UserHandle.USER_ALL);
17532                if (stickies != null) {
17533                    ArrayList<Intent> list = stickies.get(intent.getAction());
17534                    if (list != null) {
17535                        int N = list.size();
17536                        int i;
17537                        for (i=0; i<N; i++) {
17538                            if (intent.filterEquals(list.get(i))) {
17539                                throw new IllegalArgumentException(
17540                                        "Sticky broadcast " + intent + " for user "
17541                                        + userId + " conflicts with existing global broadcast");
17542                            }
17543                        }
17544                    }
17545                }
17546            }
17547            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17548            if (stickies == null) {
17549                stickies = new ArrayMap<>();
17550                mStickyBroadcasts.put(userId, stickies);
17551            }
17552            ArrayList<Intent> list = stickies.get(intent.getAction());
17553            if (list == null) {
17554                list = new ArrayList<>();
17555                stickies.put(intent.getAction(), list);
17556            }
17557            final int stickiesCount = list.size();
17558            int i;
17559            for (i = 0; i < stickiesCount; i++) {
17560                if (intent.filterEquals(list.get(i))) {
17561                    // This sticky already exists, replace it.
17562                    list.set(i, new Intent(intent));
17563                    break;
17564                }
17565            }
17566            if (i >= stickiesCount) {
17567                list.add(new Intent(intent));
17568            }
17569        }
17570
17571        int[] users;
17572        if (userId == UserHandle.USER_ALL) {
17573            // Caller wants broadcast to go to all started users.
17574            users = mUserController.getStartedUserArrayLocked();
17575        } else {
17576            // Caller wants broadcast to go to one specific user.
17577            users = new int[] {userId};
17578        }
17579
17580        // Figure out who all will receive this broadcast.
17581        List receivers = null;
17582        List<BroadcastFilter> registeredReceivers = null;
17583        // Need to resolve the intent to interested receivers...
17584        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17585                 == 0) {
17586            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17587        }
17588        if (intent.getComponent() == null) {
17589            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17590                // Query one target user at a time, excluding shell-restricted users
17591                for (int i = 0; i < users.length; i++) {
17592                    if (mUserController.hasUserRestriction(
17593                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17594                        continue;
17595                    }
17596                    List<BroadcastFilter> registeredReceiversForUser =
17597                            mReceiverResolver.queryIntent(intent,
17598                                    resolvedType, false, users[i]);
17599                    if (registeredReceivers == null) {
17600                        registeredReceivers = registeredReceiversForUser;
17601                    } else if (registeredReceiversForUser != null) {
17602                        registeredReceivers.addAll(registeredReceiversForUser);
17603                    }
17604                }
17605            } else {
17606                registeredReceivers = mReceiverResolver.queryIntent(intent,
17607                        resolvedType, false, userId);
17608            }
17609        }
17610
17611        final boolean replacePending =
17612                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17613
17614        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17615                + " replacePending=" + replacePending);
17616
17617        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17618        if (!ordered && NR > 0) {
17619            // If we are not serializing this broadcast, then send the
17620            // registered receivers separately so they don't wait for the
17621            // components to be launched.
17622            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17623            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17624                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17625                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17626                    resultExtras, ordered, sticky, false, userId);
17627            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17628            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17629            if (!replaced) {
17630                queue.enqueueParallelBroadcastLocked(r);
17631                queue.scheduleBroadcastsLocked();
17632            }
17633            registeredReceivers = null;
17634            NR = 0;
17635        }
17636
17637        // Merge into one list.
17638        int ir = 0;
17639        if (receivers != null) {
17640            // A special case for PACKAGE_ADDED: do not allow the package
17641            // being added to see this broadcast.  This prevents them from
17642            // using this as a back door to get run as soon as they are
17643            // installed.  Maybe in the future we want to have a special install
17644            // broadcast or such for apps, but we'd like to deliberately make
17645            // this decision.
17646            String skipPackages[] = null;
17647            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17648                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17649                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17650                Uri data = intent.getData();
17651                if (data != null) {
17652                    String pkgName = data.getSchemeSpecificPart();
17653                    if (pkgName != null) {
17654                        skipPackages = new String[] { pkgName };
17655                    }
17656                }
17657            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17658                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17659            }
17660            if (skipPackages != null && (skipPackages.length > 0)) {
17661                for (String skipPackage : skipPackages) {
17662                    if (skipPackage != null) {
17663                        int NT = receivers.size();
17664                        for (int it=0; it<NT; it++) {
17665                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17666                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17667                                receivers.remove(it);
17668                                it--;
17669                                NT--;
17670                            }
17671                        }
17672                    }
17673                }
17674            }
17675
17676            int NT = receivers != null ? receivers.size() : 0;
17677            int it = 0;
17678            ResolveInfo curt = null;
17679            BroadcastFilter curr = null;
17680            while (it < NT && ir < NR) {
17681                if (curt == null) {
17682                    curt = (ResolveInfo)receivers.get(it);
17683                }
17684                if (curr == null) {
17685                    curr = registeredReceivers.get(ir);
17686                }
17687                if (curr.getPriority() >= curt.priority) {
17688                    // Insert this broadcast record into the final list.
17689                    receivers.add(it, curr);
17690                    ir++;
17691                    curr = null;
17692                    it++;
17693                    NT++;
17694                } else {
17695                    // Skip to the next ResolveInfo in the final list.
17696                    it++;
17697                    curt = null;
17698                }
17699            }
17700        }
17701        while (ir < NR) {
17702            if (receivers == null) {
17703                receivers = new ArrayList();
17704            }
17705            receivers.add(registeredReceivers.get(ir));
17706            ir++;
17707        }
17708
17709        if ((receivers != null && receivers.size() > 0)
17710                || resultTo != null) {
17711            BroadcastQueue queue = broadcastQueueForIntent(intent);
17712            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17713                    callerPackage, callingPid, callingUid, resolvedType,
17714                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17715                    resultData, resultExtras, ordered, sticky, false, userId);
17716
17717            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17718                    + ": prev had " + queue.mOrderedBroadcasts.size());
17719            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17720                    "Enqueueing broadcast " + r.intent.getAction());
17721
17722            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17723            if (!replaced) {
17724                queue.enqueueOrderedBroadcastLocked(r);
17725                queue.scheduleBroadcastsLocked();
17726            }
17727        }
17728
17729        return ActivityManager.BROADCAST_SUCCESS;
17730    }
17731
17732    final Intent verifyBroadcastLocked(Intent intent) {
17733        // Refuse possible leaked file descriptors
17734        if (intent != null && intent.hasFileDescriptors() == true) {
17735            throw new IllegalArgumentException("File descriptors passed in Intent");
17736        }
17737
17738        int flags = intent.getFlags();
17739
17740        if (!mProcessesReady) {
17741            // if the caller really truly claims to know what they're doing, go
17742            // ahead and allow the broadcast without launching any receivers
17743            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17744                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17745            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17746                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17747                        + " before boot completion");
17748                throw new IllegalStateException("Cannot broadcast before boot completed");
17749            }
17750        }
17751
17752        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17753            throw new IllegalArgumentException(
17754                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17755        }
17756
17757        return intent;
17758    }
17759
17760    public final int broadcastIntent(IApplicationThread caller,
17761            Intent intent, String resolvedType, IIntentReceiver resultTo,
17762            int resultCode, String resultData, Bundle resultExtras,
17763            String[] requiredPermissions, int appOp, Bundle bOptions,
17764            boolean serialized, boolean sticky, int userId) {
17765        enforceNotIsolatedCaller("broadcastIntent");
17766        synchronized(this) {
17767            intent = verifyBroadcastLocked(intent);
17768
17769            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17770            final int callingPid = Binder.getCallingPid();
17771            final int callingUid = Binder.getCallingUid();
17772            final long origId = Binder.clearCallingIdentity();
17773            int res = broadcastIntentLocked(callerApp,
17774                    callerApp != null ? callerApp.info.packageName : null,
17775                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17776                    requiredPermissions, appOp, bOptions, serialized, sticky,
17777                    callingPid, callingUid, userId);
17778            Binder.restoreCallingIdentity(origId);
17779            return res;
17780        }
17781    }
17782
17783
17784    int broadcastIntentInPackage(String packageName, int uid,
17785            Intent intent, String resolvedType, IIntentReceiver resultTo,
17786            int resultCode, String resultData, Bundle resultExtras,
17787            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17788            int userId) {
17789        synchronized(this) {
17790            intent = verifyBroadcastLocked(intent);
17791
17792            final long origId = Binder.clearCallingIdentity();
17793            String[] requiredPermissions = requiredPermission == null ? null
17794                    : new String[] {requiredPermission};
17795            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17796                    resultTo, resultCode, resultData, resultExtras,
17797                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17798                    sticky, -1, uid, userId);
17799            Binder.restoreCallingIdentity(origId);
17800            return res;
17801        }
17802    }
17803
17804    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17805        // Refuse possible leaked file descriptors
17806        if (intent != null && intent.hasFileDescriptors() == true) {
17807            throw new IllegalArgumentException("File descriptors passed in Intent");
17808        }
17809
17810        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17811                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17812
17813        synchronized(this) {
17814            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17815                    != PackageManager.PERMISSION_GRANTED) {
17816                String msg = "Permission Denial: unbroadcastIntent() from pid="
17817                        + Binder.getCallingPid()
17818                        + ", uid=" + Binder.getCallingUid()
17819                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17820                Slog.w(TAG, msg);
17821                throw new SecurityException(msg);
17822            }
17823            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17824            if (stickies != null) {
17825                ArrayList<Intent> list = stickies.get(intent.getAction());
17826                if (list != null) {
17827                    int N = list.size();
17828                    int i;
17829                    for (i=0; i<N; i++) {
17830                        if (intent.filterEquals(list.get(i))) {
17831                            list.remove(i);
17832                            break;
17833                        }
17834                    }
17835                    if (list.size() <= 0) {
17836                        stickies.remove(intent.getAction());
17837                    }
17838                }
17839                if (stickies.size() <= 0) {
17840                    mStickyBroadcasts.remove(userId);
17841                }
17842            }
17843        }
17844    }
17845
17846    void backgroundServicesFinishedLocked(int userId) {
17847        for (BroadcastQueue queue : mBroadcastQueues) {
17848            queue.backgroundServicesFinishedLocked(userId);
17849        }
17850    }
17851
17852    public void finishReceiver(IBinder who, int resultCode, String resultData,
17853            Bundle resultExtras, boolean resultAbort, int flags) {
17854        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17855
17856        // Refuse possible leaked file descriptors
17857        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17858            throw new IllegalArgumentException("File descriptors passed in Bundle");
17859        }
17860
17861        final long origId = Binder.clearCallingIdentity();
17862        try {
17863            boolean doNext = false;
17864            BroadcastRecord r;
17865
17866            synchronized(this) {
17867                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17868                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17869                r = queue.getMatchingOrderedReceiver(who);
17870                if (r != null) {
17871                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17872                        resultData, resultExtras, resultAbort, true);
17873                }
17874            }
17875
17876            if (doNext) {
17877                r.queue.processNextBroadcast(false);
17878            }
17879            trimApplications();
17880        } finally {
17881            Binder.restoreCallingIdentity(origId);
17882        }
17883    }
17884
17885    // =========================================================
17886    // INSTRUMENTATION
17887    // =========================================================
17888
17889    public boolean startInstrumentation(ComponentName className,
17890            String profileFile, int flags, Bundle arguments,
17891            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17892            int userId, String abiOverride) {
17893        enforceNotIsolatedCaller("startInstrumentation");
17894        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17895                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17896        // Refuse possible leaked file descriptors
17897        if (arguments != null && arguments.hasFileDescriptors()) {
17898            throw new IllegalArgumentException("File descriptors passed in Bundle");
17899        }
17900
17901        synchronized(this) {
17902            InstrumentationInfo ii = null;
17903            ApplicationInfo ai = null;
17904            try {
17905                ii = mContext.getPackageManager().getInstrumentationInfo(
17906                    className, STOCK_PM_FLAGS);
17907                ai = AppGlobals.getPackageManager().getApplicationInfo(
17908                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17909            } catch (PackageManager.NameNotFoundException e) {
17910            } catch (RemoteException e) {
17911            }
17912            if (ii == null) {
17913                reportStartInstrumentationFailureLocked(watcher, className,
17914                        "Unable to find instrumentation info for: " + className);
17915                return false;
17916            }
17917            if (ai == null) {
17918                reportStartInstrumentationFailureLocked(watcher, className,
17919                        "Unable to find instrumentation target package: " + ii.targetPackage);
17920                return false;
17921            }
17922            if (!ai.hasCode()) {
17923                reportStartInstrumentationFailureLocked(watcher, className,
17924                        "Instrumentation target has no code: " + ii.targetPackage);
17925                return false;
17926            }
17927
17928            int match = mContext.getPackageManager().checkSignatures(
17929                    ii.targetPackage, ii.packageName);
17930            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17931                String msg = "Permission Denial: starting instrumentation "
17932                        + className + " from pid="
17933                        + Binder.getCallingPid()
17934                        + ", uid=" + Binder.getCallingPid()
17935                        + " not allowed because package " + ii.packageName
17936                        + " does not have a signature matching the target "
17937                        + ii.targetPackage;
17938                reportStartInstrumentationFailureLocked(watcher, className, msg);
17939                throw new SecurityException(msg);
17940            }
17941
17942            final long origId = Binder.clearCallingIdentity();
17943            // Instrumentation can kill and relaunch even persistent processes
17944            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17945                    "start instr");
17946            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17947            app.instrumentationClass = className;
17948            app.instrumentationInfo = ai;
17949            app.instrumentationProfileFile = profileFile;
17950            app.instrumentationArguments = arguments;
17951            app.instrumentationWatcher = watcher;
17952            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17953            app.instrumentationResultClass = className;
17954            Binder.restoreCallingIdentity(origId);
17955        }
17956
17957        return true;
17958    }
17959
17960    /**
17961     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17962     * error to the logs, but if somebody is watching, send the report there too.  This enables
17963     * the "am" command to report errors with more information.
17964     *
17965     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17966     * @param cn The component name of the instrumentation.
17967     * @param report The error report.
17968     */
17969    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17970            ComponentName cn, String report) {
17971        Slog.w(TAG, report);
17972        if (watcher != null) {
17973            Bundle results = new Bundle();
17974            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17975            results.putString("Error", report);
17976            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17977        }
17978    }
17979
17980    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17981        if (app.instrumentationWatcher != null) {
17982            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17983                    app.instrumentationClass, resultCode, results);
17984        }
17985
17986        // Can't call out of the system process with a lock held, so post a message.
17987        if (app.instrumentationUiAutomationConnection != null) {
17988            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17989                    app.instrumentationUiAutomationConnection).sendToTarget();
17990        }
17991
17992        app.instrumentationWatcher = null;
17993        app.instrumentationUiAutomationConnection = null;
17994        app.instrumentationClass = null;
17995        app.instrumentationInfo = null;
17996        app.instrumentationProfileFile = null;
17997        app.instrumentationArguments = null;
17998
17999        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18000                "finished inst");
18001    }
18002
18003    public void finishInstrumentation(IApplicationThread target,
18004            int resultCode, Bundle results) {
18005        int userId = UserHandle.getCallingUserId();
18006        // Refuse possible leaked file descriptors
18007        if (results != null && results.hasFileDescriptors()) {
18008            throw new IllegalArgumentException("File descriptors passed in Intent");
18009        }
18010
18011        synchronized(this) {
18012            ProcessRecord app = getRecordForAppLocked(target);
18013            if (app == null) {
18014                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18015                return;
18016            }
18017            final long origId = Binder.clearCallingIdentity();
18018            finishInstrumentationLocked(app, resultCode, results);
18019            Binder.restoreCallingIdentity(origId);
18020        }
18021    }
18022
18023    // =========================================================
18024    // CONFIGURATION
18025    // =========================================================
18026
18027    public ConfigurationInfo getDeviceConfigurationInfo() {
18028        ConfigurationInfo config = new ConfigurationInfo();
18029        synchronized (this) {
18030            config.reqTouchScreen = mConfiguration.touchscreen;
18031            config.reqKeyboardType = mConfiguration.keyboard;
18032            config.reqNavigation = mConfiguration.navigation;
18033            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18034                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18035                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18036            }
18037            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18038                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18039                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18040            }
18041            config.reqGlEsVersion = GL_ES_VERSION;
18042        }
18043        return config;
18044    }
18045
18046    ActivityStack getFocusedStack() {
18047        return mStackSupervisor.getFocusedStack();
18048    }
18049
18050    @Override
18051    public int getFocusedStackId() throws RemoteException {
18052        ActivityStack focusedStack = getFocusedStack();
18053        if (focusedStack != null) {
18054            return focusedStack.getStackId();
18055        }
18056        return -1;
18057    }
18058
18059    public Configuration getConfiguration() {
18060        Configuration ci;
18061        synchronized(this) {
18062            ci = new Configuration(mConfiguration);
18063            ci.userSetLocale = false;
18064        }
18065        return ci;
18066    }
18067
18068    @Override
18069    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18070        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18071        synchronized (this) {
18072            mSuppressResizeConfigChanges = suppress;
18073        }
18074    }
18075
18076    @Override
18077    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18078        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18079        if (fromStackId == HOME_STACK_ID) {
18080            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18081        }
18082        synchronized (this) {
18083            final long origId = Binder.clearCallingIdentity();
18084            try {
18085                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18086            } finally {
18087                Binder.restoreCallingIdentity(origId);
18088            }
18089        }
18090    }
18091
18092    @Override
18093    public void updatePersistentConfiguration(Configuration values) {
18094        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18095                "updateConfiguration()");
18096        enforceWriteSettingsPermission("updateConfiguration()");
18097        if (values == null) {
18098            throw new NullPointerException("Configuration must not be null");
18099        }
18100
18101        int userId = UserHandle.getCallingUserId();
18102
18103        synchronized(this) {
18104            final long origId = Binder.clearCallingIdentity();
18105            updateConfigurationLocked(values, null, false, true, userId);
18106            Binder.restoreCallingIdentity(origId);
18107        }
18108    }
18109
18110    private void updateFontScaleIfNeeded() {
18111        final int currentUserId;
18112        synchronized(this) {
18113            currentUserId = mUserController.getCurrentUserIdLocked();
18114        }
18115        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18116                FONT_SCALE, 1.0f, currentUserId);
18117        if (mConfiguration.fontScale != scaleFactor) {
18118            final Configuration configuration = mWindowManager.computeNewConfiguration();
18119            configuration.fontScale = scaleFactor;
18120            updatePersistentConfiguration(configuration);
18121        }
18122    }
18123
18124    private void enforceWriteSettingsPermission(String func) {
18125        int uid = Binder.getCallingUid();
18126        if (uid == Process.ROOT_UID) {
18127            return;
18128        }
18129
18130        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18131                Settings.getPackageNameForUid(mContext, uid), false)) {
18132            return;
18133        }
18134
18135        String msg = "Permission Denial: " + func + " from pid="
18136                + Binder.getCallingPid()
18137                + ", uid=" + uid
18138                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18139        Slog.w(TAG, msg);
18140        throw new SecurityException(msg);
18141    }
18142
18143    public void updateConfiguration(Configuration values) {
18144        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18145                "updateConfiguration()");
18146
18147        synchronized(this) {
18148            if (values == null && mWindowManager != null) {
18149                // sentinel: fetch the current configuration from the window manager
18150                values = mWindowManager.computeNewConfiguration();
18151            }
18152
18153            if (mWindowManager != null) {
18154                mProcessList.applyDisplaySize(mWindowManager);
18155            }
18156
18157            final long origId = Binder.clearCallingIdentity();
18158            if (values != null) {
18159                Settings.System.clearConfiguration(values);
18160            }
18161            updateConfigurationLocked(values, null, false);
18162            Binder.restoreCallingIdentity(origId);
18163        }
18164    }
18165
18166    void updateUserConfigurationLocked() {
18167        Configuration configuration = new Configuration(mConfiguration);
18168        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18169                mUserController.getCurrentUserIdLocked());
18170        updateConfigurationLocked(configuration, null, false);
18171    }
18172
18173    boolean updateConfigurationLocked(Configuration values,
18174            ActivityRecord starting, boolean initLocale) {
18175        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18176        return updateConfigurationLocked(values, starting, initLocale, false,
18177                UserHandle.USER_NULL);
18178    }
18179
18180    // To cache the list of supported system locales
18181    private String[] mSupportedSystemLocales = null;
18182
18183    /**
18184     * Do either or both things: (1) change the current configuration, and (2)
18185     * make sure the given activity is running with the (now) current
18186     * configuration.  Returns true if the activity has been left running, or
18187     * false if <var>starting</var> is being destroyed to match the new
18188     * configuration.
18189     *
18190     * @param userId is only used when persistent parameter is set to true to persist configuration
18191     *               for that particular user
18192     */
18193    private boolean updateConfigurationLocked(Configuration values,
18194            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18195        int changes = 0;
18196
18197        if (mWindowManager != null) {
18198            mWindowManager.deferSurfaceLayout();
18199        }
18200        if (values != null) {
18201            Configuration newConfig = new Configuration(mConfiguration);
18202            changes = newConfig.updateFrom(values);
18203            if (changes != 0) {
18204                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18205                        "Updating configuration to: " + values);
18206
18207                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18208
18209                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18210                    final Locale locale;
18211                    if (values.getLocales().size() == 1) {
18212                        // This is an optimization to avoid the JNI call when the result of
18213                        // getFirstMatch() does not depend on the supported locales.
18214                        locale = values.getLocales().get(0);
18215                    } else {
18216                        if (mSupportedSystemLocales == null) {
18217                            mSupportedSystemLocales =
18218                                    Resources.getSystem().getAssets().getLocales();
18219                        }
18220                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18221                    }
18222                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18223                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18224                            locale));
18225                }
18226
18227                mConfigurationSeq++;
18228                if (mConfigurationSeq <= 0) {
18229                    mConfigurationSeq = 1;
18230                }
18231                newConfig.seq = mConfigurationSeq;
18232                mConfiguration = newConfig;
18233                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18234                mUsageStatsService.reportConfigurationChange(newConfig,
18235                        mUserController.getCurrentUserIdLocked());
18236                //mUsageStatsService.noteStartConfig(newConfig);
18237
18238                final Configuration configCopy = new Configuration(mConfiguration);
18239
18240                // TODO: If our config changes, should we auto dismiss any currently
18241                // showing dialogs?
18242                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18243
18244                AttributeCache ac = AttributeCache.instance();
18245                if (ac != null) {
18246                    ac.updateConfiguration(configCopy);
18247                }
18248
18249                // Make sure all resources in our process are updated
18250                // right now, so that anyone who is going to retrieve
18251                // resource values after we return will be sure to get
18252                // the new ones.  This is especially important during
18253                // boot, where the first config change needs to guarantee
18254                // all resources have that config before following boot
18255                // code is executed.
18256                mSystemThread.applyConfigurationToResources(configCopy);
18257
18258                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18259                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18260                    msg.obj = new Configuration(configCopy);
18261                    msg.arg1 = userId;
18262                    mHandler.sendMessage(msg);
18263                }
18264
18265                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18266                if (isDensityChange) {
18267                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18268                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18269                }
18270
18271                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18272                    ProcessRecord app = mLruProcesses.get(i);
18273                    try {
18274                        if (app.thread != null) {
18275                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18276                                    + app.processName + " new config " + mConfiguration);
18277                            app.thread.scheduleConfigurationChanged(configCopy);
18278                        }
18279                    } catch (Exception e) {
18280                    }
18281                }
18282                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18283                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18284                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18285                        | Intent.FLAG_RECEIVER_FOREGROUND);
18286                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18287                        null, AppOpsManager.OP_NONE, null, false, false,
18288                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18289                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18290                    // Tell the shortcut manager that the system locale changed.  It needs to know
18291                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18292                    // we "push" from here, rather than having the service listen to the broadcast.
18293                    final ShortcutServiceInternal shortcutService =
18294                            LocalServices.getService(ShortcutServiceInternal.class);
18295                    if (shortcutService != null) {
18296                        shortcutService.onSystemLocaleChangedNoLock();
18297                    }
18298
18299                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18300                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18301                    if (!mProcessesReady) {
18302                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18303                    }
18304                    broadcastIntentLocked(null, null, intent,
18305                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18306                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18307                }
18308            }
18309            // Update the configuration with WM first and check if any of the stacks need to be
18310            // resized due to the configuration change. If so, resize the stacks now and do any
18311            // relaunches if necessary. This way we don't need to relaunch again below in
18312            // ensureActivityConfigurationLocked().
18313            if (mWindowManager != null) {
18314                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18315                if (resizedStacks != null) {
18316                    for (int stackId : resizedStacks) {
18317                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18318                        mStackSupervisor.resizeStackLocked(
18319                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18320                    }
18321                }
18322            }
18323        }
18324
18325        boolean kept = true;
18326        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18327        // mainStack is null during startup.
18328        if (mainStack != null) {
18329            if (changes != 0 && starting == null) {
18330                // If the configuration changed, and the caller is not already
18331                // in the process of starting an activity, then find the top
18332                // activity to check if its configuration needs to change.
18333                starting = mainStack.topRunningActivityLocked();
18334            }
18335
18336            if (starting != null) {
18337                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18338                // And we need to make sure at this point that all other activities
18339                // are made visible with the correct configuration.
18340                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18341                        !PRESERVE_WINDOWS);
18342            }
18343        }
18344        if (mWindowManager != null) {
18345            mWindowManager.continueSurfaceLayout();
18346        }
18347        return kept;
18348    }
18349
18350    /**
18351     * Decide based on the configuration whether we should shouw the ANR,
18352     * crash, etc dialogs.  The idea is that if there is no affordnace to
18353     * press the on-screen buttons, we shouldn't show the dialog.
18354     *
18355     * A thought: SystemUI might also want to get told about this, the Power
18356     * dialog / global actions also might want different behaviors.
18357     */
18358    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18359        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18360                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18361                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18362        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18363                                    == Configuration.UI_MODE_TYPE_CAR);
18364        return inputMethodExists && uiIsNotCarType && !inVrMode;
18365    }
18366
18367    @Override
18368    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18369        synchronized (this) {
18370            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18371            if (srec != null) {
18372                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18373            }
18374        }
18375        return false;
18376    }
18377
18378    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18379            Intent resultData) {
18380
18381        synchronized (this) {
18382            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18383            if (r != null) {
18384                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18385            }
18386            return false;
18387        }
18388    }
18389
18390    public int getLaunchedFromUid(IBinder activityToken) {
18391        ActivityRecord srec;
18392        synchronized (this) {
18393            srec = ActivityRecord.forTokenLocked(activityToken);
18394        }
18395        if (srec == null) {
18396            return -1;
18397        }
18398        return srec.launchedFromUid;
18399    }
18400
18401    public String getLaunchedFromPackage(IBinder activityToken) {
18402        ActivityRecord srec;
18403        synchronized (this) {
18404            srec = ActivityRecord.forTokenLocked(activityToken);
18405        }
18406        if (srec == null) {
18407            return null;
18408        }
18409        return srec.launchedFromPackage;
18410    }
18411
18412    // =========================================================
18413    // LIFETIME MANAGEMENT
18414    // =========================================================
18415
18416    // Returns which broadcast queue the app is the current [or imminent] receiver
18417    // on, or 'null' if the app is not an active broadcast recipient.
18418    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18419        BroadcastRecord r = app.curReceiver;
18420        if (r != null) {
18421            return r.queue;
18422        }
18423
18424        // It's not the current receiver, but it might be starting up to become one
18425        synchronized (this) {
18426            for (BroadcastQueue queue : mBroadcastQueues) {
18427                r = queue.mPendingBroadcast;
18428                if (r != null && r.curApp == app) {
18429                    // found it; report which queue it's in
18430                    return queue;
18431                }
18432            }
18433        }
18434
18435        return null;
18436    }
18437
18438    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18439            int targetUid, ComponentName targetComponent, String targetProcess) {
18440        if (!mTrackingAssociations) {
18441            return null;
18442        }
18443        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18444                = mAssociations.get(targetUid);
18445        if (components == null) {
18446            components = new ArrayMap<>();
18447            mAssociations.put(targetUid, components);
18448        }
18449        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18450        if (sourceUids == null) {
18451            sourceUids = new SparseArray<>();
18452            components.put(targetComponent, sourceUids);
18453        }
18454        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18455        if (sourceProcesses == null) {
18456            sourceProcesses = new ArrayMap<>();
18457            sourceUids.put(sourceUid, sourceProcesses);
18458        }
18459        Association ass = sourceProcesses.get(sourceProcess);
18460        if (ass == null) {
18461            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18462                    targetProcess);
18463            sourceProcesses.put(sourceProcess, ass);
18464        }
18465        ass.mCount++;
18466        ass.mNesting++;
18467        if (ass.mNesting == 1) {
18468            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18469            ass.mLastState = sourceState;
18470        }
18471        return ass;
18472    }
18473
18474    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18475            ComponentName targetComponent) {
18476        if (!mTrackingAssociations) {
18477            return;
18478        }
18479        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18480                = mAssociations.get(targetUid);
18481        if (components == null) {
18482            return;
18483        }
18484        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18485        if (sourceUids == null) {
18486            return;
18487        }
18488        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18489        if (sourceProcesses == null) {
18490            return;
18491        }
18492        Association ass = sourceProcesses.get(sourceProcess);
18493        if (ass == null || ass.mNesting <= 0) {
18494            return;
18495        }
18496        ass.mNesting--;
18497        if (ass.mNesting == 0) {
18498            long uptime = SystemClock.uptimeMillis();
18499            ass.mTime += uptime - ass.mStartTime;
18500            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18501                    += uptime - ass.mLastStateUptime;
18502            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18503        }
18504    }
18505
18506    private void noteUidProcessState(final int uid, final int state) {
18507        mBatteryStatsService.noteUidProcessState(uid, state);
18508        if (mTrackingAssociations) {
18509            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18510                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18511                        = mAssociations.valueAt(i1);
18512                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18513                    SparseArray<ArrayMap<String, Association>> sourceUids
18514                            = targetComponents.valueAt(i2);
18515                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18516                    if (sourceProcesses != null) {
18517                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18518                            Association ass = sourceProcesses.valueAt(i4);
18519                            if (ass.mNesting >= 1) {
18520                                // currently associated
18521                                long uptime = SystemClock.uptimeMillis();
18522                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18523                                        += uptime - ass.mLastStateUptime;
18524                                ass.mLastState = state;
18525                                ass.mLastStateUptime = uptime;
18526                            }
18527                        }
18528                    }
18529                }
18530            }
18531        }
18532    }
18533
18534    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18535            boolean doingAll, long now) {
18536        if (mAdjSeq == app.adjSeq) {
18537            // This adjustment has already been computed.
18538            return app.curRawAdj;
18539        }
18540
18541        if (app.thread == null) {
18542            app.adjSeq = mAdjSeq;
18543            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18544            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18545            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18546        }
18547
18548        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18549        app.adjSource = null;
18550        app.adjTarget = null;
18551        app.empty = false;
18552        app.cached = false;
18553
18554        final int activitiesSize = app.activities.size();
18555
18556        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18557            // The max adjustment doesn't allow this app to be anything
18558            // below foreground, so it is not worth doing work for it.
18559            app.adjType = "fixed";
18560            app.adjSeq = mAdjSeq;
18561            app.curRawAdj = app.maxAdj;
18562            app.foregroundActivities = false;
18563            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18564            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18565            // System processes can do UI, and when they do we want to have
18566            // them trim their memory after the user leaves the UI.  To
18567            // facilitate this, here we need to determine whether or not it
18568            // is currently showing UI.
18569            app.systemNoUi = true;
18570            if (app == TOP_APP) {
18571                app.systemNoUi = false;
18572            } else if (activitiesSize > 0) {
18573                for (int j = 0; j < activitiesSize; j++) {
18574                    final ActivityRecord r = app.activities.get(j);
18575                    if (r.visible) {
18576                        app.systemNoUi = false;
18577                    }
18578                }
18579            }
18580            if (!app.systemNoUi) {
18581                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18582            }
18583            return (app.curAdj=app.maxAdj);
18584        }
18585
18586        app.systemNoUi = false;
18587
18588        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18589
18590        // Determine the importance of the process, starting with most
18591        // important to least, and assign an appropriate OOM adjustment.
18592        int adj;
18593        int schedGroup;
18594        int procState;
18595        boolean foregroundActivities = false;
18596        BroadcastQueue queue;
18597        if (app == TOP_APP) {
18598            // The last app on the list is the foreground app.
18599            adj = ProcessList.FOREGROUND_APP_ADJ;
18600            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18601            app.adjType = "top-activity";
18602            foregroundActivities = true;
18603            procState = PROCESS_STATE_CUR_TOP;
18604        } else if (app.instrumentationClass != null) {
18605            // Don't want to kill running instrumentation.
18606            adj = ProcessList.FOREGROUND_APP_ADJ;
18607            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18608            app.adjType = "instrumentation";
18609            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18610        } else if ((queue = isReceivingBroadcast(app)) != null) {
18611            // An app that is currently receiving a broadcast also
18612            // counts as being in the foreground for OOM killer purposes.
18613            // It's placed in a sched group based on the nature of the
18614            // broadcast as reflected by which queue it's active in.
18615            adj = ProcessList.FOREGROUND_APP_ADJ;
18616            schedGroup = (queue == mFgBroadcastQueue)
18617                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18618            app.adjType = "broadcast";
18619            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18620        } else if (app.executingServices.size() > 0) {
18621            // An app that is currently executing a service callback also
18622            // counts as being in the foreground.
18623            adj = ProcessList.FOREGROUND_APP_ADJ;
18624            schedGroup = app.execServicesFg ?
18625                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18626            app.adjType = "exec-service";
18627            procState = ActivityManager.PROCESS_STATE_SERVICE;
18628            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18629        } else {
18630            // As far as we know the process is empty.  We may change our mind later.
18631            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18632            // At this point we don't actually know the adjustment.  Use the cached adj
18633            // value that the caller wants us to.
18634            adj = cachedAdj;
18635            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18636            app.cached = true;
18637            app.empty = true;
18638            app.adjType = "cch-empty";
18639        }
18640
18641        // Examine all activities if not already foreground.
18642        if (!foregroundActivities && activitiesSize > 0) {
18643            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18644            for (int j = 0; j < activitiesSize; j++) {
18645                final ActivityRecord r = app.activities.get(j);
18646                if (r.app != app) {
18647                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18648                            + " instead of expected " + app);
18649                    if (r.app == null || (r.app.uid == app.uid)) {
18650                        // Only fix things up when they look sane
18651                        r.app = app;
18652                    } else {
18653                        continue;
18654                    }
18655                }
18656                if (r.visible) {
18657                    // App has a visible activity; only upgrade adjustment.
18658                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18659                        adj = ProcessList.VISIBLE_APP_ADJ;
18660                        app.adjType = "visible";
18661                    }
18662                    if (procState > PROCESS_STATE_CUR_TOP) {
18663                        procState = PROCESS_STATE_CUR_TOP;
18664                    }
18665                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18666                    app.cached = false;
18667                    app.empty = false;
18668                    foregroundActivities = true;
18669                    if (r.task != null && minLayer > 0) {
18670                        final int layer = r.task.mLayerRank;
18671                        if (layer >= 0 && minLayer > layer) {
18672                            minLayer = layer;
18673                        }
18674                    }
18675                    break;
18676                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18677                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18678                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18679                        app.adjType = "pausing";
18680                    }
18681                    if (procState > PROCESS_STATE_CUR_TOP) {
18682                        procState = PROCESS_STATE_CUR_TOP;
18683                    }
18684                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18685                    app.cached = false;
18686                    app.empty = false;
18687                    foregroundActivities = true;
18688                } else if (r.state == ActivityState.STOPPING) {
18689                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18690                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18691                        app.adjType = "stopping";
18692                    }
18693                    // For the process state, we will at this point consider the
18694                    // process to be cached.  It will be cached either as an activity
18695                    // or empty depending on whether the activity is finishing.  We do
18696                    // this so that we can treat the process as cached for purposes of
18697                    // memory trimming (determing current memory level, trim command to
18698                    // send to process) since there can be an arbitrary number of stopping
18699                    // processes and they should soon all go into the cached state.
18700                    if (!r.finishing) {
18701                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18702                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18703                        }
18704                    }
18705                    app.cached = false;
18706                    app.empty = false;
18707                    foregroundActivities = true;
18708                } else {
18709                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18710                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18711                        app.adjType = "cch-act";
18712                    }
18713                }
18714            }
18715            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18716                adj += minLayer;
18717            }
18718        }
18719
18720        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18721                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18722            if (app.foregroundServices) {
18723                // The user is aware of this app, so make it visible.
18724                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18725                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18726                app.cached = false;
18727                app.adjType = "fg-service";
18728                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18729            } else if (app.forcingToForeground != null) {
18730                // The user is aware of this app, so make it visible.
18731                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18732                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18733                app.cached = false;
18734                app.adjType = "force-fg";
18735                app.adjSource = app.forcingToForeground;
18736                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18737            }
18738        }
18739
18740        if (app == mHeavyWeightProcess) {
18741            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18742                // We don't want to kill the current heavy-weight process.
18743                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18744                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18745                app.cached = false;
18746                app.adjType = "heavy";
18747            }
18748            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18749                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18750            }
18751        }
18752
18753        if (app == mHomeProcess) {
18754            if (adj > ProcessList.HOME_APP_ADJ) {
18755                // This process is hosting what we currently consider to be the
18756                // home app, so we don't want to let it go into the background.
18757                adj = ProcessList.HOME_APP_ADJ;
18758                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18759                app.cached = false;
18760                app.adjType = "home";
18761            }
18762            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18763                procState = ActivityManager.PROCESS_STATE_HOME;
18764            }
18765        }
18766
18767        if (app == mPreviousProcess && app.activities.size() > 0) {
18768            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18769                // This was the previous process that showed UI to the user.
18770                // We want to try to keep it around more aggressively, to give
18771                // a good experience around switching between two apps.
18772                adj = ProcessList.PREVIOUS_APP_ADJ;
18773                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18774                app.cached = false;
18775                app.adjType = "previous";
18776            }
18777            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18778                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18779            }
18780        }
18781
18782        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18783                + " reason=" + app.adjType);
18784
18785        // By default, we use the computed adjustment.  It may be changed if
18786        // there are applications dependent on our services or providers, but
18787        // this gives us a baseline and makes sure we don't get into an
18788        // infinite recursion.
18789        app.adjSeq = mAdjSeq;
18790        app.curRawAdj = adj;
18791        app.hasStartedServices = false;
18792
18793        if (mBackupTarget != null && app == mBackupTarget.app) {
18794            // If possible we want to avoid killing apps while they're being backed up
18795            if (adj > ProcessList.BACKUP_APP_ADJ) {
18796                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18797                adj = ProcessList.BACKUP_APP_ADJ;
18798                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18799                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18800                }
18801                app.adjType = "backup";
18802                app.cached = false;
18803            }
18804            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18805                procState = ActivityManager.PROCESS_STATE_BACKUP;
18806            }
18807        }
18808
18809        boolean mayBeTop = false;
18810
18811        for (int is = app.services.size()-1;
18812                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18813                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18814                        || procState > ActivityManager.PROCESS_STATE_TOP);
18815                is--) {
18816            ServiceRecord s = app.services.valueAt(is);
18817            if (s.startRequested) {
18818                app.hasStartedServices = true;
18819                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18820                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18821                }
18822                if (app.hasShownUi && app != mHomeProcess) {
18823                    // If this process has shown some UI, let it immediately
18824                    // go to the LRU list because it may be pretty heavy with
18825                    // UI stuff.  We'll tag it with a label just to help
18826                    // debug and understand what is going on.
18827                    if (adj > ProcessList.SERVICE_ADJ) {
18828                        app.adjType = "cch-started-ui-services";
18829                    }
18830                } else {
18831                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18832                        // This service has seen some activity within
18833                        // recent memory, so we will keep its process ahead
18834                        // of the background processes.
18835                        if (adj > ProcessList.SERVICE_ADJ) {
18836                            adj = ProcessList.SERVICE_ADJ;
18837                            app.adjType = "started-services";
18838                            app.cached = false;
18839                        }
18840                    }
18841                    // If we have let the service slide into the background
18842                    // state, still have some text describing what it is doing
18843                    // even though the service no longer has an impact.
18844                    if (adj > ProcessList.SERVICE_ADJ) {
18845                        app.adjType = "cch-started-services";
18846                    }
18847                }
18848            }
18849            for (int conni = s.connections.size()-1;
18850                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18851                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18852                            || procState > ActivityManager.PROCESS_STATE_TOP);
18853                    conni--) {
18854                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18855                for (int i = 0;
18856                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18857                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18858                                || procState > ActivityManager.PROCESS_STATE_TOP);
18859                        i++) {
18860                    // XXX should compute this based on the max of
18861                    // all connected clients.
18862                    ConnectionRecord cr = clist.get(i);
18863                    if (cr.binding.client == app) {
18864                        // Binding to ourself is not interesting.
18865                        continue;
18866                    }
18867                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18868                        ProcessRecord client = cr.binding.client;
18869                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18870                                TOP_APP, doingAll, now);
18871                        int clientProcState = client.curProcState;
18872                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18873                            // If the other app is cached for any reason, for purposes here
18874                            // we are going to consider it empty.  The specific cached state
18875                            // doesn't propagate except under certain conditions.
18876                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18877                        }
18878                        String adjType = null;
18879                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18880                            // Not doing bind OOM management, so treat
18881                            // this guy more like a started service.
18882                            if (app.hasShownUi && app != mHomeProcess) {
18883                                // If this process has shown some UI, let it immediately
18884                                // go to the LRU list because it may be pretty heavy with
18885                                // UI stuff.  We'll tag it with a label just to help
18886                                // debug and understand what is going on.
18887                                if (adj > clientAdj) {
18888                                    adjType = "cch-bound-ui-services";
18889                                }
18890                                app.cached = false;
18891                                clientAdj = adj;
18892                                clientProcState = procState;
18893                            } else {
18894                                if (now >= (s.lastActivity
18895                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18896                                    // This service has not seen activity within
18897                                    // recent memory, so allow it to drop to the
18898                                    // LRU list if there is no other reason to keep
18899                                    // it around.  We'll also tag it with a label just
18900                                    // to help debug and undertand what is going on.
18901                                    if (adj > clientAdj) {
18902                                        adjType = "cch-bound-services";
18903                                    }
18904                                    clientAdj = adj;
18905                                }
18906                            }
18907                        }
18908                        if (adj > clientAdj) {
18909                            // If this process has recently shown UI, and
18910                            // the process that is binding to it is less
18911                            // important than being visible, then we don't
18912                            // care about the binding as much as we care
18913                            // about letting this process get into the LRU
18914                            // list to be killed and restarted if needed for
18915                            // memory.
18916                            if (app.hasShownUi && app != mHomeProcess
18917                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18918                                adjType = "cch-bound-ui-services";
18919                            } else {
18920                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18921                                        |Context.BIND_IMPORTANT)) != 0) {
18922                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18923                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18924                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18925                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18926                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18927                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18928                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18929                                    adj = clientAdj;
18930                                } else {
18931                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18932                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18933                                    }
18934                                }
18935                                if (!client.cached) {
18936                                    app.cached = false;
18937                                }
18938                                adjType = "service";
18939                            }
18940                        }
18941                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18942                            // This will treat important bound services identically to
18943                            // the top app, which may behave differently than generic
18944                            // foreground work.
18945                            if (client.curSchedGroup > schedGroup) {
18946                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18947                                    schedGroup = client.curSchedGroup;
18948                                } else {
18949                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18950                                }
18951                            }
18952                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18953                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18954                                    // Special handling of clients who are in the top state.
18955                                    // We *may* want to consider this process to be in the
18956                                    // top state as well, but only if there is not another
18957                                    // reason for it to be running.  Being on the top is a
18958                                    // special state, meaning you are specifically running
18959                                    // for the current top app.  If the process is already
18960                                    // running in the background for some other reason, it
18961                                    // is more important to continue considering it to be
18962                                    // in the background state.
18963                                    mayBeTop = true;
18964                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18965                                } else {
18966                                    // Special handling for above-top states (persistent
18967                                    // processes).  These should not bring the current process
18968                                    // into the top state, since they are not on top.  Instead
18969                                    // give them the best state after that.
18970                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18971                                        clientProcState =
18972                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18973                                    } else if (mWakefulness
18974                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18975                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18976                                                    != 0) {
18977                                        clientProcState =
18978                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18979                                    } else {
18980                                        clientProcState =
18981                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18982                                    }
18983                                }
18984                            }
18985                        } else {
18986                            if (clientProcState <
18987                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18988                                clientProcState =
18989                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18990                            }
18991                        }
18992                        if (procState > clientProcState) {
18993                            procState = clientProcState;
18994                        }
18995                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18996                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18997                            app.pendingUiClean = true;
18998                        }
18999                        if (adjType != null) {
19000                            app.adjType = adjType;
19001                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19002                                    .REASON_SERVICE_IN_USE;
19003                            app.adjSource = cr.binding.client;
19004                            app.adjSourceProcState = clientProcState;
19005                            app.adjTarget = s.name;
19006                        }
19007                    }
19008                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19009                        app.treatLikeActivity = true;
19010                    }
19011                    final ActivityRecord a = cr.activity;
19012                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19013                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19014                            (a.visible || a.state == ActivityState.RESUMED ||
19015                             a.state == ActivityState.PAUSING)) {
19016                            adj = ProcessList.FOREGROUND_APP_ADJ;
19017                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19018                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19019                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19020                                } else {
19021                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19022                                }
19023                            }
19024                            app.cached = false;
19025                            app.adjType = "service";
19026                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19027                                    .REASON_SERVICE_IN_USE;
19028                            app.adjSource = a;
19029                            app.adjSourceProcState = procState;
19030                            app.adjTarget = s.name;
19031                        }
19032                    }
19033                }
19034            }
19035        }
19036
19037        for (int provi = app.pubProviders.size()-1;
19038                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19039                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19040                        || procState > ActivityManager.PROCESS_STATE_TOP);
19041                provi--) {
19042            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19043            for (int i = cpr.connections.size()-1;
19044                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19045                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19046                            || procState > ActivityManager.PROCESS_STATE_TOP);
19047                    i--) {
19048                ContentProviderConnection conn = cpr.connections.get(i);
19049                ProcessRecord client = conn.client;
19050                if (client == app) {
19051                    // Being our own client is not interesting.
19052                    continue;
19053                }
19054                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19055                int clientProcState = client.curProcState;
19056                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19057                    // If the other app is cached for any reason, for purposes here
19058                    // we are going to consider it empty.
19059                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19060                }
19061                if (adj > clientAdj) {
19062                    if (app.hasShownUi && app != mHomeProcess
19063                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19064                        app.adjType = "cch-ui-provider";
19065                    } else {
19066                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19067                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19068                        app.adjType = "provider";
19069                    }
19070                    app.cached &= client.cached;
19071                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19072                            .REASON_PROVIDER_IN_USE;
19073                    app.adjSource = client;
19074                    app.adjSourceProcState = clientProcState;
19075                    app.adjTarget = cpr.name;
19076                }
19077                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19078                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19079                        // Special handling of clients who are in the top state.
19080                        // We *may* want to consider this process to be in the
19081                        // top state as well, but only if there is not another
19082                        // reason for it to be running.  Being on the top is a
19083                        // special state, meaning you are specifically running
19084                        // for the current top app.  If the process is already
19085                        // running in the background for some other reason, it
19086                        // is more important to continue considering it to be
19087                        // in the background state.
19088                        mayBeTop = true;
19089                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19090                    } else {
19091                        // Special handling for above-top states (persistent
19092                        // processes).  These should not bring the current process
19093                        // into the top state, since they are not on top.  Instead
19094                        // give them the best state after that.
19095                        clientProcState =
19096                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19097                    }
19098                }
19099                if (procState > clientProcState) {
19100                    procState = clientProcState;
19101                }
19102                if (client.curSchedGroup > schedGroup) {
19103                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19104                }
19105            }
19106            // If the provider has external (non-framework) process
19107            // dependencies, ensure that its adjustment is at least
19108            // FOREGROUND_APP_ADJ.
19109            if (cpr.hasExternalProcessHandles()) {
19110                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19111                    adj = ProcessList.FOREGROUND_APP_ADJ;
19112                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19113                    app.cached = false;
19114                    app.adjType = "provider";
19115                    app.adjTarget = cpr.name;
19116                }
19117                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19118                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19119                }
19120            }
19121        }
19122
19123        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19124            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19125                adj = ProcessList.PREVIOUS_APP_ADJ;
19126                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19127                app.cached = false;
19128                app.adjType = "provider";
19129            }
19130            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19131                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19132            }
19133        }
19134
19135        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19136            // A client of one of our services or providers is in the top state.  We
19137            // *may* want to be in the top state, but not if we are already running in
19138            // the background for some other reason.  For the decision here, we are going
19139            // to pick out a few specific states that we want to remain in when a client
19140            // is top (states that tend to be longer-term) and otherwise allow it to go
19141            // to the top state.
19142            switch (procState) {
19143                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19144                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19145                case ActivityManager.PROCESS_STATE_SERVICE:
19146                    // These all are longer-term states, so pull them up to the top
19147                    // of the background states, but not all the way to the top state.
19148                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19149                    break;
19150                default:
19151                    // Otherwise, top is a better choice, so take it.
19152                    procState = ActivityManager.PROCESS_STATE_TOP;
19153                    break;
19154            }
19155        }
19156
19157        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19158            if (app.hasClientActivities) {
19159                // This is a cached process, but with client activities.  Mark it so.
19160                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19161                app.adjType = "cch-client-act";
19162            } else if (app.treatLikeActivity) {
19163                // This is a cached process, but somebody wants us to treat it like it has
19164                // an activity, okay!
19165                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19166                app.adjType = "cch-as-act";
19167            }
19168        }
19169
19170        if (adj == ProcessList.SERVICE_ADJ) {
19171            if (doingAll) {
19172                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19173                mNewNumServiceProcs++;
19174                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19175                if (!app.serviceb) {
19176                    // This service isn't far enough down on the LRU list to
19177                    // normally be a B service, but if we are low on RAM and it
19178                    // is large we want to force it down since we would prefer to
19179                    // keep launcher over it.
19180                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19181                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19182                        app.serviceHighRam = true;
19183                        app.serviceb = true;
19184                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19185                    } else {
19186                        mNewNumAServiceProcs++;
19187                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19188                    }
19189                } else {
19190                    app.serviceHighRam = false;
19191                }
19192            }
19193            if (app.serviceb) {
19194                adj = ProcessList.SERVICE_B_ADJ;
19195            }
19196        }
19197
19198        app.curRawAdj = adj;
19199
19200        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19201        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19202        if (adj > app.maxAdj) {
19203            adj = app.maxAdj;
19204            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19205                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19206            }
19207        }
19208
19209        // Do final modification to adj.  Everything we do between here and applying
19210        // the final setAdj must be done in this function, because we will also use
19211        // it when computing the final cached adj later.  Note that we don't need to
19212        // worry about this for max adj above, since max adj will always be used to
19213        // keep it out of the cached vaues.
19214        app.curAdj = app.modifyRawOomAdj(adj);
19215        app.curSchedGroup = schedGroup;
19216        app.curProcState = procState;
19217        app.foregroundActivities = foregroundActivities;
19218
19219        return app.curRawAdj;
19220    }
19221
19222    /**
19223     * Record new PSS sample for a process.
19224     */
19225    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19226            long now) {
19227        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19228                swapPss * 1024);
19229        proc.lastPssTime = now;
19230        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19231        if (DEBUG_PSS) Slog.d(TAG_PSS,
19232                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19233                + " state=" + ProcessList.makeProcStateString(procState));
19234        if (proc.initialIdlePss == 0) {
19235            proc.initialIdlePss = pss;
19236        }
19237        proc.lastPss = pss;
19238        proc.lastSwapPss = swapPss;
19239        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19240            proc.lastCachedPss = pss;
19241            proc.lastCachedSwapPss = swapPss;
19242        }
19243
19244        final SparseArray<Pair<Long, String>> watchUids
19245                = mMemWatchProcesses.getMap().get(proc.processName);
19246        Long check = null;
19247        if (watchUids != null) {
19248            Pair<Long, String> val = watchUids.get(proc.uid);
19249            if (val == null) {
19250                val = watchUids.get(0);
19251            }
19252            if (val != null) {
19253                check = val.first;
19254            }
19255        }
19256        if (check != null) {
19257            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19258                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19259                if (!isDebuggable) {
19260                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19261                        isDebuggable = true;
19262                    }
19263                }
19264                if (isDebuggable) {
19265                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19266                    final ProcessRecord myProc = proc;
19267                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19268                    mMemWatchDumpProcName = proc.processName;
19269                    mMemWatchDumpFile = heapdumpFile.toString();
19270                    mMemWatchDumpPid = proc.pid;
19271                    mMemWatchDumpUid = proc.uid;
19272                    BackgroundThread.getHandler().post(new Runnable() {
19273                        @Override
19274                        public void run() {
19275                            revokeUriPermission(ActivityThread.currentActivityThread()
19276                                            .getApplicationThread(),
19277                                    DumpHeapActivity.JAVA_URI,
19278                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19279                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19280                                    UserHandle.myUserId());
19281                            ParcelFileDescriptor fd = null;
19282                            try {
19283                                heapdumpFile.delete();
19284                                fd = ParcelFileDescriptor.open(heapdumpFile,
19285                                        ParcelFileDescriptor.MODE_CREATE |
19286                                                ParcelFileDescriptor.MODE_TRUNCATE |
19287                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19288                                                ParcelFileDescriptor.MODE_APPEND);
19289                                IApplicationThread thread = myProc.thread;
19290                                if (thread != null) {
19291                                    try {
19292                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19293                                                "Requesting dump heap from "
19294                                                + myProc + " to " + heapdumpFile);
19295                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19296                                    } catch (RemoteException e) {
19297                                    }
19298                                }
19299                            } catch (FileNotFoundException e) {
19300                                e.printStackTrace();
19301                            } finally {
19302                                if (fd != null) {
19303                                    try {
19304                                        fd.close();
19305                                    } catch (IOException e) {
19306                                    }
19307                                }
19308                            }
19309                        }
19310                    });
19311                } else {
19312                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19313                            + ", but debugging not enabled");
19314                }
19315            }
19316        }
19317    }
19318
19319    /**
19320     * Schedule PSS collection of a process.
19321     */
19322    void requestPssLocked(ProcessRecord proc, int procState) {
19323        if (mPendingPssProcesses.contains(proc)) {
19324            return;
19325        }
19326        if (mPendingPssProcesses.size() == 0) {
19327            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19328        }
19329        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19330        proc.pssProcState = procState;
19331        mPendingPssProcesses.add(proc);
19332    }
19333
19334    /**
19335     * Schedule PSS collection of all processes.
19336     */
19337    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19338        if (!always) {
19339            if (now < (mLastFullPssTime +
19340                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19341                return;
19342            }
19343        }
19344        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19345        mLastFullPssTime = now;
19346        mFullPssPending = true;
19347        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19348        mPendingPssProcesses.clear();
19349        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19350            ProcessRecord app = mLruProcesses.get(i);
19351            if (app.thread == null
19352                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19353                continue;
19354            }
19355            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19356                app.pssProcState = app.setProcState;
19357                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19358                        mTestPssMode, isSleeping(), now);
19359                mPendingPssProcesses.add(app);
19360            }
19361        }
19362        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19363    }
19364
19365    public void setTestPssMode(boolean enabled) {
19366        synchronized (this) {
19367            mTestPssMode = enabled;
19368            if (enabled) {
19369                // Whenever we enable the mode, we want to take a snapshot all of current
19370                // process mem use.
19371                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19372            }
19373        }
19374    }
19375
19376    /**
19377     * Ask a given process to GC right now.
19378     */
19379    final void performAppGcLocked(ProcessRecord app) {
19380        try {
19381            app.lastRequestedGc = SystemClock.uptimeMillis();
19382            if (app.thread != null) {
19383                if (app.reportLowMemory) {
19384                    app.reportLowMemory = false;
19385                    app.thread.scheduleLowMemory();
19386                } else {
19387                    app.thread.processInBackground();
19388                }
19389            }
19390        } catch (Exception e) {
19391            // whatever.
19392        }
19393    }
19394
19395    /**
19396     * Returns true if things are idle enough to perform GCs.
19397     */
19398    private final boolean canGcNowLocked() {
19399        boolean processingBroadcasts = false;
19400        for (BroadcastQueue q : mBroadcastQueues) {
19401            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19402                processingBroadcasts = true;
19403            }
19404        }
19405        return !processingBroadcasts
19406                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19407    }
19408
19409    /**
19410     * Perform GCs on all processes that are waiting for it, but only
19411     * if things are idle.
19412     */
19413    final void performAppGcsLocked() {
19414        final int N = mProcessesToGc.size();
19415        if (N <= 0) {
19416            return;
19417        }
19418        if (canGcNowLocked()) {
19419            while (mProcessesToGc.size() > 0) {
19420                ProcessRecord proc = mProcessesToGc.remove(0);
19421                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19422                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19423                            <= SystemClock.uptimeMillis()) {
19424                        // To avoid spamming the system, we will GC processes one
19425                        // at a time, waiting a few seconds between each.
19426                        performAppGcLocked(proc);
19427                        scheduleAppGcsLocked();
19428                        return;
19429                    } else {
19430                        // It hasn't been long enough since we last GCed this
19431                        // process...  put it in the list to wait for its time.
19432                        addProcessToGcListLocked(proc);
19433                        break;
19434                    }
19435                }
19436            }
19437
19438            scheduleAppGcsLocked();
19439        }
19440    }
19441
19442    /**
19443     * If all looks good, perform GCs on all processes waiting for them.
19444     */
19445    final void performAppGcsIfAppropriateLocked() {
19446        if (canGcNowLocked()) {
19447            performAppGcsLocked();
19448            return;
19449        }
19450        // Still not idle, wait some more.
19451        scheduleAppGcsLocked();
19452    }
19453
19454    /**
19455     * Schedule the execution of all pending app GCs.
19456     */
19457    final void scheduleAppGcsLocked() {
19458        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19459
19460        if (mProcessesToGc.size() > 0) {
19461            // Schedule a GC for the time to the next process.
19462            ProcessRecord proc = mProcessesToGc.get(0);
19463            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19464
19465            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19466            long now = SystemClock.uptimeMillis();
19467            if (when < (now+GC_TIMEOUT)) {
19468                when = now + GC_TIMEOUT;
19469            }
19470            mHandler.sendMessageAtTime(msg, when);
19471        }
19472    }
19473
19474    /**
19475     * Add a process to the array of processes waiting to be GCed.  Keeps the
19476     * list in sorted order by the last GC time.  The process can't already be
19477     * on the list.
19478     */
19479    final void addProcessToGcListLocked(ProcessRecord proc) {
19480        boolean added = false;
19481        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19482            if (mProcessesToGc.get(i).lastRequestedGc <
19483                    proc.lastRequestedGc) {
19484                added = true;
19485                mProcessesToGc.add(i+1, proc);
19486                break;
19487            }
19488        }
19489        if (!added) {
19490            mProcessesToGc.add(0, proc);
19491        }
19492    }
19493
19494    /**
19495     * Set up to ask a process to GC itself.  This will either do it
19496     * immediately, or put it on the list of processes to gc the next
19497     * time things are idle.
19498     */
19499    final void scheduleAppGcLocked(ProcessRecord app) {
19500        long now = SystemClock.uptimeMillis();
19501        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19502            return;
19503        }
19504        if (!mProcessesToGc.contains(app)) {
19505            addProcessToGcListLocked(app);
19506            scheduleAppGcsLocked();
19507        }
19508    }
19509
19510    final void checkExcessivePowerUsageLocked(boolean doKills) {
19511        updateCpuStatsNow();
19512
19513        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19514        boolean doWakeKills = doKills;
19515        boolean doCpuKills = doKills;
19516        if (mLastPowerCheckRealtime == 0) {
19517            doWakeKills = false;
19518        }
19519        if (mLastPowerCheckUptime == 0) {
19520            doCpuKills = false;
19521        }
19522        if (stats.isScreenOn()) {
19523            doWakeKills = false;
19524        }
19525        final long curRealtime = SystemClock.elapsedRealtime();
19526        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19527        final long curUptime = SystemClock.uptimeMillis();
19528        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19529        mLastPowerCheckRealtime = curRealtime;
19530        mLastPowerCheckUptime = curUptime;
19531        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19532            doWakeKills = false;
19533        }
19534        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19535            doCpuKills = false;
19536        }
19537        int i = mLruProcesses.size();
19538        while (i > 0) {
19539            i--;
19540            ProcessRecord app = mLruProcesses.get(i);
19541            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19542                long wtime;
19543                synchronized (stats) {
19544                    wtime = stats.getProcessWakeTime(app.info.uid,
19545                            app.pid, curRealtime);
19546                }
19547                long wtimeUsed = wtime - app.lastWakeTime;
19548                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19549                if (DEBUG_POWER) {
19550                    StringBuilder sb = new StringBuilder(128);
19551                    sb.append("Wake for ");
19552                    app.toShortString(sb);
19553                    sb.append(": over ");
19554                    TimeUtils.formatDuration(realtimeSince, sb);
19555                    sb.append(" used ");
19556                    TimeUtils.formatDuration(wtimeUsed, sb);
19557                    sb.append(" (");
19558                    sb.append((wtimeUsed*100)/realtimeSince);
19559                    sb.append("%)");
19560                    Slog.i(TAG_POWER, sb.toString());
19561                    sb.setLength(0);
19562                    sb.append("CPU for ");
19563                    app.toShortString(sb);
19564                    sb.append(": over ");
19565                    TimeUtils.formatDuration(uptimeSince, sb);
19566                    sb.append(" used ");
19567                    TimeUtils.formatDuration(cputimeUsed, sb);
19568                    sb.append(" (");
19569                    sb.append((cputimeUsed*100)/uptimeSince);
19570                    sb.append("%)");
19571                    Slog.i(TAG_POWER, sb.toString());
19572                }
19573                // If a process has held a wake lock for more
19574                // than 50% of the time during this period,
19575                // that sounds bad.  Kill!
19576                if (doWakeKills && realtimeSince > 0
19577                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19578                    synchronized (stats) {
19579                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19580                                realtimeSince, wtimeUsed);
19581                    }
19582                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19583                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19584                } else if (doCpuKills && uptimeSince > 0
19585                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19586                    synchronized (stats) {
19587                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19588                                uptimeSince, cputimeUsed);
19589                    }
19590                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19591                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19592                } else {
19593                    app.lastWakeTime = wtime;
19594                    app.lastCpuTime = app.curCpuTime;
19595                }
19596            }
19597        }
19598    }
19599
19600    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19601            long nowElapsed) {
19602        boolean success = true;
19603
19604        if (app.curRawAdj != app.setRawAdj) {
19605            app.setRawAdj = app.curRawAdj;
19606        }
19607
19608        int changes = 0;
19609
19610        if (app.curAdj != app.setAdj) {
19611            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19612            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19613                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19614                    + app.adjType);
19615            app.setAdj = app.curAdj;
19616        }
19617
19618        if (app.setSchedGroup != app.curSchedGroup) {
19619            app.setSchedGroup = app.curSchedGroup;
19620            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19621                    "Setting sched group of " + app.processName
19622                    + " to " + app.curSchedGroup);
19623            if (app.waitingToKill != null && app.curReceiver == null
19624                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19625                app.kill(app.waitingToKill, true);
19626                success = false;
19627            } else {
19628                int processGroup;
19629                switch (app.curSchedGroup) {
19630                    case ProcessList.SCHED_GROUP_BACKGROUND:
19631                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19632                        break;
19633                    case ProcessList.SCHED_GROUP_TOP_APP:
19634                        processGroup = Process.THREAD_GROUP_TOP_APP;
19635                        break;
19636                    default:
19637                        processGroup = Process.THREAD_GROUP_DEFAULT;
19638                        break;
19639                }
19640                if (true) {
19641                    long oldId = Binder.clearCallingIdentity();
19642                    try {
19643                        Process.setProcessGroup(app.pid, processGroup);
19644                    } catch (Exception e) {
19645                        Slog.w(TAG, "Failed setting process group of " + app.pid
19646                                + " to " + app.curSchedGroup);
19647                        e.printStackTrace();
19648                    } finally {
19649                        Binder.restoreCallingIdentity(oldId);
19650                    }
19651                } else {
19652                    if (app.thread != null) {
19653                        try {
19654                            app.thread.setSchedulingGroup(processGroup);
19655                        } catch (RemoteException e) {
19656                        }
19657                    }
19658                }
19659            }
19660        }
19661        if (app.repForegroundActivities != app.foregroundActivities) {
19662            app.repForegroundActivities = app.foregroundActivities;
19663            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19664        }
19665        if (app.repProcState != app.curProcState) {
19666            app.repProcState = app.curProcState;
19667            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19668            if (app.thread != null) {
19669                try {
19670                    if (false) {
19671                        //RuntimeException h = new RuntimeException("here");
19672                        Slog.i(TAG, "Sending new process state " + app.repProcState
19673                                + " to " + app /*, h*/);
19674                    }
19675                    app.thread.setProcessState(app.repProcState);
19676                } catch (RemoteException e) {
19677                }
19678            }
19679        }
19680        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19681                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19682            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19683                // Experimental code to more aggressively collect pss while
19684                // running test...  the problem is that this tends to collect
19685                // the data right when a process is transitioning between process
19686                // states, which well tend to give noisy data.
19687                long start = SystemClock.uptimeMillis();
19688                long pss = Debug.getPss(app.pid, mTmpLong, null);
19689                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19690                mPendingPssProcesses.remove(app);
19691                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19692                        + " to " + app.curProcState + ": "
19693                        + (SystemClock.uptimeMillis()-start) + "ms");
19694            }
19695            app.lastStateTime = now;
19696            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19697                    mTestPssMode, isSleeping(), now);
19698            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19699                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19700                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19701                    + (app.nextPssTime-now) + ": " + app);
19702        } else {
19703            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19704                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19705                    mTestPssMode)))) {
19706                requestPssLocked(app, app.setProcState);
19707                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19708                        mTestPssMode, isSleeping(), now);
19709            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19710                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19711        }
19712        if (app.setProcState != app.curProcState) {
19713            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19714                    "Proc state change of " + app.processName
19715                            + " to " + app.curProcState);
19716            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19717            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19718            if (setImportant && !curImportant) {
19719                // This app is no longer something we consider important enough to allow to
19720                // use arbitrary amounts of battery power.  Note
19721                // its current wake lock time to later know to kill it if
19722                // it is not behaving well.
19723                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19724                synchronized (stats) {
19725                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19726                            app.pid, nowElapsed);
19727                }
19728                app.lastCpuTime = app.curCpuTime;
19729
19730            }
19731            // Inform UsageStats of important process state change
19732            // Must be called before updating setProcState
19733            maybeUpdateUsageStatsLocked(app, nowElapsed);
19734
19735            app.setProcState = app.curProcState;
19736            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19737                app.notCachedSinceIdle = false;
19738            }
19739            if (!doingAll) {
19740                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19741            } else {
19742                app.procStateChanged = true;
19743            }
19744        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19745                > USAGE_STATS_INTERACTION_INTERVAL) {
19746            // For apps that sit around for a long time in the interactive state, we need
19747            // to report this at least once a day so they don't go idle.
19748            maybeUpdateUsageStatsLocked(app, nowElapsed);
19749        }
19750
19751        if (changes != 0) {
19752            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19753                    "Changes in " + app + ": " + changes);
19754            int i = mPendingProcessChanges.size()-1;
19755            ProcessChangeItem item = null;
19756            while (i >= 0) {
19757                item = mPendingProcessChanges.get(i);
19758                if (item.pid == app.pid) {
19759                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19760                            "Re-using existing item: " + item);
19761                    break;
19762                }
19763                i--;
19764            }
19765            if (i < 0) {
19766                // No existing item in pending changes; need a new one.
19767                final int NA = mAvailProcessChanges.size();
19768                if (NA > 0) {
19769                    item = mAvailProcessChanges.remove(NA-1);
19770                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19771                            "Retrieving available item: " + item);
19772                } else {
19773                    item = new ProcessChangeItem();
19774                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19775                            "Allocating new item: " + item);
19776                }
19777                item.changes = 0;
19778                item.pid = app.pid;
19779                item.uid = app.info.uid;
19780                if (mPendingProcessChanges.size() == 0) {
19781                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19782                            "*** Enqueueing dispatch processes changed!");
19783                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19784                }
19785                mPendingProcessChanges.add(item);
19786            }
19787            item.changes |= changes;
19788            item.processState = app.repProcState;
19789            item.foregroundActivities = app.repForegroundActivities;
19790            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19791                    "Item " + Integer.toHexString(System.identityHashCode(item))
19792                    + " " + app.toShortString() + ": changes=" + item.changes
19793                    + " procState=" + item.processState
19794                    + " foreground=" + item.foregroundActivities
19795                    + " type=" + app.adjType + " source=" + app.adjSource
19796                    + " target=" + app.adjTarget);
19797        }
19798
19799        return success;
19800    }
19801
19802    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19803        final UidRecord.ChangeItem pendingChange;
19804        if (uidRec == null || uidRec.pendingChange == null) {
19805            if (mPendingUidChanges.size() == 0) {
19806                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19807                        "*** Enqueueing dispatch uid changed!");
19808                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19809            }
19810            final int NA = mAvailUidChanges.size();
19811            if (NA > 0) {
19812                pendingChange = mAvailUidChanges.remove(NA-1);
19813                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19814                        "Retrieving available item: " + pendingChange);
19815            } else {
19816                pendingChange = new UidRecord.ChangeItem();
19817                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19818                        "Allocating new item: " + pendingChange);
19819            }
19820            if (uidRec != null) {
19821                uidRec.pendingChange = pendingChange;
19822                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19823                    // If this uid is going away, and we haven't yet reported it is gone,
19824                    // then do so now.
19825                    change = UidRecord.CHANGE_GONE_IDLE;
19826                }
19827            } else if (uid < 0) {
19828                throw new IllegalArgumentException("No UidRecord or uid");
19829            }
19830            pendingChange.uidRecord = uidRec;
19831            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19832            mPendingUidChanges.add(pendingChange);
19833        } else {
19834            pendingChange = uidRec.pendingChange;
19835            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19836                change = UidRecord.CHANGE_GONE_IDLE;
19837            }
19838        }
19839        pendingChange.change = change;
19840        pendingChange.processState = uidRec != null
19841                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19842    }
19843
19844    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19845            String authority) {
19846        if (app == null) return;
19847        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19848            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19849            if (userState == null) return;
19850            final long now = SystemClock.elapsedRealtime();
19851            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19852            if (lastReported == null || lastReported < now - 60 * 1000L) {
19853                mUsageStatsService.reportContentProviderUsage(
19854                        authority, providerPkgName, app.userId);
19855                userState.mProviderLastReportedFg.put(authority, now);
19856            }
19857        }
19858    }
19859
19860    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19861        if (DEBUG_USAGE_STATS) {
19862            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19863                    + "] state changes: old = " + app.setProcState + ", new = "
19864                    + app.curProcState);
19865        }
19866        if (mUsageStatsService == null) {
19867            return;
19868        }
19869        boolean isInteraction;
19870        // To avoid some abuse patterns, we are going to be careful about what we consider
19871        // to be an app interaction.  Being the top activity doesn't count while the display
19872        // is sleeping, nor do short foreground services.
19873        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19874            isInteraction = true;
19875            app.fgInteractionTime = 0;
19876        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19877            if (app.fgInteractionTime == 0) {
19878                app.fgInteractionTime = nowElapsed;
19879                isInteraction = false;
19880            } else {
19881                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19882            }
19883        } else {
19884            isInteraction = app.curProcState
19885                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19886            app.fgInteractionTime = 0;
19887        }
19888        if (isInteraction && (!app.reportedInteraction
19889                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19890            app.interactionEventTime = nowElapsed;
19891            String[] packages = app.getPackageList();
19892            if (packages != null) {
19893                for (int i = 0; i < packages.length; i++) {
19894                    mUsageStatsService.reportEvent(packages[i], app.userId,
19895                            UsageEvents.Event.SYSTEM_INTERACTION);
19896                }
19897            }
19898        }
19899        app.reportedInteraction = isInteraction;
19900        if (!isInteraction) {
19901            app.interactionEventTime = 0;
19902        }
19903    }
19904
19905    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19906        if (proc.thread != null) {
19907            if (proc.baseProcessTracker != null) {
19908                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19909            }
19910        }
19911    }
19912
19913    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19914            ProcessRecord TOP_APP, boolean doingAll, long now) {
19915        if (app.thread == null) {
19916            return false;
19917        }
19918
19919        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19920
19921        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19922    }
19923
19924    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19925            boolean oomAdj) {
19926        if (isForeground != proc.foregroundServices) {
19927            proc.foregroundServices = isForeground;
19928            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19929                    proc.info.uid);
19930            if (isForeground) {
19931                if (curProcs == null) {
19932                    curProcs = new ArrayList<ProcessRecord>();
19933                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19934                }
19935                if (!curProcs.contains(proc)) {
19936                    curProcs.add(proc);
19937                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19938                            proc.info.packageName, proc.info.uid);
19939                }
19940            } else {
19941                if (curProcs != null) {
19942                    if (curProcs.remove(proc)) {
19943                        mBatteryStatsService.noteEvent(
19944                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19945                                proc.info.packageName, proc.info.uid);
19946                        if (curProcs.size() <= 0) {
19947                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19948                        }
19949                    }
19950                }
19951            }
19952            if (oomAdj) {
19953                updateOomAdjLocked();
19954            }
19955        }
19956    }
19957
19958    private final ActivityRecord resumedAppLocked() {
19959        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19960        String pkg;
19961        int uid;
19962        if (act != null) {
19963            pkg = act.packageName;
19964            uid = act.info.applicationInfo.uid;
19965        } else {
19966            pkg = null;
19967            uid = -1;
19968        }
19969        // Has the UID or resumed package name changed?
19970        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19971                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19972            if (mCurResumedPackage != null) {
19973                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19974                        mCurResumedPackage, mCurResumedUid);
19975            }
19976            mCurResumedPackage = pkg;
19977            mCurResumedUid = uid;
19978            if (mCurResumedPackage != null) {
19979                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19980                        mCurResumedPackage, mCurResumedUid);
19981            }
19982        }
19983        return act;
19984    }
19985
19986    final boolean updateOomAdjLocked(ProcessRecord app) {
19987        final ActivityRecord TOP_ACT = resumedAppLocked();
19988        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19989        final boolean wasCached = app.cached;
19990
19991        mAdjSeq++;
19992
19993        // This is the desired cached adjusment we want to tell it to use.
19994        // If our app is currently cached, we know it, and that is it.  Otherwise,
19995        // we don't know it yet, and it needs to now be cached we will then
19996        // need to do a complete oom adj.
19997        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19998                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19999        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20000                SystemClock.uptimeMillis());
20001        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20002            // Changed to/from cached state, so apps after it in the LRU
20003            // list may also be changed.
20004            updateOomAdjLocked();
20005        }
20006        return success;
20007    }
20008
20009    final void updateOomAdjLocked() {
20010        final ActivityRecord TOP_ACT = resumedAppLocked();
20011        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20012        final long now = SystemClock.uptimeMillis();
20013        final long nowElapsed = SystemClock.elapsedRealtime();
20014        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20015        final int N = mLruProcesses.size();
20016
20017        if (false) {
20018            RuntimeException e = new RuntimeException();
20019            e.fillInStackTrace();
20020            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20021        }
20022
20023        // Reset state in all uid records.
20024        for (int i=mActiveUids.size()-1; i>=0; i--) {
20025            final UidRecord uidRec = mActiveUids.valueAt(i);
20026            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20027                    "Starting update of " + uidRec);
20028            uidRec.reset();
20029        }
20030
20031        mStackSupervisor.rankTaskLayersIfNeeded();
20032
20033        mAdjSeq++;
20034        mNewNumServiceProcs = 0;
20035        mNewNumAServiceProcs = 0;
20036
20037        final int emptyProcessLimit;
20038        final int cachedProcessLimit;
20039        if (mProcessLimit <= 0) {
20040            emptyProcessLimit = cachedProcessLimit = 0;
20041        } else if (mProcessLimit == 1) {
20042            emptyProcessLimit = 1;
20043            cachedProcessLimit = 0;
20044        } else {
20045            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20046            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20047        }
20048
20049        // Let's determine how many processes we have running vs.
20050        // how many slots we have for background processes; we may want
20051        // to put multiple processes in a slot of there are enough of
20052        // them.
20053        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20054                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20055        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20056        if (numEmptyProcs > cachedProcessLimit) {
20057            // If there are more empty processes than our limit on cached
20058            // processes, then use the cached process limit for the factor.
20059            // This ensures that the really old empty processes get pushed
20060            // down to the bottom, so if we are running low on memory we will
20061            // have a better chance at keeping around more cached processes
20062            // instead of a gazillion empty processes.
20063            numEmptyProcs = cachedProcessLimit;
20064        }
20065        int emptyFactor = numEmptyProcs/numSlots;
20066        if (emptyFactor < 1) emptyFactor = 1;
20067        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20068        if (cachedFactor < 1) cachedFactor = 1;
20069        int stepCached = 0;
20070        int stepEmpty = 0;
20071        int numCached = 0;
20072        int numEmpty = 0;
20073        int numTrimming = 0;
20074
20075        mNumNonCachedProcs = 0;
20076        mNumCachedHiddenProcs = 0;
20077
20078        // First update the OOM adjustment for each of the
20079        // application processes based on their current state.
20080        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20081        int nextCachedAdj = curCachedAdj+1;
20082        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20083        int nextEmptyAdj = curEmptyAdj+2;
20084        for (int i=N-1; i>=0; i--) {
20085            ProcessRecord app = mLruProcesses.get(i);
20086            if (!app.killedByAm && app.thread != null) {
20087                app.procStateChanged = false;
20088                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20089
20090                // If we haven't yet assigned the final cached adj
20091                // to the process, do that now.
20092                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20093                    switch (app.curProcState) {
20094                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20095                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20096                            // This process is a cached process holding activities...
20097                            // assign it the next cached value for that type, and then
20098                            // step that cached level.
20099                            app.curRawAdj = curCachedAdj;
20100                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20101                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20102                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20103                                    + ")");
20104                            if (curCachedAdj != nextCachedAdj) {
20105                                stepCached++;
20106                                if (stepCached >= cachedFactor) {
20107                                    stepCached = 0;
20108                                    curCachedAdj = nextCachedAdj;
20109                                    nextCachedAdj += 2;
20110                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20111                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20112                                    }
20113                                }
20114                            }
20115                            break;
20116                        default:
20117                            // For everything else, assign next empty cached process
20118                            // level and bump that up.  Note that this means that
20119                            // long-running services that have dropped down to the
20120                            // cached level will be treated as empty (since their process
20121                            // state is still as a service), which is what we want.
20122                            app.curRawAdj = curEmptyAdj;
20123                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20124                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20125                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20126                                    + ")");
20127                            if (curEmptyAdj != nextEmptyAdj) {
20128                                stepEmpty++;
20129                                if (stepEmpty >= emptyFactor) {
20130                                    stepEmpty = 0;
20131                                    curEmptyAdj = nextEmptyAdj;
20132                                    nextEmptyAdj += 2;
20133                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20134                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20135                                    }
20136                                }
20137                            }
20138                            break;
20139                    }
20140                }
20141
20142                applyOomAdjLocked(app, true, now, nowElapsed);
20143
20144                // Count the number of process types.
20145                switch (app.curProcState) {
20146                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20147                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20148                        mNumCachedHiddenProcs++;
20149                        numCached++;
20150                        if (numCached > cachedProcessLimit) {
20151                            app.kill("cached #" + numCached, true);
20152                        }
20153                        break;
20154                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20155                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20156                                && app.lastActivityTime < oldTime) {
20157                            app.kill("empty for "
20158                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20159                                    / 1000) + "s", true);
20160                        } else {
20161                            numEmpty++;
20162                            if (numEmpty > emptyProcessLimit) {
20163                                app.kill("empty #" + numEmpty, true);
20164                            }
20165                        }
20166                        break;
20167                    default:
20168                        mNumNonCachedProcs++;
20169                        break;
20170                }
20171
20172                if (app.isolated && app.services.size() <= 0) {
20173                    // If this is an isolated process, and there are no
20174                    // services running in it, then the process is no longer
20175                    // needed.  We agressively kill these because we can by
20176                    // definition not re-use the same process again, and it is
20177                    // good to avoid having whatever code was running in them
20178                    // left sitting around after no longer needed.
20179                    app.kill("isolated not needed", true);
20180                } else {
20181                    // Keeping this process, update its uid.
20182                    final UidRecord uidRec = app.uidRecord;
20183                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20184                        uidRec.curProcState = app.curProcState;
20185                    }
20186                }
20187
20188                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20189                        && !app.killedByAm) {
20190                    numTrimming++;
20191                }
20192            }
20193        }
20194
20195        mNumServiceProcs = mNewNumServiceProcs;
20196
20197        // Now determine the memory trimming level of background processes.
20198        // Unfortunately we need to start at the back of the list to do this
20199        // properly.  We only do this if the number of background apps we
20200        // are managing to keep around is less than half the maximum we desire;
20201        // if we are keeping a good number around, we'll let them use whatever
20202        // memory they want.
20203        final int numCachedAndEmpty = numCached + numEmpty;
20204        int memFactor;
20205        if (numCached <= ProcessList.TRIM_CACHED_APPS
20206                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20207            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20208                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20209            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20210                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20211            } else {
20212                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20213            }
20214        } else {
20215            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20216        }
20217        // We always allow the memory level to go up (better).  We only allow it to go
20218        // down if we are in a state where that is allowed, *and* the total number of processes
20219        // has gone down since last time.
20220        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20221                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20222                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20223        if (memFactor > mLastMemoryLevel) {
20224            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20225                memFactor = mLastMemoryLevel;
20226                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20227            }
20228        }
20229        if (memFactor != mLastMemoryLevel) {
20230            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20231        }
20232        mLastMemoryLevel = memFactor;
20233        mLastNumProcesses = mLruProcesses.size();
20234        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20235        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20236        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20237            if (mLowRamStartTime == 0) {
20238                mLowRamStartTime = now;
20239            }
20240            int step = 0;
20241            int fgTrimLevel;
20242            switch (memFactor) {
20243                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20244                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20245                    break;
20246                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20247                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20248                    break;
20249                default:
20250                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20251                    break;
20252            }
20253            int factor = numTrimming/3;
20254            int minFactor = 2;
20255            if (mHomeProcess != null) minFactor++;
20256            if (mPreviousProcess != null) minFactor++;
20257            if (factor < minFactor) factor = minFactor;
20258            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20259            for (int i=N-1; i>=0; i--) {
20260                ProcessRecord app = mLruProcesses.get(i);
20261                if (allChanged || app.procStateChanged) {
20262                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20263                    app.procStateChanged = false;
20264                }
20265                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20266                        && !app.killedByAm) {
20267                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20268                        try {
20269                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20270                                    "Trimming memory of " + app.processName + " to " + curLevel);
20271                            app.thread.scheduleTrimMemory(curLevel);
20272                        } catch (RemoteException e) {
20273                        }
20274                        if (false) {
20275                            // For now we won't do this; our memory trimming seems
20276                            // to be good enough at this point that destroying
20277                            // activities causes more harm than good.
20278                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20279                                    && app != mHomeProcess && app != mPreviousProcess) {
20280                                // Need to do this on its own message because the stack may not
20281                                // be in a consistent state at this point.
20282                                // For these apps we will also finish their activities
20283                                // to help them free memory.
20284                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20285                            }
20286                        }
20287                    }
20288                    app.trimMemoryLevel = curLevel;
20289                    step++;
20290                    if (step >= factor) {
20291                        step = 0;
20292                        switch (curLevel) {
20293                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20294                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20295                                break;
20296                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20297                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20298                                break;
20299                        }
20300                    }
20301                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20302                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20303                            && app.thread != null) {
20304                        try {
20305                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20306                                    "Trimming memory of heavy-weight " + app.processName
20307                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20308                            app.thread.scheduleTrimMemory(
20309                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20310                        } catch (RemoteException e) {
20311                        }
20312                    }
20313                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20314                } else {
20315                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20316                            || app.systemNoUi) && app.pendingUiClean) {
20317                        // If this application is now in the background and it
20318                        // had done UI, then give it the special trim level to
20319                        // have it free UI resources.
20320                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20321                        if (app.trimMemoryLevel < level && app.thread != null) {
20322                            try {
20323                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20324                                        "Trimming memory of bg-ui " + app.processName
20325                                        + " to " + level);
20326                                app.thread.scheduleTrimMemory(level);
20327                            } catch (RemoteException e) {
20328                            }
20329                        }
20330                        app.pendingUiClean = false;
20331                    }
20332                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20333                        try {
20334                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20335                                    "Trimming memory of fg " + app.processName
20336                                    + " to " + fgTrimLevel);
20337                            app.thread.scheduleTrimMemory(fgTrimLevel);
20338                        } catch (RemoteException e) {
20339                        }
20340                    }
20341                    app.trimMemoryLevel = fgTrimLevel;
20342                }
20343            }
20344        } else {
20345            if (mLowRamStartTime != 0) {
20346                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20347                mLowRamStartTime = 0;
20348            }
20349            for (int i=N-1; i>=0; i--) {
20350                ProcessRecord app = mLruProcesses.get(i);
20351                if (allChanged || app.procStateChanged) {
20352                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20353                    app.procStateChanged = false;
20354                }
20355                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20356                        || app.systemNoUi) && app.pendingUiClean) {
20357                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20358                            && app.thread != null) {
20359                        try {
20360                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20361                                    "Trimming memory of ui hidden " + app.processName
20362                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20363                            app.thread.scheduleTrimMemory(
20364                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20365                        } catch (RemoteException e) {
20366                        }
20367                    }
20368                    app.pendingUiClean = false;
20369                }
20370                app.trimMemoryLevel = 0;
20371            }
20372        }
20373
20374        if (mAlwaysFinishActivities) {
20375            // Need to do this on its own message because the stack may not
20376            // be in a consistent state at this point.
20377            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20378        }
20379
20380        if (allChanged) {
20381            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20382        }
20383
20384        // Update from any uid changes.
20385        for (int i=mActiveUids.size()-1; i>=0; i--) {
20386            final UidRecord uidRec = mActiveUids.valueAt(i);
20387            int uidChange = UidRecord.CHANGE_PROCSTATE;
20388            if (uidRec.setProcState != uidRec.curProcState) {
20389                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20390                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20391                        + " to " + uidRec.curProcState);
20392                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20393                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20394                        uidRec.lastBackgroundTime = nowElapsed;
20395                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20396                            // Note: the background settle time is in elapsed realtime, while
20397                            // the handler time base is uptime.  All this means is that we may
20398                            // stop background uids later than we had intended, but that only
20399                            // happens because the device was sleeping so we are okay anyway.
20400                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20401                        }
20402                    }
20403                } else {
20404                    if (uidRec.idle) {
20405                        uidChange = UidRecord.CHANGE_ACTIVE;
20406                        uidRec.idle = false;
20407                    }
20408                    uidRec.lastBackgroundTime = 0;
20409                }
20410                uidRec.setProcState = uidRec.curProcState;
20411                enqueueUidChangeLocked(uidRec, -1, uidChange);
20412                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20413            }
20414        }
20415
20416        if (mProcessStats.shouldWriteNowLocked(now)) {
20417            mHandler.post(new Runnable() {
20418                @Override public void run() {
20419                    synchronized (ActivityManagerService.this) {
20420                        mProcessStats.writeStateAsyncLocked();
20421                    }
20422                }
20423            });
20424        }
20425
20426        if (DEBUG_OOM_ADJ) {
20427            final long duration = SystemClock.uptimeMillis() - now;
20428            if (false) {
20429                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20430                        new RuntimeException("here").fillInStackTrace());
20431            } else {
20432                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20433            }
20434        }
20435    }
20436
20437    final void idleUids() {
20438        synchronized (this) {
20439            final long nowElapsed = SystemClock.elapsedRealtime();
20440            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20441            long nextTime = 0;
20442            for (int i=mActiveUids.size()-1; i>=0; i--) {
20443                final UidRecord uidRec = mActiveUids.valueAt(i);
20444                final long bgTime = uidRec.lastBackgroundTime;
20445                if (bgTime > 0 && !uidRec.idle) {
20446                    if (bgTime <= maxBgTime) {
20447                        uidRec.idle = true;
20448                        doStopUidLocked(uidRec.uid, uidRec);
20449                    } else {
20450                        if (nextTime == 0 || nextTime > bgTime) {
20451                            nextTime = bgTime;
20452                        }
20453                    }
20454                }
20455            }
20456            if (nextTime > 0) {
20457                mHandler.removeMessages(IDLE_UIDS_MSG);
20458                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20459                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20460            }
20461        }
20462    }
20463
20464    final void runInBackgroundDisabled(int uid) {
20465        synchronized (this) {
20466            UidRecord uidRec = mActiveUids.get(uid);
20467            if (uidRec != null) {
20468                // This uid is actually running...  should it be considered background now?
20469                if (uidRec.idle) {
20470                    doStopUidLocked(uidRec.uid, uidRec);
20471                }
20472            } else {
20473                // This uid isn't actually running...  still send a report about it being "stopped".
20474                doStopUidLocked(uid, null);
20475            }
20476        }
20477    }
20478
20479    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20480        mServices.stopInBackgroundLocked(uid);
20481        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20482    }
20483
20484    final void trimApplications() {
20485        synchronized (this) {
20486            int i;
20487
20488            // First remove any unused application processes whose package
20489            // has been removed.
20490            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20491                final ProcessRecord app = mRemovedProcesses.get(i);
20492                if (app.activities.size() == 0
20493                        && app.curReceiver == null && app.services.size() == 0) {
20494                    Slog.i(
20495                        TAG, "Exiting empty application process "
20496                        + app.processName + " ("
20497                        + (app.thread != null ? app.thread.asBinder() : null)
20498                        + ")\n");
20499                    if (app.pid > 0 && app.pid != MY_PID) {
20500                        app.kill("empty", false);
20501                    } else {
20502                        try {
20503                            app.thread.scheduleExit();
20504                        } catch (Exception e) {
20505                            // Ignore exceptions.
20506                        }
20507                    }
20508                    cleanUpApplicationRecordLocked(app, false, true, -1);
20509                    mRemovedProcesses.remove(i);
20510
20511                    if (app.persistent) {
20512                        addAppLocked(app.info, false, null /* ABI override */);
20513                    }
20514                }
20515            }
20516
20517            // Now update the oom adj for all processes.
20518            updateOomAdjLocked();
20519        }
20520    }
20521
20522    /** This method sends the specified signal to each of the persistent apps */
20523    public void signalPersistentProcesses(int sig) throws RemoteException {
20524        if (sig != Process.SIGNAL_USR1) {
20525            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20526        }
20527
20528        synchronized (this) {
20529            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20530                    != PackageManager.PERMISSION_GRANTED) {
20531                throw new SecurityException("Requires permission "
20532                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20533            }
20534
20535            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20536                ProcessRecord r = mLruProcesses.get(i);
20537                if (r.thread != null && r.persistent) {
20538                    Process.sendSignal(r.pid, sig);
20539                }
20540            }
20541        }
20542    }
20543
20544    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20545        if (proc == null || proc == mProfileProc) {
20546            proc = mProfileProc;
20547            profileType = mProfileType;
20548            clearProfilerLocked();
20549        }
20550        if (proc == null) {
20551            return;
20552        }
20553        try {
20554            proc.thread.profilerControl(false, null, profileType);
20555        } catch (RemoteException e) {
20556            throw new IllegalStateException("Process disappeared");
20557        }
20558    }
20559
20560    private void clearProfilerLocked() {
20561        if (mProfileFd != null) {
20562            try {
20563                mProfileFd.close();
20564            } catch (IOException e) {
20565            }
20566        }
20567        mProfileApp = null;
20568        mProfileProc = null;
20569        mProfileFile = null;
20570        mProfileType = 0;
20571        mAutoStopProfiler = false;
20572        mSamplingInterval = 0;
20573    }
20574
20575    public boolean profileControl(String process, int userId, boolean start,
20576            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20577
20578        try {
20579            synchronized (this) {
20580                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20581                // its own permission.
20582                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20583                        != PackageManager.PERMISSION_GRANTED) {
20584                    throw new SecurityException("Requires permission "
20585                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20586                }
20587
20588                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20589                    throw new IllegalArgumentException("null profile info or fd");
20590                }
20591
20592                ProcessRecord proc = null;
20593                if (process != null) {
20594                    proc = findProcessLocked(process, userId, "profileControl");
20595                }
20596
20597                if (start && (proc == null || proc.thread == null)) {
20598                    throw new IllegalArgumentException("Unknown process: " + process);
20599                }
20600
20601                if (start) {
20602                    stopProfilerLocked(null, 0);
20603                    setProfileApp(proc.info, proc.processName, profilerInfo);
20604                    mProfileProc = proc;
20605                    mProfileType = profileType;
20606                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20607                    try {
20608                        fd = fd.dup();
20609                    } catch (IOException e) {
20610                        fd = null;
20611                    }
20612                    profilerInfo.profileFd = fd;
20613                    proc.thread.profilerControl(start, profilerInfo, profileType);
20614                    fd = null;
20615                    mProfileFd = null;
20616                } else {
20617                    stopProfilerLocked(proc, profileType);
20618                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20619                        try {
20620                            profilerInfo.profileFd.close();
20621                        } catch (IOException e) {
20622                        }
20623                    }
20624                }
20625
20626                return true;
20627            }
20628        } catch (RemoteException e) {
20629            throw new IllegalStateException("Process disappeared");
20630        } finally {
20631            if (profilerInfo != null && profilerInfo.profileFd != null) {
20632                try {
20633                    profilerInfo.profileFd.close();
20634                } catch (IOException e) {
20635                }
20636            }
20637        }
20638    }
20639
20640    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20641        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20642                userId, true, ALLOW_FULL_ONLY, callName, null);
20643        ProcessRecord proc = null;
20644        try {
20645            int pid = Integer.parseInt(process);
20646            synchronized (mPidsSelfLocked) {
20647                proc = mPidsSelfLocked.get(pid);
20648            }
20649        } catch (NumberFormatException e) {
20650        }
20651
20652        if (proc == null) {
20653            ArrayMap<String, SparseArray<ProcessRecord>> all
20654                    = mProcessNames.getMap();
20655            SparseArray<ProcessRecord> procs = all.get(process);
20656            if (procs != null && procs.size() > 0) {
20657                proc = procs.valueAt(0);
20658                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20659                    for (int i=1; i<procs.size(); i++) {
20660                        ProcessRecord thisProc = procs.valueAt(i);
20661                        if (thisProc.userId == userId) {
20662                            proc = thisProc;
20663                            break;
20664                        }
20665                    }
20666                }
20667            }
20668        }
20669
20670        return proc;
20671    }
20672
20673    public boolean dumpHeap(String process, int userId, boolean managed,
20674            String path, ParcelFileDescriptor fd) throws RemoteException {
20675
20676        try {
20677            synchronized (this) {
20678                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20679                // its own permission (same as profileControl).
20680                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20681                        != PackageManager.PERMISSION_GRANTED) {
20682                    throw new SecurityException("Requires permission "
20683                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20684                }
20685
20686                if (fd == null) {
20687                    throw new IllegalArgumentException("null fd");
20688                }
20689
20690                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20691                if (proc == null || proc.thread == null) {
20692                    throw new IllegalArgumentException("Unknown process: " + process);
20693                }
20694
20695                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20696                if (!isDebuggable) {
20697                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20698                        throw new SecurityException("Process not debuggable: " + proc);
20699                    }
20700                }
20701
20702                proc.thread.dumpHeap(managed, path, fd);
20703                fd = null;
20704                return true;
20705            }
20706        } catch (RemoteException e) {
20707            throw new IllegalStateException("Process disappeared");
20708        } finally {
20709            if (fd != null) {
20710                try {
20711                    fd.close();
20712                } catch (IOException e) {
20713                }
20714            }
20715        }
20716    }
20717
20718    @Override
20719    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20720            String reportPackage) {
20721        if (processName != null) {
20722            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20723                    "setDumpHeapDebugLimit()");
20724        } else {
20725            synchronized (mPidsSelfLocked) {
20726                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20727                if (proc == null) {
20728                    throw new SecurityException("No process found for calling pid "
20729                            + Binder.getCallingPid());
20730                }
20731                if (!Build.IS_DEBUGGABLE
20732                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20733                    throw new SecurityException("Not running a debuggable build");
20734                }
20735                processName = proc.processName;
20736                uid = proc.uid;
20737                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20738                    throw new SecurityException("Package " + reportPackage + " is not running in "
20739                            + proc);
20740                }
20741            }
20742        }
20743        synchronized (this) {
20744            if (maxMemSize > 0) {
20745                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20746            } else {
20747                if (uid != 0) {
20748                    mMemWatchProcesses.remove(processName, uid);
20749                } else {
20750                    mMemWatchProcesses.getMap().remove(processName);
20751                }
20752            }
20753        }
20754    }
20755
20756    @Override
20757    public void dumpHeapFinished(String path) {
20758        synchronized (this) {
20759            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20760                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20761                        + " does not match last pid " + mMemWatchDumpPid);
20762                return;
20763            }
20764            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20765                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20766                        + " does not match last path " + mMemWatchDumpFile);
20767                return;
20768            }
20769            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20770            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20771        }
20772    }
20773
20774    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20775    public void monitor() {
20776        synchronized (this) { }
20777    }
20778
20779    void onCoreSettingsChange(Bundle settings) {
20780        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20781            ProcessRecord processRecord = mLruProcesses.get(i);
20782            try {
20783                if (processRecord.thread != null) {
20784                    processRecord.thread.setCoreSettings(settings);
20785                }
20786            } catch (RemoteException re) {
20787                /* ignore */
20788            }
20789        }
20790    }
20791
20792    // Multi-user methods
20793
20794    /**
20795     * Start user, if its not already running, but don't bring it to foreground.
20796     */
20797    @Override
20798    public boolean startUserInBackground(final int userId) {
20799        return mUserController.startUser(userId, /* foreground */ false);
20800    }
20801
20802    @Override
20803    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20804        return mUserController.unlockUser(userId, token, secret, listener);
20805    }
20806
20807    @Override
20808    public boolean switchUser(final int targetUserId) {
20809        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20810        UserInfo currentUserInfo;
20811        UserInfo targetUserInfo;
20812        synchronized (this) {
20813            int currentUserId = mUserController.getCurrentUserIdLocked();
20814            currentUserInfo = mUserController.getUserInfo(currentUserId);
20815            targetUserInfo = mUserController.getUserInfo(targetUserId);
20816            if (targetUserInfo == null) {
20817                Slog.w(TAG, "No user info for user #" + targetUserId);
20818                return false;
20819            }
20820            if (!targetUserInfo.supportsSwitchTo()) {
20821                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20822                return false;
20823            }
20824            if (targetUserInfo.isManagedProfile()) {
20825                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20826                return false;
20827            }
20828            mUserController.setTargetUserIdLocked(targetUserId);
20829        }
20830        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20831        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20832        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20833        return true;
20834    }
20835
20836    void scheduleStartProfilesLocked() {
20837        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20838            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20839                    DateUtils.SECOND_IN_MILLIS);
20840        }
20841    }
20842
20843    @Override
20844    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20845        return mUserController.stopUser(userId, force, callback);
20846    }
20847
20848    @Override
20849    public UserInfo getCurrentUser() {
20850        return mUserController.getCurrentUser();
20851    }
20852
20853    @Override
20854    public boolean isUserRunning(int userId, int flags) {
20855        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20856                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20857            String msg = "Permission Denial: isUserRunning() from pid="
20858                    + Binder.getCallingPid()
20859                    + ", uid=" + Binder.getCallingUid()
20860                    + " requires " + INTERACT_ACROSS_USERS;
20861            Slog.w(TAG, msg);
20862            throw new SecurityException(msg);
20863        }
20864        synchronized (this) {
20865            return mUserController.isUserRunningLocked(userId, flags);
20866        }
20867    }
20868
20869    @Override
20870    public int[] getRunningUserIds() {
20871        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20872                != PackageManager.PERMISSION_GRANTED) {
20873            String msg = "Permission Denial: isUserRunning() from pid="
20874                    + Binder.getCallingPid()
20875                    + ", uid=" + Binder.getCallingUid()
20876                    + " requires " + INTERACT_ACROSS_USERS;
20877            Slog.w(TAG, msg);
20878            throw new SecurityException(msg);
20879        }
20880        synchronized (this) {
20881            return mUserController.getStartedUserArrayLocked();
20882        }
20883    }
20884
20885    @Override
20886    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20887        mUserController.registerUserSwitchObserver(observer);
20888    }
20889
20890    @Override
20891    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20892        mUserController.unregisterUserSwitchObserver(observer);
20893    }
20894
20895    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20896        if (info == null) return null;
20897        ApplicationInfo newInfo = new ApplicationInfo(info);
20898        newInfo.initForUser(userId);
20899        return newInfo;
20900    }
20901
20902    public boolean isUserStopped(int userId) {
20903        synchronized (this) {
20904            return mUserController.getStartedUserStateLocked(userId) == null;
20905        }
20906    }
20907
20908    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20909        if (aInfo == null
20910                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20911            return aInfo;
20912        }
20913
20914        ActivityInfo info = new ActivityInfo(aInfo);
20915        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20916        return info;
20917    }
20918
20919    private boolean processSanityChecksLocked(ProcessRecord process) {
20920        if (process == null || process.thread == null) {
20921            return false;
20922        }
20923
20924        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20925        if (!isDebuggable) {
20926            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20927                return false;
20928            }
20929        }
20930
20931        return true;
20932    }
20933
20934    public boolean startBinderTracking() throws RemoteException {
20935        synchronized (this) {
20936            mBinderTransactionTrackingEnabled = true;
20937            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20938            // permission (same as profileControl).
20939            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20940                    != PackageManager.PERMISSION_GRANTED) {
20941                throw new SecurityException("Requires permission "
20942                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20943            }
20944
20945            for (int i = 0; i < mLruProcesses.size(); i++) {
20946                ProcessRecord process = mLruProcesses.get(i);
20947                if (!processSanityChecksLocked(process)) {
20948                    continue;
20949                }
20950                try {
20951                    process.thread.startBinderTracking();
20952                } catch (RemoteException e) {
20953                    Log.v(TAG, "Process disappared");
20954                }
20955            }
20956            return true;
20957        }
20958    }
20959
20960    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20961        try {
20962            synchronized (this) {
20963                mBinderTransactionTrackingEnabled = false;
20964                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20965                // permission (same as profileControl).
20966                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20967                        != PackageManager.PERMISSION_GRANTED) {
20968                    throw new SecurityException("Requires permission "
20969                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20970                }
20971
20972                if (fd == null) {
20973                    throw new IllegalArgumentException("null fd");
20974                }
20975
20976                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20977                pw.println("Binder transaction traces for all processes.\n");
20978                for (ProcessRecord process : mLruProcesses) {
20979                    if (!processSanityChecksLocked(process)) {
20980                        continue;
20981                    }
20982
20983                    pw.println("Traces for process: " + process.processName);
20984                    pw.flush();
20985                    try {
20986                        TransferPipe tp = new TransferPipe();
20987                        try {
20988                            process.thread.stopBinderTrackingAndDump(
20989                                    tp.getWriteFd().getFileDescriptor());
20990                            tp.go(fd.getFileDescriptor());
20991                        } finally {
20992                            tp.kill();
20993                        }
20994                    } catch (IOException e) {
20995                        pw.println("Failure while dumping IPC traces from " + process +
20996                                ".  Exception: " + e);
20997                        pw.flush();
20998                    } catch (RemoteException e) {
20999                        pw.println("Got a RemoteException while dumping IPC traces from " +
21000                                process + ".  Exception: " + e);
21001                        pw.flush();
21002                    }
21003                }
21004                fd = null;
21005                return true;
21006            }
21007        } finally {
21008            if (fd != null) {
21009                try {
21010                    fd.close();
21011                } catch (IOException e) {
21012                }
21013            }
21014        }
21015    }
21016
21017    private final class LocalService extends ActivityManagerInternal {
21018        @Override
21019        public void onWakefulnessChanged(int wakefulness) {
21020            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21021        }
21022
21023        @Override
21024        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21025                String processName, String abiOverride, int uid, Runnable crashHandler) {
21026            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21027                    processName, abiOverride, uid, crashHandler);
21028        }
21029
21030        @Override
21031        public SleepToken acquireSleepToken(String tag) {
21032            Preconditions.checkNotNull(tag);
21033
21034            synchronized (ActivityManagerService.this) {
21035                SleepTokenImpl token = new SleepTokenImpl(tag);
21036                mSleepTokens.add(token);
21037                updateSleepIfNeededLocked();
21038                applyVrModeIfNeededLocked(mFocusedActivity, false);
21039                return token;
21040            }
21041        }
21042
21043        @Override
21044        public ComponentName getHomeActivityForUser(int userId) {
21045            synchronized (ActivityManagerService.this) {
21046                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21047                return homeActivity == null ? null : homeActivity.realActivity;
21048            }
21049        }
21050
21051        @Override
21052        public void onUserRemoved(int userId) {
21053            synchronized (ActivityManagerService.this) {
21054                ActivityManagerService.this.onUserStoppedLocked(userId);
21055            }
21056        }
21057
21058        @Override
21059        public void onLocalVoiceInteractionStarted(IBinder activity,
21060                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21061            synchronized (ActivityManagerService.this) {
21062                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21063                        voiceSession, voiceInteractor);
21064            }
21065        }
21066
21067        @Override
21068        public void notifyStartingWindowDrawn() {
21069            synchronized (ActivityManagerService.this) {
21070                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21071            }
21072        }
21073
21074        @Override
21075        public void notifyAppTransitionStarting(int reason) {
21076            synchronized (ActivityManagerService.this) {
21077                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21078            }
21079        }
21080
21081        @Override
21082        public void notifyAppTransitionFinished() {
21083            synchronized (ActivityManagerService.this) {
21084                mStackSupervisor.notifyAppTransitionDone();
21085            }
21086        }
21087
21088        @Override
21089        public void notifyAppTransitionCancelled() {
21090            synchronized (ActivityManagerService.this) {
21091                mStackSupervisor.notifyAppTransitionDone();
21092            }
21093        }
21094
21095        @Override
21096        public List<IBinder> getTopVisibleActivities() {
21097            synchronized (ActivityManagerService.this) {
21098                return mStackSupervisor.getTopVisibleActivities();
21099            }
21100        }
21101
21102        @Override
21103        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21104            synchronized (ActivityManagerService.this) {
21105                mStackSupervisor.setDockedStackMinimized(minimized);
21106            }
21107        }
21108
21109        @Override
21110        public void killForegroundAppsForUser(int userHandle) {
21111            synchronized (ActivityManagerService.this) {
21112                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21113                final int NP = mProcessNames.getMap().size();
21114                for (int ip = 0; ip < NP; ip++) {
21115                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21116                    final int NA = apps.size();
21117                    for (int ia = 0; ia < NA; ia++) {
21118                        final ProcessRecord app = apps.valueAt(ia);
21119                        if (app.persistent) {
21120                            // We don't kill persistent processes.
21121                            continue;
21122                        }
21123                        if (app.removed) {
21124                            procs.add(app);
21125                        } else if (app.userId == userHandle && app.foregroundActivities) {
21126                            app.removed = true;
21127                            procs.add(app);
21128                        }
21129                    }
21130                }
21131
21132                final int N = procs.size();
21133                for (int i = 0; i < N; i++) {
21134                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21135                }
21136            }
21137        }
21138    }
21139
21140    private final class SleepTokenImpl extends SleepToken {
21141        private final String mTag;
21142        private final long mAcquireTime;
21143
21144        public SleepTokenImpl(String tag) {
21145            mTag = tag;
21146            mAcquireTime = SystemClock.uptimeMillis();
21147        }
21148
21149        @Override
21150        public void release() {
21151            synchronized (ActivityManagerService.this) {
21152                if (mSleepTokens.remove(this)) {
21153                    updateSleepIfNeededLocked();
21154                }
21155            }
21156        }
21157
21158        @Override
21159        public String toString() {
21160            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21161        }
21162    }
21163
21164    /**
21165     * An implementation of IAppTask, that allows an app to manage its own tasks via
21166     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21167     * only the process that calls getAppTasks() can call the AppTask methods.
21168     */
21169    class AppTaskImpl extends IAppTask.Stub {
21170        private int mTaskId;
21171        private int mCallingUid;
21172
21173        public AppTaskImpl(int taskId, int callingUid) {
21174            mTaskId = taskId;
21175            mCallingUid = callingUid;
21176        }
21177
21178        private void checkCaller() {
21179            if (mCallingUid != Binder.getCallingUid()) {
21180                throw new SecurityException("Caller " + mCallingUid
21181                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21182            }
21183        }
21184
21185        @Override
21186        public void finishAndRemoveTask() {
21187            checkCaller();
21188
21189            synchronized (ActivityManagerService.this) {
21190                long origId = Binder.clearCallingIdentity();
21191                try {
21192                    // We remove the task from recents to preserve backwards
21193                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21194                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21195                    }
21196                } finally {
21197                    Binder.restoreCallingIdentity(origId);
21198                }
21199            }
21200        }
21201
21202        @Override
21203        public ActivityManager.RecentTaskInfo getTaskInfo() {
21204            checkCaller();
21205
21206            synchronized (ActivityManagerService.this) {
21207                long origId = Binder.clearCallingIdentity();
21208                try {
21209                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21210                    if (tr == null) {
21211                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21212                    }
21213                    return createRecentTaskInfoFromTaskRecord(tr);
21214                } finally {
21215                    Binder.restoreCallingIdentity(origId);
21216                }
21217            }
21218        }
21219
21220        @Override
21221        public void moveToFront() {
21222            checkCaller();
21223            // Will bring task to front if it already has a root activity.
21224            final long origId = Binder.clearCallingIdentity();
21225            try {
21226                synchronized (this) {
21227                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21228                }
21229            } finally {
21230                Binder.restoreCallingIdentity(origId);
21231            }
21232        }
21233
21234        @Override
21235        public int startActivity(IBinder whoThread, String callingPackage,
21236                Intent intent, String resolvedType, Bundle bOptions) {
21237            checkCaller();
21238
21239            int callingUser = UserHandle.getCallingUserId();
21240            TaskRecord tr;
21241            IApplicationThread appThread;
21242            synchronized (ActivityManagerService.this) {
21243                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21244                if (tr == null) {
21245                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21246                }
21247                appThread = ApplicationThreadNative.asInterface(whoThread);
21248                if (appThread == null) {
21249                    throw new IllegalArgumentException("Bad app thread " + appThread);
21250                }
21251            }
21252            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21253                    resolvedType, null, null, null, null, 0, 0, null, null,
21254                    null, bOptions, false, callingUser, null, tr);
21255        }
21256
21257        @Override
21258        public void setExcludeFromRecents(boolean exclude) {
21259            checkCaller();
21260
21261            synchronized (ActivityManagerService.this) {
21262                long origId = Binder.clearCallingIdentity();
21263                try {
21264                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21265                    if (tr == null) {
21266                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21267                    }
21268                    Intent intent = tr.getBaseIntent();
21269                    if (exclude) {
21270                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21271                    } else {
21272                        intent.setFlags(intent.getFlags()
21273                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21274                    }
21275                } finally {
21276                    Binder.restoreCallingIdentity(origId);
21277                }
21278            }
21279        }
21280    }
21281
21282    /**
21283     * Kill processes for the user with id userId and that depend on the package named packageName
21284     */
21285    @Override
21286    public void killPackageDependents(String packageName, int userId) {
21287        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21288        if (packageName == null) {
21289            throw new NullPointerException(
21290                    "Cannot kill the dependents of a package without its name.");
21291        }
21292
21293        long callingId = Binder.clearCallingIdentity();
21294        IPackageManager pm = AppGlobals.getPackageManager();
21295        int pkgUid = -1;
21296        try {
21297            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21298        } catch (RemoteException e) {
21299        }
21300        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21301            throw new IllegalArgumentException(
21302                    "Cannot kill dependents of non-existing package " + packageName);
21303        }
21304        try {
21305            synchronized(this) {
21306                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21307                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21308                        "dep: " + packageName);
21309            }
21310        } finally {
21311            Binder.restoreCallingIdentity(callingId);
21312        }
21313    }
21314}
21315