ActivityManagerService.java revision b6ccae999fe285eb9c0c17ca88c271046afdfc20
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.Notification;
101import android.app.NotificationManager;
102import android.app.PendingIntent;
103import android.app.ProfilerInfo;
104import android.app.admin.DevicePolicyManager;
105import android.app.admin.DevicePolicyManagerInternal;
106import android.app.assist.AssistContent;
107import android.app.assist.AssistStructure;
108import android.app.backup.IBackupManager;
109import android.app.usage.UsageEvents;
110import android.app.usage.UsageStatsManagerInternal;
111import android.appwidget.AppWidgetManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.PackageManager.NameNotFoundException;
136import android.content.pm.PackageManagerInternal;
137import android.content.pm.ParceledListSlice;
138import android.content.pm.PathPermission;
139import android.content.pm.PermissionInfo;
140import android.content.pm.ProviderInfo;
141import android.content.pm.ResolveInfo;
142import android.content.pm.ServiceInfo;
143import android.content.pm.UserInfo;
144import android.content.res.CompatibilityInfo;
145import android.content.res.Configuration;
146import android.content.res.Resources;
147import android.database.ContentObserver;
148import android.graphics.Bitmap;
149import android.graphics.Point;
150import android.graphics.Rect;
151import android.location.LocationManager;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.BatteryStats;
156import android.os.Binder;
157import android.os.Build;
158import android.os.Bundle;
159import android.os.Debug;
160import android.os.DropBoxManager;
161import android.os.Environment;
162import android.os.FactoryTest;
163import android.os.FileObserver;
164import android.os.FileUtils;
165import android.os.Handler;
166import android.os.IBinder;
167import android.os.IPermissionController;
168import android.os.IProcessInfoService;
169import android.os.IProgressListener;
170import android.os.Looper;
171import android.os.Message;
172import android.os.Parcel;
173import android.os.ParcelFileDescriptor;
174import android.os.PersistableBundle;
175import android.os.PowerManager;
176import android.os.PowerManagerInternal;
177import android.os.Process;
178import android.os.RemoteCallbackList;
179import android.os.RemoteException;
180import android.os.ResultReceiver;
181import android.os.ServiceManager;
182import android.os.StrictMode;
183import android.os.SystemClock;
184import android.os.SystemProperties;
185import android.os.Trace;
186import android.os.TransactionTooLargeException;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.os.WorkSource;
191import android.os.storage.IMountService;
192import android.os.storage.MountServiceInternal;
193import android.os.storage.StorageManager;
194import android.provider.Settings;
195import android.service.voice.IVoiceInteractionSession;
196import android.service.voice.VoiceInteractionManagerInternal;
197import android.service.voice.VoiceInteractionSession;
198import android.text.format.DateUtils;
199import android.text.format.Time;
200import android.util.ArrayMap;
201import android.util.ArraySet;
202import android.util.AtomicFile;
203import android.util.DebugUtils;
204import android.util.EventLog;
205import android.util.LocaleList;
206import android.util.Log;
207import android.util.Pair;
208import android.util.PrintWriterPrinter;
209import android.util.Slog;
210import android.util.SparseArray;
211import android.util.TimeUtils;
212import android.util.Xml;
213import android.view.Display;
214import android.view.Gravity;
215import android.view.LayoutInflater;
216import android.view.View;
217import android.view.WindowManager;
218
219import java.io.File;
220import java.io.FileDescriptor;
221import java.io.FileInputStream;
222import java.io.FileNotFoundException;
223import java.io.FileOutputStream;
224import java.io.IOException;
225import java.io.InputStreamReader;
226import java.io.PrintWriter;
227import java.io.StringWriter;
228import java.lang.ref.WeakReference;
229import java.nio.charset.StandardCharsets;
230import java.util.ArrayList;
231import java.util.Arrays;
232import java.util.Collections;
233import java.util.Comparator;
234import java.util.HashMap;
235import java.util.HashSet;
236import java.util.Iterator;
237import java.util.List;
238import java.util.Locale;
239import java.util.Map;
240import java.util.Set;
241import java.util.concurrent.atomic.AtomicBoolean;
242import java.util.concurrent.atomic.AtomicLong;
243
244import dalvik.system.VMRuntime;
245
246import libcore.io.IoUtils;
247import libcore.util.EmptyArray;
248
249import static android.Manifest.permission.INTERACT_ACROSS_USERS;
250import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
251import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
252import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
253import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
254import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
255import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
256import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
257import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
258import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
259import static android.app.ActivityManager.StackId.HOME_STACK_ID;
260import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
261import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
262import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
263import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
264import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
265import static android.content.pm.PackageManager.GET_PROVIDERS;
266import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
267import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
268import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
269import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
270import static android.content.pm.PackageManager.PERMISSION_GRANTED;
271import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
272import static android.provider.Settings.Global.DEBUG_APP;
273import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
274import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
275import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
276import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
277import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
278import static android.provider.Settings.System.FONT_SCALE;
279import static com.android.internal.util.XmlUtils.readBooleanAttribute;
280import static com.android.internal.util.XmlUtils.readIntAttribute;
281import static com.android.internal.util.XmlUtils.readLongAttribute;
282import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
283import static com.android.internal.util.XmlUtils.writeIntAttribute;
284import static com.android.internal.util.XmlUtils.writeLongAttribute;
285import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
317import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
341import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
342import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
343import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
344import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
345import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
346import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
347import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
348import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
349import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
350import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
351import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
352import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
353import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
354import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
355import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
356import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
357import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
358import static org.xmlpull.v1.XmlPullParser.START_TAG;
359
360public final class ActivityManagerService extends ActivityManagerNative
361        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
362
363    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
364    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
365    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
366    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
367    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
368    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
369    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
370    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
371    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
372    private static final String TAG_LRU = TAG + POSTFIX_LRU;
373    private static final String TAG_MU = TAG + POSTFIX_MU;
374    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
375    private static final String TAG_POWER = TAG + POSTFIX_POWER;
376    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
377    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
378    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
379    private static final String TAG_PSS = TAG + POSTFIX_PSS;
380    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
381    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
382    private static final String TAG_STACK = TAG + POSTFIX_STACK;
383    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
384    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
385    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
386    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
387    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
388
389    /** Control over CPU and battery monitoring */
390    // write battery stats every 30 minutes.
391    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
392    static final boolean MONITOR_CPU_USAGE = true;
393    // don't sample cpu less than every 5 seconds.
394    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
395    // wait possibly forever for next cpu sample.
396    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
397    static final boolean MONITOR_THREAD_CPU_USAGE = false;
398
399    // The flags that are set for all calls we make to the package manager.
400    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
401
402    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
403
404    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
405
406    // Amount of time after a call to stopAppSwitches() during which we will
407    // prevent further untrusted switches from happening.
408    static final long APP_SWITCH_DELAY_TIME = 5*1000;
409
410    // How long we wait for a launched process to attach to the activity manager
411    // before we decide it's never going to come up for real.
412    static final int PROC_START_TIMEOUT = 10*1000;
413    // How long we wait for an attached process to publish its content providers
414    // before we decide it must be hung.
415    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
416
417    // How long we will retain processes hosting content providers in the "last activity"
418    // state before allowing them to drop down to the regular cached LRU list.  This is
419    // to avoid thrashing of provider processes under low memory situations.
420    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
421
422    // How long we wait for a launched process to attach to the activity manager
423    // before we decide it's never going to come up for real, when the process was
424    // started with a wrapper for instrumentation (such as Valgrind) because it
425    // could take much longer than usual.
426    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
427
428    // How long to wait after going idle before forcing apps to GC.
429    static final int GC_TIMEOUT = 5*1000;
430
431    // The minimum amount of time between successive GC requests for a process.
432    static final int GC_MIN_INTERVAL = 60*1000;
433
434    // The minimum amount of time between successive PSS requests for a process.
435    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
436
437    // The minimum amount of time between successive PSS requests for a process
438    // when the request is due to the memory state being lowered.
439    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
440
441    // The rate at which we check for apps using excessive power -- 15 mins.
442    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
443
444    // The minimum sample duration we will allow before deciding we have
445    // enough data on wake locks to start killing things.
446    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
447
448    // The minimum sample duration we will allow before deciding we have
449    // enough data on CPU usage to start killing things.
450    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
451
452    // How long we allow a receiver to run before giving up on it.
453    static final int BROADCAST_FG_TIMEOUT = 10*1000;
454    static final int BROADCAST_BG_TIMEOUT = 60*1000;
455
456    // How long we wait until we timeout on key dispatching.
457    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
458
459    // How long we wait until we timeout on key dispatching during instrumentation.
460    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
461
462    // This is the amount of time an app needs to be running a foreground service before
463    // we will consider it to be doing interaction for usage stats.
464    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
465
466    // Maximum amount of time we will allow to elapse before re-reporting usage stats
467    // interaction with foreground processes.
468    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
469
470    // This is the amount of time we allow an app to settle after it goes into the background,
471    // before we start restricting what it can do.
472    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
473
474    // How long to wait in getAssistContextExtras for the activity and foreground services
475    // to respond with the result.
476    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
477
478    // How long top wait when going through the modern assist (which doesn't need to block
479    // on getting this result before starting to launch its UI).
480    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
481
482    // Maximum number of persisted Uri grants a package is allowed
483    static final int MAX_PERSISTED_URI_GRANTS = 128;
484
485    static final int MY_PID = Process.myPid();
486
487    static final String[] EMPTY_STRING_ARRAY = new String[0];
488
489    // How many bytes to write into the dropbox log before truncating
490    static final int DROPBOX_MAX_SIZE = 256 * 1024;
491
492    // Access modes for handleIncomingUser.
493    static final int ALLOW_NON_FULL = 0;
494    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
495    static final int ALLOW_FULL_ONLY = 2;
496
497    // Delay in notifying task stack change listeners (in millis)
498    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
499
500    // Necessary ApplicationInfo flags to mark an app as persistent
501    private static final int PERSISTENT_MASK =
502            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
503
504    // Intent sent when remote bugreport collection has been completed
505    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
506            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
507
508    // Delay to disable app launch boost
509    static final int APP_BOOST_MESSAGE_DELAY = 3000;
510    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
511    static final int APP_BOOST_TIMEOUT = 2500;
512
513    // Used to indicate that a task is removed it should also be removed from recents.
514    private static final boolean REMOVE_FROM_RECENTS = true;
515    // Used to indicate that an app transition should be animated.
516    static final boolean ANIMATE = true;
517
518    // Determines whether to take full screen screenshots
519    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
520    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
521
522    private static native int nativeMigrateToBoost();
523    private static native int nativeMigrateFromBoost();
524    private boolean mIsBoosted = false;
525    private long mBoostStartTime = 0;
526
527    /** All system services */
528    SystemServiceManager mSystemServiceManager;
529
530    private Installer mInstaller;
531
532    /** Run all ActivityStacks through this */
533    final ActivityStackSupervisor mStackSupervisor;
534
535    final ActivityStarter mActivityStarter;
536
537    /** Task stack change listeners. */
538    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
539            new RemoteCallbackList<ITaskStackListener>();
540
541    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
542
543    public IntentFirewall mIntentFirewall;
544
545    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
546    // default actuion automatically.  Important for devices without direct input
547    // devices.
548    private boolean mShowDialogs = true;
549    private boolean mInVrMode = false;
550
551    BroadcastQueue mFgBroadcastQueue;
552    BroadcastQueue mBgBroadcastQueue;
553    // Convenient for easy iteration over the queues. Foreground is first
554    // so that dispatch of foreground broadcasts gets precedence.
555    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
556
557    BroadcastQueue broadcastQueueForIntent(Intent intent) {
558        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
559        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
560                "Broadcast intent " + intent + " on "
561                + (isFg ? "foreground" : "background") + " queue");
562        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
563    }
564
565    /**
566     * Activity we have told the window manager to have key focus.
567     */
568    ActivityRecord mFocusedActivity = null;
569
570    /**
571     * User id of the last activity mFocusedActivity was set to.
572     */
573    private int mLastFocusedUserId;
574
575    /**
576     * If non-null, we are tracking the time the user spends in the currently focused app.
577     */
578    private AppTimeTracker mCurAppTimeTracker;
579
580    /**
581     * List of intents that were used to start the most recent tasks.
582     */
583    final RecentTasks mRecentTasks;
584
585    /**
586     * For addAppTask: cached of the last activity component that was added.
587     */
588    ComponentName mLastAddedTaskComponent;
589
590    /**
591     * For addAppTask: cached of the last activity uid that was added.
592     */
593    int mLastAddedTaskUid;
594
595    /**
596     * For addAppTask: cached of the last ActivityInfo that was added.
597     */
598    ActivityInfo mLastAddedTaskActivity;
599
600    /**
601     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
602     */
603    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
604
605    /**
606     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
607     */
608    String mDeviceOwnerName;
609
610    final UserController mUserController;
611
612    final AppErrors mAppErrors;
613
614    boolean mDoingSetFocusedActivity;
615
616    public boolean canShowErrorDialogs() {
617        return mShowDialogs && !mSleeping && !mShuttingDown;
618    }
619
620    public class PendingAssistExtras extends Binder implements Runnable {
621        public final ActivityRecord activity;
622        public final Bundle extras;
623        public final Intent intent;
624        public final String hint;
625        public final IResultReceiver receiver;
626        public final int userHandle;
627        public boolean haveResult = false;
628        public Bundle result = null;
629        public AssistStructure structure = null;
630        public AssistContent content = null;
631        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
632                String _hint, IResultReceiver _receiver, int _userHandle) {
633            activity = _activity;
634            extras = _extras;
635            intent = _intent;
636            hint = _hint;
637            receiver = _receiver;
638            userHandle = _userHandle;
639        }
640        @Override
641        public void run() {
642            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
643            synchronized (this) {
644                haveResult = true;
645                notifyAll();
646            }
647            pendingAssistExtrasTimedOut(this);
648        }
649    }
650
651    final ArrayList<PendingAssistExtras> mPendingAssistExtras
652            = new ArrayList<PendingAssistExtras>();
653
654    /**
655     * Process management.
656     */
657    final ProcessList mProcessList = new ProcessList();
658
659    /**
660     * All of the applications we currently have running organized by name.
661     * The keys are strings of the application package name (as
662     * returned by the package manager), and the keys are ApplicationRecord
663     * objects.
664     */
665    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
666
667    /**
668     * Tracking long-term execution of processes to look for abuse and other
669     * bad app behavior.
670     */
671    final ProcessStatsService mProcessStats;
672
673    /**
674     * The currently running isolated processes.
675     */
676    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
677
678    /**
679     * Counter for assigning isolated process uids, to avoid frequently reusing the
680     * same ones.
681     */
682    int mNextIsolatedProcessUid = 0;
683
684    /**
685     * The currently running heavy-weight process, if any.
686     */
687    ProcessRecord mHeavyWeightProcess = null;
688
689    /**
690     * All of the processes we currently have running organized by pid.
691     * The keys are the pid running the application.
692     *
693     * <p>NOTE: This object is protected by its own lock, NOT the global
694     * activity manager lock!
695     */
696    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
697
698    /**
699     * All of the processes that have been forced to be foreground.  The key
700     * is the pid of the caller who requested it (we hold a death
701     * link on it).
702     */
703    abstract class ForegroundToken implements IBinder.DeathRecipient {
704        int pid;
705        IBinder token;
706    }
707    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
708
709    /**
710     * List of records for processes that someone had tried to start before the
711     * system was ready.  We don't start them at that point, but ensure they
712     * are started by the time booting is complete.
713     */
714    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
715
716    /**
717     * List of persistent applications that are in the process
718     * of being started.
719     */
720    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
721
722    /**
723     * Processes that are being forcibly torn down.
724     */
725    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
726
727    /**
728     * List of running applications, sorted by recent usage.
729     * The first entry in the list is the least recently used.
730     */
731    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
732
733    /**
734     * Where in mLruProcesses that the processes hosting activities start.
735     */
736    int mLruProcessActivityStart = 0;
737
738    /**
739     * Where in mLruProcesses that the processes hosting services start.
740     * This is after (lower index) than mLruProcessesActivityStart.
741     */
742    int mLruProcessServiceStart = 0;
743
744    /**
745     * List of processes that should gc as soon as things are idle.
746     */
747    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
748
749    /**
750     * Processes we want to collect PSS data from.
751     */
752    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
753
754    private boolean mBinderTransactionTrackingEnabled = false;
755
756    /**
757     * Last time we requested PSS data of all processes.
758     */
759    long mLastFullPssTime = SystemClock.uptimeMillis();
760
761    /**
762     * If set, the next time we collect PSS data we should do a full collection
763     * with data from native processes and the kernel.
764     */
765    boolean mFullPssPending = false;
766
767    /**
768     * This is the process holding what we currently consider to be
769     * the "home" activity.
770     */
771    ProcessRecord mHomeProcess;
772
773    /**
774     * This is the process holding the activity the user last visited that
775     * is in a different process from the one they are currently in.
776     */
777    ProcessRecord mPreviousProcess;
778
779    /**
780     * The time at which the previous process was last visible.
781     */
782    long mPreviousProcessVisibleTime;
783
784    /**
785     * Track all uids that have actively running processes.
786     */
787    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
788
789    /**
790     * This is for verifying the UID report flow.
791     */
792    static final boolean VALIDATE_UID_STATES = true;
793    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
794
795    /**
796     * Packages that the user has asked to have run in screen size
797     * compatibility mode instead of filling the screen.
798     */
799    final CompatModePackages mCompatModePackages;
800
801    /**
802     * Set of IntentSenderRecord objects that are currently active.
803     */
804    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
805            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
806
807    /**
808     * Fingerprints (hashCode()) of stack traces that we've
809     * already logged DropBox entries for.  Guarded by itself.  If
810     * something (rogue user app) forces this over
811     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
812     */
813    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
814    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
815
816    /**
817     * Strict Mode background batched logging state.
818     *
819     * The string buffer is guarded by itself, and its lock is also
820     * used to determine if another batched write is already
821     * in-flight.
822     */
823    private final StringBuilder mStrictModeBuffer = new StringBuilder();
824
825    /**
826     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
827     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
828     */
829    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
830
831    /**
832     * Resolver for broadcast intents to registered receivers.
833     * Holds BroadcastFilter (subclass of IntentFilter).
834     */
835    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
836            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
837        @Override
838        protected boolean allowFilterResult(
839                BroadcastFilter filter, List<BroadcastFilter> dest) {
840            IBinder target = filter.receiverList.receiver.asBinder();
841            for (int i = dest.size() - 1; i >= 0; i--) {
842                if (dest.get(i).receiverList.receiver.asBinder() == target) {
843                    return false;
844                }
845            }
846            return true;
847        }
848
849        @Override
850        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
851            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
852                    || userId == filter.owningUserId) {
853                return super.newResult(filter, match, userId);
854            }
855            return null;
856        }
857
858        @Override
859        protected BroadcastFilter[] newArray(int size) {
860            return new BroadcastFilter[size];
861        }
862
863        @Override
864        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
865            return packageName.equals(filter.packageName);
866        }
867    };
868
869    /**
870     * State of all active sticky broadcasts per user.  Keys are the action of the
871     * sticky Intent, values are an ArrayList of all broadcasted intents with
872     * that action (which should usually be one).  The SparseArray is keyed
873     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
874     * for stickies that are sent to all users.
875     */
876    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
877            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
878
879    final ActiveServices mServices;
880
881    final static class Association {
882        final int mSourceUid;
883        final String mSourceProcess;
884        final int mTargetUid;
885        final ComponentName mTargetComponent;
886        final String mTargetProcess;
887
888        int mCount;
889        long mTime;
890
891        int mNesting;
892        long mStartTime;
893
894        // states of the source process when the bind occurred.
895        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
896        long mLastStateUptime;
897        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
898                - ActivityManager.MIN_PROCESS_STATE+1];
899
900        Association(int sourceUid, String sourceProcess, int targetUid,
901                ComponentName targetComponent, String targetProcess) {
902            mSourceUid = sourceUid;
903            mSourceProcess = sourceProcess;
904            mTargetUid = targetUid;
905            mTargetComponent = targetComponent;
906            mTargetProcess = targetProcess;
907        }
908    }
909
910    /**
911     * When service association tracking is enabled, this is all of the associations we
912     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
913     * -> association data.
914     */
915    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
916            mAssociations = new SparseArray<>();
917    boolean mTrackingAssociations;
918
919    /**
920     * Backup/restore process management
921     */
922    String mBackupAppName = null;
923    BackupRecord mBackupTarget = null;
924
925    final ProviderMap mProviderMap;
926
927    /**
928     * List of content providers who have clients waiting for them.  The
929     * application is currently being launched and the provider will be
930     * removed from this list once it is published.
931     */
932    final ArrayList<ContentProviderRecord> mLaunchingProviders
933            = new ArrayList<ContentProviderRecord>();
934
935    /**
936     * File storing persisted {@link #mGrantedUriPermissions}.
937     */
938    private final AtomicFile mGrantFile;
939
940    /** XML constants used in {@link #mGrantFile} */
941    private static final String TAG_URI_GRANTS = "uri-grants";
942    private static final String TAG_URI_GRANT = "uri-grant";
943    private static final String ATTR_USER_HANDLE = "userHandle";
944    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
945    private static final String ATTR_TARGET_USER_ID = "targetUserId";
946    private static final String ATTR_SOURCE_PKG = "sourcePkg";
947    private static final String ATTR_TARGET_PKG = "targetPkg";
948    private static final String ATTR_URI = "uri";
949    private static final String ATTR_MODE_FLAGS = "modeFlags";
950    private static final String ATTR_CREATED_TIME = "createdTime";
951    private static final String ATTR_PREFIX = "prefix";
952
953    /**
954     * Global set of specific {@link Uri} permissions that have been granted.
955     * This optimized lookup structure maps from {@link UriPermission#targetUid}
956     * to {@link UriPermission#uri} to {@link UriPermission}.
957     */
958    @GuardedBy("this")
959    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
960            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
961
962    public static class GrantUri {
963        public final int sourceUserId;
964        public final Uri uri;
965        public boolean prefix;
966
967        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
968            this.sourceUserId = sourceUserId;
969            this.uri = uri;
970            this.prefix = prefix;
971        }
972
973        @Override
974        public int hashCode() {
975            int hashCode = 1;
976            hashCode = 31 * hashCode + sourceUserId;
977            hashCode = 31 * hashCode + uri.hashCode();
978            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
979            return hashCode;
980        }
981
982        @Override
983        public boolean equals(Object o) {
984            if (o instanceof GrantUri) {
985                GrantUri other = (GrantUri) o;
986                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
987                        && prefix == other.prefix;
988            }
989            return false;
990        }
991
992        @Override
993        public String toString() {
994            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
995            if (prefix) result += " [prefix]";
996            return result;
997        }
998
999        public String toSafeString() {
1000            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1001            if (prefix) result += " [prefix]";
1002            return result;
1003        }
1004
1005        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1006            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1007                    ContentProvider.getUriWithoutUserId(uri), false);
1008        }
1009    }
1010
1011    CoreSettingsObserver mCoreSettingsObserver;
1012
1013    FontScaleSettingObserver mFontScaleSettingObserver;
1014
1015    private final class FontScaleSettingObserver extends ContentObserver {
1016        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1017
1018        public FontScaleSettingObserver() {
1019            super(mHandler);
1020            ContentResolver resolver = mContext.getContentResolver();
1021            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1022        }
1023
1024        @Override
1025        public void onChange(boolean selfChange, Uri uri) {
1026            if (mFontScaleUri.equals(uri)) {
1027                updateFontScaleIfNeeded();
1028            }
1029        }
1030    }
1031
1032    /**
1033     * Thread-local storage used to carry caller permissions over through
1034     * indirect content-provider access.
1035     */
1036    private class Identity {
1037        public final IBinder token;
1038        public final int pid;
1039        public final int uid;
1040
1041        Identity(IBinder _token, int _pid, int _uid) {
1042            token = _token;
1043            pid = _pid;
1044            uid = _uid;
1045        }
1046    }
1047
1048    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1049
1050    /**
1051     * All information we have collected about the runtime performance of
1052     * any user id that can impact battery performance.
1053     */
1054    final BatteryStatsService mBatteryStatsService;
1055
1056    /**
1057     * Information about component usage
1058     */
1059    UsageStatsManagerInternal mUsageStatsService;
1060
1061    /**
1062     * Access to DeviceIdleController service.
1063     */
1064    DeviceIdleController.LocalService mLocalDeviceIdleController;
1065
1066    /**
1067     * Information about and control over application operations
1068     */
1069    final AppOpsService mAppOpsService;
1070
1071    /**
1072     * Current configuration information.  HistoryRecord objects are given
1073     * a reference to this object to indicate which configuration they are
1074     * currently running in, so this object must be kept immutable.
1075     */
1076    Configuration mConfiguration = new Configuration();
1077
1078    /**
1079     * Current sequencing integer of the configuration, for skipping old
1080     * configurations.
1081     */
1082    int mConfigurationSeq = 0;
1083
1084    boolean mSuppressResizeConfigChanges = false;
1085
1086    /**
1087     * Hardware-reported OpenGLES version.
1088     */
1089    final int GL_ES_VERSION;
1090
1091    /**
1092     * List of initialization arguments to pass to all processes when binding applications to them.
1093     * For example, references to the commonly used services.
1094     */
1095    HashMap<String, IBinder> mAppBindArgs;
1096
1097    /**
1098     * Temporary to avoid allocations.  Protected by main lock.
1099     */
1100    final StringBuilder mStringBuilder = new StringBuilder(256);
1101
1102    /**
1103     * Used to control how we initialize the service.
1104     */
1105    ComponentName mTopComponent;
1106    String mTopAction = Intent.ACTION_MAIN;
1107    String mTopData;
1108
1109    volatile boolean mProcessesReady = false;
1110    volatile boolean mSystemReady = false;
1111    volatile boolean mOnBattery = false;
1112    volatile int mFactoryTest;
1113
1114    @GuardedBy("this") boolean mBooting = false;
1115    @GuardedBy("this") boolean mCallFinishBooting = false;
1116    @GuardedBy("this") boolean mBootAnimationComplete = false;
1117    @GuardedBy("this") boolean mLaunchWarningShown = false;
1118    @GuardedBy("this") boolean mCheckedForSetup = false;
1119
1120    Context mContext;
1121
1122    /**
1123     * The time at which we will allow normal application switches again,
1124     * after a call to {@link #stopAppSwitches()}.
1125     */
1126    long mAppSwitchesAllowedTime;
1127
1128    /**
1129     * This is set to true after the first switch after mAppSwitchesAllowedTime
1130     * is set; any switches after that will clear the time.
1131     */
1132    boolean mDidAppSwitch;
1133
1134    /**
1135     * Last time (in realtime) at which we checked for power usage.
1136     */
1137    long mLastPowerCheckRealtime;
1138
1139    /**
1140     * Last time (in uptime) at which we checked for power usage.
1141     */
1142    long mLastPowerCheckUptime;
1143
1144    /**
1145     * Set while we are wanting to sleep, to prevent any
1146     * activities from being started/resumed.
1147     */
1148    private boolean mSleeping = false;
1149
1150    /**
1151     * The process state used for processes that are running the top activities.
1152     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1153     */
1154    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1155
1156    /**
1157     * Set while we are running a voice interaction.  This overrides
1158     * sleeping while it is active.
1159     */
1160    private IVoiceInteractionSession mRunningVoice;
1161
1162    /**
1163     * For some direct access we need to power manager.
1164     */
1165    PowerManagerInternal mLocalPowerManager;
1166
1167    /**
1168     * We want to hold a wake lock while running a voice interaction session, since
1169     * this may happen with the screen off and we need to keep the CPU running to
1170     * be able to continue to interact with the user.
1171     */
1172    PowerManager.WakeLock mVoiceWakeLock;
1173
1174    /**
1175     * State of external calls telling us if the device is awake or asleep.
1176     */
1177    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1178
1179    /**
1180     * A list of tokens that cause the top activity to be put to sleep.
1181     * They are used by components that may hide and block interaction with underlying
1182     * activities.
1183     */
1184    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1185
1186    static final int LOCK_SCREEN_HIDDEN = 0;
1187    static final int LOCK_SCREEN_LEAVING = 1;
1188    static final int LOCK_SCREEN_SHOWN = 2;
1189    /**
1190     * State of external call telling us if the lock screen is shown.
1191     */
1192    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1193
1194    /**
1195     * Set if we are shutting down the system, similar to sleeping.
1196     */
1197    boolean mShuttingDown = false;
1198
1199    /**
1200     * Current sequence id for oom_adj computation traversal.
1201     */
1202    int mAdjSeq = 0;
1203
1204    /**
1205     * Current sequence id for process LRU updating.
1206     */
1207    int mLruSeq = 0;
1208
1209    /**
1210     * Keep track of the non-cached/empty process we last found, to help
1211     * determine how to distribute cached/empty processes next time.
1212     */
1213    int mNumNonCachedProcs = 0;
1214
1215    /**
1216     * Keep track of the number of cached hidden procs, to balance oom adj
1217     * distribution between those and empty procs.
1218     */
1219    int mNumCachedHiddenProcs = 0;
1220
1221    /**
1222     * Keep track of the number of service processes we last found, to
1223     * determine on the next iteration which should be B services.
1224     */
1225    int mNumServiceProcs = 0;
1226    int mNewNumAServiceProcs = 0;
1227    int mNewNumServiceProcs = 0;
1228
1229    /**
1230     * Allow the current computed overall memory level of the system to go down?
1231     * This is set to false when we are killing processes for reasons other than
1232     * memory management, so that the now smaller process list will not be taken as
1233     * an indication that memory is tighter.
1234     */
1235    boolean mAllowLowerMemLevel = false;
1236
1237    /**
1238     * The last computed memory level, for holding when we are in a state that
1239     * processes are going away for other reasons.
1240     */
1241    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1242
1243    /**
1244     * The last total number of process we have, to determine if changes actually look
1245     * like a shrinking number of process due to lower RAM.
1246     */
1247    int mLastNumProcesses;
1248
1249    /**
1250     * The uptime of the last time we performed idle maintenance.
1251     */
1252    long mLastIdleTime = SystemClock.uptimeMillis();
1253
1254    /**
1255     * Total time spent with RAM that has been added in the past since the last idle time.
1256     */
1257    long mLowRamTimeSinceLastIdle = 0;
1258
1259    /**
1260     * If RAM is currently low, when that horrible situation started.
1261     */
1262    long mLowRamStartTime = 0;
1263
1264    /**
1265     * For reporting to battery stats the current top application.
1266     */
1267    private String mCurResumedPackage = null;
1268    private int mCurResumedUid = -1;
1269
1270    /**
1271     * For reporting to battery stats the apps currently running foreground
1272     * service.  The ProcessMap is package/uid tuples; each of these contain
1273     * an array of the currently foreground processes.
1274     */
1275    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1276            = new ProcessMap<ArrayList<ProcessRecord>>();
1277
1278    /**
1279     * This is set if we had to do a delayed dexopt of an app before launching
1280     * it, to increase the ANR timeouts in that case.
1281     */
1282    boolean mDidDexOpt;
1283
1284    /**
1285     * Set if the systemServer made a call to enterSafeMode.
1286     */
1287    boolean mSafeMode;
1288
1289    /**
1290     * If true, we are running under a test environment so will sample PSS from processes
1291     * much more rapidly to try to collect better data when the tests are rapidly
1292     * running through apps.
1293     */
1294    boolean mTestPssMode = false;
1295
1296    String mDebugApp = null;
1297    boolean mWaitForDebugger = false;
1298    boolean mDebugTransient = false;
1299    String mOrigDebugApp = null;
1300    boolean mOrigWaitForDebugger = false;
1301    boolean mAlwaysFinishActivities = false;
1302    boolean mLenientBackgroundCheck = false;
1303    boolean mForceResizableActivities;
1304    boolean mSupportsMultiWindow;
1305    boolean mSupportsFreeformWindowManagement;
1306    boolean mSupportsPictureInPicture;
1307    Rect mDefaultPinnedStackBounds;
1308    IActivityController mController = null;
1309    boolean mControllerIsAMonkey = false;
1310    String mProfileApp = null;
1311    ProcessRecord mProfileProc = null;
1312    String mProfileFile;
1313    ParcelFileDescriptor mProfileFd;
1314    int mSamplingInterval = 0;
1315    boolean mAutoStopProfiler = false;
1316    int mProfileType = 0;
1317    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1318    String mMemWatchDumpProcName;
1319    String mMemWatchDumpFile;
1320    int mMemWatchDumpPid;
1321    int mMemWatchDumpUid;
1322    String mTrackAllocationApp = null;
1323    String mNativeDebuggingApp = null;
1324
1325    final long[] mTmpLong = new long[2];
1326
1327    static final class ProcessChangeItem {
1328        static final int CHANGE_ACTIVITIES = 1<<0;
1329        static final int CHANGE_PROCESS_STATE = 1<<1;
1330        int changes;
1331        int uid;
1332        int pid;
1333        int processState;
1334        boolean foregroundActivities;
1335    }
1336
1337    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1338    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1339
1340    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1341    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1342
1343    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1344    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1345
1346    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1347    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1348
1349    /**
1350     * Runtime CPU use collection thread.  This object's lock is used to
1351     * perform synchronization with the thread (notifying it to run).
1352     */
1353    final Thread mProcessCpuThread;
1354
1355    /**
1356     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1357     * Must acquire this object's lock when accessing it.
1358     * NOTE: this lock will be held while doing long operations (trawling
1359     * through all processes in /proc), so it should never be acquired by
1360     * any critical paths such as when holding the main activity manager lock.
1361     */
1362    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1363            MONITOR_THREAD_CPU_USAGE);
1364    final AtomicLong mLastCpuTime = new AtomicLong(0);
1365    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1366
1367    long mLastWriteTime = 0;
1368
1369    /**
1370     * Used to retain an update lock when the foreground activity is in
1371     * immersive mode.
1372     */
1373    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1374
1375    /**
1376     * Set to true after the system has finished booting.
1377     */
1378    boolean mBooted = false;
1379
1380    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1381    int mProcessLimitOverride = -1;
1382
1383    WindowManagerService mWindowManager;
1384    final ActivityThread mSystemThread;
1385
1386    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1387        final ProcessRecord mApp;
1388        final int mPid;
1389        final IApplicationThread mAppThread;
1390
1391        AppDeathRecipient(ProcessRecord app, int pid,
1392                IApplicationThread thread) {
1393            if (DEBUG_ALL) Slog.v(
1394                TAG, "New death recipient " + this
1395                + " for thread " + thread.asBinder());
1396            mApp = app;
1397            mPid = pid;
1398            mAppThread = thread;
1399        }
1400
1401        @Override
1402        public void binderDied() {
1403            if (DEBUG_ALL) Slog.v(
1404                TAG, "Death received in " + this
1405                + " for thread " + mAppThread.asBinder());
1406            synchronized(ActivityManagerService.this) {
1407                appDiedLocked(mApp, mPid, mAppThread, true);
1408            }
1409        }
1410    }
1411
1412    static final int SHOW_ERROR_UI_MSG = 1;
1413    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1414    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1415    static final int UPDATE_CONFIGURATION_MSG = 4;
1416    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1417    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1418    static final int SERVICE_TIMEOUT_MSG = 12;
1419    static final int UPDATE_TIME_ZONE = 13;
1420    static final int SHOW_UID_ERROR_UI_MSG = 14;
1421    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1422    static final int PROC_START_TIMEOUT_MSG = 20;
1423    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1424    static final int KILL_APPLICATION_MSG = 22;
1425    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1426    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1427    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1428    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1429    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1430    static final int CLEAR_DNS_CACHE_MSG = 28;
1431    static final int UPDATE_HTTP_PROXY_MSG = 29;
1432    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1433    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1434    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1435    static final int REPORT_MEM_USAGE_MSG = 33;
1436    static final int REPORT_USER_SWITCH_MSG = 34;
1437    static final int CONTINUE_USER_SWITCH_MSG = 35;
1438    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1439    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1440    static final int PERSIST_URI_GRANTS_MSG = 38;
1441    static final int REQUEST_ALL_PSS_MSG = 39;
1442    static final int START_PROFILES_MSG = 40;
1443    static final int UPDATE_TIME = 41;
1444    static final int SYSTEM_USER_START_MSG = 42;
1445    static final int SYSTEM_USER_CURRENT_MSG = 43;
1446    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1447    static final int FINISH_BOOTING_MSG = 45;
1448    static final int START_USER_SWITCH_UI_MSG = 46;
1449    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1450    static final int DISMISS_DIALOG_UI_MSG = 48;
1451    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1452    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1453    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1454    static final int DELETE_DUMPHEAP_MSG = 52;
1455    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1456    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1457    static final int REPORT_TIME_TRACKER_MSG = 55;
1458    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1459    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1460    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1461    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1462    static final int IDLE_UIDS_MSG = 60;
1463    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1464    static final int LOG_STACK_STATE = 62;
1465    static final int VR_MODE_CHANGE_MSG = 63;
1466    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1467    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1468    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1469    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1470    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1471    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1472
1473    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1474    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1475    static final int FIRST_COMPAT_MODE_MSG = 300;
1476    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1477
1478    static ServiceThread sKillThread = null;
1479    static KillHandler sKillHandler = null;
1480
1481    CompatModeDialog mCompatModeDialog;
1482    long mLastMemUsageReportTime = 0;
1483
1484    /**
1485     * Flag whether the current user is a "monkey", i.e. whether
1486     * the UI is driven by a UI automation tool.
1487     */
1488    private boolean mUserIsMonkey;
1489
1490    /** Flag whether the device has a Recents UI */
1491    boolean mHasRecents;
1492
1493    /** The dimensions of the thumbnails in the Recents UI. */
1494    int mThumbnailWidth;
1495    int mThumbnailHeight;
1496    float mFullscreenThumbnailScale;
1497
1498    final ServiceThread mHandlerThread;
1499    final MainHandler mHandler;
1500    final UiHandler mUiHandler;
1501
1502    PackageManagerInternal mPackageManagerInt;
1503
1504    final class KillHandler extends Handler {
1505        static final int KILL_PROCESS_GROUP_MSG = 4000;
1506
1507        public KillHandler(Looper looper) {
1508            super(looper, null, true);
1509        }
1510
1511        @Override
1512        public void handleMessage(Message msg) {
1513            switch (msg.what) {
1514                case KILL_PROCESS_GROUP_MSG:
1515                {
1516                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1517                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1518                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1519                }
1520                break;
1521
1522                default:
1523                    super.handleMessage(msg);
1524            }
1525        }
1526    }
1527
1528    final class UiHandler extends Handler {
1529        public UiHandler() {
1530            super(com.android.server.UiThread.get().getLooper(), null, true);
1531        }
1532
1533        @Override
1534        public void handleMessage(Message msg) {
1535            switch (msg.what) {
1536            case SHOW_ERROR_UI_MSG: {
1537                mAppErrors.handleShowAppErrorUi(msg);
1538                ensureBootCompleted();
1539            } break;
1540            case SHOW_NOT_RESPONDING_UI_MSG: {
1541                mAppErrors.handleShowAnrUi(msg);
1542                ensureBootCompleted();
1543            } break;
1544            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1545                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1546                synchronized (ActivityManagerService.this) {
1547                    ProcessRecord proc = (ProcessRecord) data.get("app");
1548                    if (proc == null) {
1549                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1550                        break;
1551                    }
1552                    if (proc.crashDialog != null) {
1553                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1554                        return;
1555                    }
1556                    AppErrorResult res = (AppErrorResult) data.get("result");
1557                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1558                        Dialog d = new StrictModeViolationDialog(mContext,
1559                                ActivityManagerService.this, res, proc);
1560                        d.show();
1561                        proc.crashDialog = d;
1562                    } else {
1563                        // The device is asleep, so just pretend that the user
1564                        // saw a crash dialog and hit "force quit".
1565                        res.set(0);
1566                    }
1567                }
1568                ensureBootCompleted();
1569            } break;
1570            case SHOW_FACTORY_ERROR_UI_MSG: {
1571                Dialog d = new FactoryErrorDialog(
1572                    mContext, msg.getData().getCharSequence("msg"));
1573                d.show();
1574                ensureBootCompleted();
1575            } break;
1576            case WAIT_FOR_DEBUGGER_UI_MSG: {
1577                synchronized (ActivityManagerService.this) {
1578                    ProcessRecord app = (ProcessRecord)msg.obj;
1579                    if (msg.arg1 != 0) {
1580                        if (!app.waitedForDebugger) {
1581                            Dialog d = new AppWaitingForDebuggerDialog(
1582                                    ActivityManagerService.this,
1583                                    mContext, app);
1584                            app.waitDialog = d;
1585                            app.waitedForDebugger = true;
1586                            d.show();
1587                        }
1588                    } else {
1589                        if (app.waitDialog != null) {
1590                            app.waitDialog.dismiss();
1591                            app.waitDialog = null;
1592                        }
1593                    }
1594                }
1595            } break;
1596            case SHOW_UID_ERROR_UI_MSG: {
1597                if (mShowDialogs) {
1598                    AlertDialog d = new BaseErrorDialog(mContext);
1599                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1600                    d.setCancelable(false);
1601                    d.setTitle(mContext.getText(R.string.android_system_label));
1602                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1603                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1604                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1605                    d.show();
1606                }
1607            } break;
1608            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1609                if (mShowDialogs) {
1610                    AlertDialog d = new BaseErrorDialog(mContext);
1611                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1612                    d.setCancelable(false);
1613                    d.setTitle(mContext.getText(R.string.android_system_label));
1614                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1615                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1616                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1617                    d.show();
1618                }
1619            } break;
1620            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1621                synchronized (ActivityManagerService.this) {
1622                    ActivityRecord ar = (ActivityRecord) msg.obj;
1623                    if (mCompatModeDialog != null) {
1624                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1625                                ar.info.applicationInfo.packageName)) {
1626                            return;
1627                        }
1628                        mCompatModeDialog.dismiss();
1629                        mCompatModeDialog = null;
1630                    }
1631                    if (ar != null && false) {
1632                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1633                                ar.packageName)) {
1634                            int mode = mCompatModePackages.computeCompatModeLocked(
1635                                    ar.info.applicationInfo);
1636                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1637                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1638                                mCompatModeDialog = new CompatModeDialog(
1639                                        ActivityManagerService.this, mContext,
1640                                        ar.info.applicationInfo);
1641                                mCompatModeDialog.show();
1642                            }
1643                        }
1644                    }
1645                }
1646                break;
1647            }
1648            case START_USER_SWITCH_UI_MSG: {
1649                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1650                break;
1651            }
1652            case DISMISS_DIALOG_UI_MSG: {
1653                final Dialog d = (Dialog) msg.obj;
1654                d.dismiss();
1655                break;
1656            }
1657            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1658                dispatchProcessesChanged();
1659                break;
1660            }
1661            case DISPATCH_PROCESS_DIED_UI_MSG: {
1662                final int pid = msg.arg1;
1663                final int uid = msg.arg2;
1664                dispatchProcessDied(pid, uid);
1665                break;
1666            }
1667            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1668                dispatchUidsChanged();
1669            } break;
1670            }
1671        }
1672    }
1673
1674    final class MainHandler extends Handler {
1675        public MainHandler(Looper looper) {
1676            super(looper, null, true);
1677        }
1678
1679        @Override
1680        public void handleMessage(Message msg) {
1681            switch (msg.what) {
1682            case UPDATE_CONFIGURATION_MSG: {
1683                final ContentResolver resolver = mContext.getContentResolver();
1684                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1685                        msg.arg1);
1686            } break;
1687            case GC_BACKGROUND_PROCESSES_MSG: {
1688                synchronized (ActivityManagerService.this) {
1689                    performAppGcsIfAppropriateLocked();
1690                }
1691            } break;
1692            case SERVICE_TIMEOUT_MSG: {
1693                if (mDidDexOpt) {
1694                    mDidDexOpt = false;
1695                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1696                    nmsg.obj = msg.obj;
1697                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1698                    return;
1699                }
1700                mServices.serviceTimeout((ProcessRecord)msg.obj);
1701            } break;
1702            case UPDATE_TIME_ZONE: {
1703                synchronized (ActivityManagerService.this) {
1704                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1705                        ProcessRecord r = mLruProcesses.get(i);
1706                        if (r.thread != null) {
1707                            try {
1708                                r.thread.updateTimeZone();
1709                            } catch (RemoteException ex) {
1710                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1711                            }
1712                        }
1713                    }
1714                }
1715            } break;
1716            case CLEAR_DNS_CACHE_MSG: {
1717                synchronized (ActivityManagerService.this) {
1718                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1719                        ProcessRecord r = mLruProcesses.get(i);
1720                        if (r.thread != null) {
1721                            try {
1722                                r.thread.clearDnsCache();
1723                            } catch (RemoteException ex) {
1724                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1725                            }
1726                        }
1727                    }
1728                }
1729            } break;
1730            case UPDATE_HTTP_PROXY_MSG: {
1731                ProxyInfo proxy = (ProxyInfo)msg.obj;
1732                String host = "";
1733                String port = "";
1734                String exclList = "";
1735                Uri pacFileUrl = Uri.EMPTY;
1736                if (proxy != null) {
1737                    host = proxy.getHost();
1738                    port = Integer.toString(proxy.getPort());
1739                    exclList = proxy.getExclusionListAsString();
1740                    pacFileUrl = proxy.getPacFileUrl();
1741                }
1742                synchronized (ActivityManagerService.this) {
1743                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1744                        ProcessRecord r = mLruProcesses.get(i);
1745                        if (r.thread != null) {
1746                            try {
1747                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1748                            } catch (RemoteException ex) {
1749                                Slog.w(TAG, "Failed to update http proxy for: " +
1750                                        r.info.processName);
1751                            }
1752                        }
1753                    }
1754                }
1755            } break;
1756            case PROC_START_TIMEOUT_MSG: {
1757                if (mDidDexOpt) {
1758                    mDidDexOpt = false;
1759                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1760                    nmsg.obj = msg.obj;
1761                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1762                    return;
1763                }
1764                ProcessRecord app = (ProcessRecord)msg.obj;
1765                synchronized (ActivityManagerService.this) {
1766                    processStartTimedOutLocked(app);
1767                }
1768            } break;
1769            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1770                ProcessRecord app = (ProcessRecord)msg.obj;
1771                synchronized (ActivityManagerService.this) {
1772                    processContentProviderPublishTimedOutLocked(app);
1773                }
1774            } break;
1775            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1776                synchronized (ActivityManagerService.this) {
1777                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1778                }
1779            } break;
1780            case KILL_APPLICATION_MSG: {
1781                synchronized (ActivityManagerService.this) {
1782                    int appid = msg.arg1;
1783                    boolean restart = (msg.arg2 == 1);
1784                    Bundle bundle = (Bundle)msg.obj;
1785                    String pkg = bundle.getString("pkg");
1786                    String reason = bundle.getString("reason");
1787                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1788                            false, UserHandle.USER_ALL, reason);
1789                }
1790            } break;
1791            case FINALIZE_PENDING_INTENT_MSG: {
1792                ((PendingIntentRecord)msg.obj).completeFinalize();
1793            } break;
1794            case POST_HEAVY_NOTIFICATION_MSG: {
1795                INotificationManager inm = NotificationManager.getService();
1796                if (inm == null) {
1797                    return;
1798                }
1799
1800                ActivityRecord root = (ActivityRecord)msg.obj;
1801                ProcessRecord process = root.app;
1802                if (process == null) {
1803                    return;
1804                }
1805
1806                try {
1807                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1808                    String text = mContext.getString(R.string.heavy_weight_notification,
1809                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1810                    Notification notification = new Notification.Builder(context)
1811                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1812                            .setWhen(0)
1813                            .setOngoing(true)
1814                            .setTicker(text)
1815                            .setColor(mContext.getColor(
1816                                    com.android.internal.R.color.system_notification_accent_color))
1817                            .setContentTitle(text)
1818                            .setContentText(
1819                                    mContext.getText(R.string.heavy_weight_notification_detail))
1820                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1821                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1822                                    new UserHandle(root.userId)))
1823                            .build();
1824                    try {
1825                        int[] outId = new int[1];
1826                        inm.enqueueNotificationWithTag("android", "android", null,
1827                                R.string.heavy_weight_notification,
1828                                notification, outId, root.userId);
1829                    } catch (RuntimeException e) {
1830                        Slog.w(ActivityManagerService.TAG,
1831                                "Error showing notification for heavy-weight app", e);
1832                    } catch (RemoteException e) {
1833                    }
1834                } catch (NameNotFoundException e) {
1835                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1836                }
1837            } break;
1838            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1839                INotificationManager inm = NotificationManager.getService();
1840                if (inm == null) {
1841                    return;
1842                }
1843                try {
1844                    inm.cancelNotificationWithTag("android", null,
1845                            R.string.heavy_weight_notification,  msg.arg1);
1846                } catch (RuntimeException e) {
1847                    Slog.w(ActivityManagerService.TAG,
1848                            "Error canceling notification for service", e);
1849                } catch (RemoteException e) {
1850                }
1851            } break;
1852            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1853                synchronized (ActivityManagerService.this) {
1854                    checkExcessivePowerUsageLocked(true);
1855                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1856                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1857                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1858                }
1859            } break;
1860            case REPORT_MEM_USAGE_MSG: {
1861                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1862                Thread thread = new Thread() {
1863                    @Override public void run() {
1864                        reportMemUsage(memInfos);
1865                    }
1866                };
1867                thread.start();
1868                break;
1869            }
1870            case REPORT_USER_SWITCH_MSG: {
1871                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1872                break;
1873            }
1874            case CONTINUE_USER_SWITCH_MSG: {
1875                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1876                break;
1877            }
1878            case USER_SWITCH_TIMEOUT_MSG: {
1879                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1880                break;
1881            }
1882            case IMMERSIVE_MODE_LOCK_MSG: {
1883                final boolean nextState = (msg.arg1 != 0);
1884                if (mUpdateLock.isHeld() != nextState) {
1885                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1886                            "Applying new update lock state '" + nextState
1887                            + "' for " + (ActivityRecord)msg.obj);
1888                    if (nextState) {
1889                        mUpdateLock.acquire();
1890                    } else {
1891                        mUpdateLock.release();
1892                    }
1893                }
1894                break;
1895            }
1896            case PERSIST_URI_GRANTS_MSG: {
1897                writeGrantedUriPermissions();
1898                break;
1899            }
1900            case REQUEST_ALL_PSS_MSG: {
1901                synchronized (ActivityManagerService.this) {
1902                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1903                }
1904                break;
1905            }
1906            case START_PROFILES_MSG: {
1907                synchronized (ActivityManagerService.this) {
1908                    mUserController.startProfilesLocked();
1909                }
1910                break;
1911            }
1912            case UPDATE_TIME: {
1913                synchronized (ActivityManagerService.this) {
1914                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1915                        ProcessRecord r = mLruProcesses.get(i);
1916                        if (r.thread != null) {
1917                            try {
1918                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1919                            } catch (RemoteException ex) {
1920                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1921                            }
1922                        }
1923                    }
1924                }
1925                break;
1926            }
1927            case SYSTEM_USER_START_MSG: {
1928                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1929                        Integer.toString(msg.arg1), msg.arg1);
1930                mSystemServiceManager.startUser(msg.arg1);
1931                break;
1932            }
1933            case SYSTEM_USER_UNLOCK_MSG: {
1934                final int userId = msg.arg1;
1935                mSystemServiceManager.unlockUser(userId);
1936                synchronized (ActivityManagerService.this) {
1937                    mRecentTasks.loadUserRecentsLocked(userId);
1938                }
1939                if (userId == UserHandle.USER_SYSTEM) {
1940                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1941                }
1942                installEncryptionUnawareProviders(userId);
1943                break;
1944            }
1945            case SYSTEM_USER_CURRENT_MSG: {
1946                mBatteryStatsService.noteEvent(
1947                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1948                        Integer.toString(msg.arg2), msg.arg2);
1949                mBatteryStatsService.noteEvent(
1950                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1951                        Integer.toString(msg.arg1), msg.arg1);
1952                mSystemServiceManager.switchUser(msg.arg1);
1953                break;
1954            }
1955            case ENTER_ANIMATION_COMPLETE_MSG: {
1956                synchronized (ActivityManagerService.this) {
1957                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1958                    if (r != null && r.app != null && r.app.thread != null) {
1959                        try {
1960                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1961                        } catch (RemoteException e) {
1962                        }
1963                    }
1964                }
1965                break;
1966            }
1967            case FINISH_BOOTING_MSG: {
1968                if (msg.arg1 != 0) {
1969                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1970                    finishBooting();
1971                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1972                }
1973                if (msg.arg2 != 0) {
1974                    enableScreenAfterBoot();
1975                }
1976                break;
1977            }
1978            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1979                try {
1980                    Locale l = (Locale) msg.obj;
1981                    IBinder service = ServiceManager.getService("mount");
1982                    IMountService mountService = IMountService.Stub.asInterface(service);
1983                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1984                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1985                } catch (RemoteException e) {
1986                    Log.e(TAG, "Error storing locale for decryption UI", e);
1987                }
1988                break;
1989            }
1990            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1991                synchronized (ActivityManagerService.this) {
1992                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1993                        try {
1994                            // Make a one-way callback to the listener
1995                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1996                        } catch (RemoteException e){
1997                            // Handled by the RemoteCallbackList
1998                        }
1999                    }
2000                    mTaskStackListeners.finishBroadcast();
2001                }
2002                break;
2003            }
2004            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2005                synchronized (ActivityManagerService.this) {
2006                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2007                        try {
2008                            // Make a one-way callback to the listener
2009                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2010                        } catch (RemoteException e){
2011                            // Handled by the RemoteCallbackList
2012                        }
2013                    }
2014                    mTaskStackListeners.finishBroadcast();
2015                }
2016                break;
2017            }
2018            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2019                synchronized (ActivityManagerService.this) {
2020                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2021                        try {
2022                            // Make a one-way callback to the listener
2023                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2024                        } catch (RemoteException e){
2025                            // Handled by the RemoteCallbackList
2026                        }
2027                    }
2028                    mTaskStackListeners.finishBroadcast();
2029                }
2030                break;
2031            }
2032            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2033                synchronized (ActivityManagerService.this) {
2034                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2035                        try {
2036                            // Make a one-way callback to the listener
2037                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2038                        } catch (RemoteException e){
2039                            // Handled by the RemoteCallbackList
2040                        }
2041                    }
2042                    mTaskStackListeners.finishBroadcast();
2043                }
2044                break;
2045            }
2046            case NOTIFY_FORCED_RESIZABLE_MSG: {
2047                synchronized (ActivityManagerService.this) {
2048                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2049                        try {
2050                            // Make a one-way callback to the listener
2051                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2052                                    (String) msg.obj, msg.arg1);
2053                        } catch (RemoteException e){
2054                            // Handled by the RemoteCallbackList
2055                        }
2056                    }
2057                    mTaskStackListeners.finishBroadcast();
2058                }
2059                break;
2060            }
2061                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2062                    synchronized (ActivityManagerService.this) {
2063                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2064                            try {
2065                                // Make a one-way callback to the listener
2066                                mTaskStackListeners.getBroadcastItem(i)
2067                                        .onActivityDismissingDockedStack();
2068                            } catch (RemoteException e){
2069                                // Handled by the RemoteCallbackList
2070                            }
2071                        }
2072                        mTaskStackListeners.finishBroadcast();
2073                    }
2074                    break;
2075                }
2076            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2077                final int uid = msg.arg1;
2078                final byte[] firstPacket = (byte[]) msg.obj;
2079
2080                synchronized (mPidsSelfLocked) {
2081                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2082                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2083                        if (p.uid == uid) {
2084                            try {
2085                                p.thread.notifyCleartextNetwork(firstPacket);
2086                            } catch (RemoteException ignored) {
2087                            }
2088                        }
2089                    }
2090                }
2091                break;
2092            }
2093            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2094                final String procName;
2095                final int uid;
2096                final long memLimit;
2097                final String reportPackage;
2098                synchronized (ActivityManagerService.this) {
2099                    procName = mMemWatchDumpProcName;
2100                    uid = mMemWatchDumpUid;
2101                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2102                    if (val == null) {
2103                        val = mMemWatchProcesses.get(procName, 0);
2104                    }
2105                    if (val != null) {
2106                        memLimit = val.first;
2107                        reportPackage = val.second;
2108                    } else {
2109                        memLimit = 0;
2110                        reportPackage = null;
2111                    }
2112                }
2113                if (procName == null) {
2114                    return;
2115                }
2116
2117                if (DEBUG_PSS) Slog.d(TAG_PSS,
2118                        "Showing dump heap notification from " + procName + "/" + uid);
2119
2120                INotificationManager inm = NotificationManager.getService();
2121                if (inm == null) {
2122                    return;
2123                }
2124
2125                String text = mContext.getString(R.string.dump_heap_notification, procName);
2126
2127
2128                Intent deleteIntent = new Intent();
2129                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2130                Intent intent = new Intent();
2131                intent.setClassName("android", DumpHeapActivity.class.getName());
2132                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2133                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2134                if (reportPackage != null) {
2135                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2136                }
2137                int userId = UserHandle.getUserId(uid);
2138                Notification notification = new Notification.Builder(mContext)
2139                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2140                        .setWhen(0)
2141                        .setOngoing(true)
2142                        .setAutoCancel(true)
2143                        .setTicker(text)
2144                        .setColor(mContext.getColor(
2145                                com.android.internal.R.color.system_notification_accent_color))
2146                        .setContentTitle(text)
2147                        .setContentText(
2148                                mContext.getText(R.string.dump_heap_notification_detail))
2149                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2150                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2151                                new UserHandle(userId)))
2152                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2153                                deleteIntent, 0, UserHandle.SYSTEM))
2154                        .build();
2155
2156                try {
2157                    int[] outId = new int[1];
2158                    inm.enqueueNotificationWithTag("android", "android", null,
2159                            R.string.dump_heap_notification,
2160                            notification, outId, userId);
2161                } catch (RuntimeException e) {
2162                    Slog.w(ActivityManagerService.TAG,
2163                            "Error showing notification for dump heap", e);
2164                } catch (RemoteException e) {
2165                }
2166            } break;
2167            case DELETE_DUMPHEAP_MSG: {
2168                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2169                        DumpHeapActivity.JAVA_URI,
2170                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2171                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2172                        UserHandle.myUserId());
2173                synchronized (ActivityManagerService.this) {
2174                    mMemWatchDumpFile = null;
2175                    mMemWatchDumpProcName = null;
2176                    mMemWatchDumpPid = -1;
2177                    mMemWatchDumpUid = -1;
2178                }
2179            } break;
2180            case FOREGROUND_PROFILE_CHANGED_MSG: {
2181                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2182            } break;
2183            case REPORT_TIME_TRACKER_MSG: {
2184                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2185                tracker.deliverResult(mContext);
2186            } break;
2187            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2188                mUserController.dispatchUserSwitchComplete(msg.arg1);
2189            } break;
2190            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2191                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2192                try {
2193                    connection.shutdown();
2194                } catch (RemoteException e) {
2195                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2196                }
2197                // Only a UiAutomation can set this flag and now that
2198                // it is finished we make sure it is reset to its default.
2199                mUserIsMonkey = false;
2200            } break;
2201            case APP_BOOST_DEACTIVATE_MSG: {
2202                synchronized(ActivityManagerService.this) {
2203                    if (mIsBoosted) {
2204                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2205                            nativeMigrateFromBoost();
2206                            mIsBoosted = false;
2207                            mBoostStartTime = 0;
2208                        } else {
2209                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2210                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2211                        }
2212                    }
2213                }
2214            } break;
2215            case IDLE_UIDS_MSG: {
2216                idleUids();
2217            } break;
2218            case LOG_STACK_STATE: {
2219                synchronized (ActivityManagerService.this) {
2220                    mStackSupervisor.logStackState();
2221                }
2222            } break;
2223            case VR_MODE_CHANGE_MSG: {
2224                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2225                final ActivityRecord r = (ActivityRecord) msg.obj;
2226                boolean vrMode;
2227                ComponentName requestedPackage;
2228                ComponentName callingPackage;
2229                int userId;
2230                synchronized (ActivityManagerService.this) {
2231                    vrMode = r.requestedVrComponent != null;
2232                    requestedPackage = r.requestedVrComponent;
2233                    userId = r.userId;
2234                    callingPackage = r.info.getComponentName();
2235                    if (mInVrMode != vrMode) {
2236                        mInVrMode = vrMode;
2237                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2238                    }
2239                }
2240                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2241            } break;
2242            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2243                final ActivityRecord r = (ActivityRecord) msg.obj;
2244                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2245                if (needsVrMode) {
2246                    VrManagerInternal vrService =
2247                            LocalServices.getService(VrManagerInternal.class);
2248                    boolean enable = msg.arg1 == 1;
2249                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2250                            r.info.getComponentName());
2251                }
2252            } break;
2253            }
2254        }
2255    };
2256
2257    static final int COLLECT_PSS_BG_MSG = 1;
2258
2259    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2260        @Override
2261        public void handleMessage(Message msg) {
2262            switch (msg.what) {
2263            case COLLECT_PSS_BG_MSG: {
2264                long start = SystemClock.uptimeMillis();
2265                MemInfoReader memInfo = null;
2266                synchronized (ActivityManagerService.this) {
2267                    if (mFullPssPending) {
2268                        mFullPssPending = false;
2269                        memInfo = new MemInfoReader();
2270                    }
2271                }
2272                if (memInfo != null) {
2273                    updateCpuStatsNow();
2274                    long nativeTotalPss = 0;
2275                    synchronized (mProcessCpuTracker) {
2276                        final int N = mProcessCpuTracker.countStats();
2277                        for (int j=0; j<N; j++) {
2278                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2279                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2280                                // This is definitely an application process; skip it.
2281                                continue;
2282                            }
2283                            synchronized (mPidsSelfLocked) {
2284                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2285                                    // This is one of our own processes; skip it.
2286                                    continue;
2287                                }
2288                            }
2289                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2290                        }
2291                    }
2292                    memInfo.readMemInfo();
2293                    synchronized (ActivityManagerService.this) {
2294                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2295                                + (SystemClock.uptimeMillis()-start) + "ms");
2296                        final long cachedKb = memInfo.getCachedSizeKb();
2297                        final long freeKb = memInfo.getFreeSizeKb();
2298                        final long zramKb = memInfo.getZramTotalSizeKb();
2299                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2300                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2301                                kernelKb*1024, nativeTotalPss*1024);
2302                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2303                                nativeTotalPss);
2304                    }
2305                }
2306
2307                int num = 0;
2308                long[] tmp = new long[2];
2309                do {
2310                    ProcessRecord proc;
2311                    int procState;
2312                    int pid;
2313                    long lastPssTime;
2314                    synchronized (ActivityManagerService.this) {
2315                        if (mPendingPssProcesses.size() <= 0) {
2316                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2317                                    "Collected PSS of " + num + " processes in "
2318                                    + (SystemClock.uptimeMillis() - start) + "ms");
2319                            mPendingPssProcesses.clear();
2320                            return;
2321                        }
2322                        proc = mPendingPssProcesses.remove(0);
2323                        procState = proc.pssProcState;
2324                        lastPssTime = proc.lastPssTime;
2325                        if (proc.thread != null && procState == proc.setProcState
2326                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2327                                        < SystemClock.uptimeMillis()) {
2328                            pid = proc.pid;
2329                        } else {
2330                            proc = null;
2331                            pid = 0;
2332                        }
2333                    }
2334                    if (proc != null) {
2335                        long pss = Debug.getPss(pid, tmp, null);
2336                        synchronized (ActivityManagerService.this) {
2337                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2338                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2339                                num++;
2340                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2341                                        SystemClock.uptimeMillis());
2342                            }
2343                        }
2344                    }
2345                } while (true);
2346            }
2347            }
2348        }
2349    };
2350
2351    public void setSystemProcess() {
2352        try {
2353            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2354            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2355            ServiceManager.addService("meminfo", new MemBinder(this));
2356            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2357            ServiceManager.addService("dbinfo", new DbBinder(this));
2358            if (MONITOR_CPU_USAGE) {
2359                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2360            }
2361            ServiceManager.addService("permission", new PermissionController(this));
2362            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2363
2364            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2365                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2366            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2367
2368            synchronized (this) {
2369                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2370                app.persistent = true;
2371                app.pid = MY_PID;
2372                app.maxAdj = ProcessList.SYSTEM_ADJ;
2373                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2374                synchronized (mPidsSelfLocked) {
2375                    mPidsSelfLocked.put(app.pid, app);
2376                }
2377                updateLruProcessLocked(app, false, null);
2378                updateOomAdjLocked();
2379            }
2380        } catch (PackageManager.NameNotFoundException e) {
2381            throw new RuntimeException(
2382                    "Unable to find android system package", e);
2383        }
2384    }
2385
2386    public void setWindowManager(WindowManagerService wm) {
2387        mWindowManager = wm;
2388        mStackSupervisor.setWindowManager(wm);
2389        mActivityStarter.setWindowManager(wm);
2390    }
2391
2392    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2393        mUsageStatsService = usageStatsManager;
2394    }
2395
2396    public void startObservingNativeCrashes() {
2397        final NativeCrashListener ncl = new NativeCrashListener(this);
2398        ncl.start();
2399    }
2400
2401    public IAppOpsService getAppOpsService() {
2402        return mAppOpsService;
2403    }
2404
2405    static class MemBinder extends Binder {
2406        ActivityManagerService mActivityManagerService;
2407        MemBinder(ActivityManagerService activityManagerService) {
2408            mActivityManagerService = activityManagerService;
2409        }
2410
2411        @Override
2412        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2413            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2414                    != PackageManager.PERMISSION_GRANTED) {
2415                pw.println("Permission Denial: can't dump meminfo from from pid="
2416                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2417                        + " without permission " + android.Manifest.permission.DUMP);
2418                return;
2419            }
2420
2421            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2422        }
2423    }
2424
2425    static class GraphicsBinder extends Binder {
2426        ActivityManagerService mActivityManagerService;
2427        GraphicsBinder(ActivityManagerService activityManagerService) {
2428            mActivityManagerService = activityManagerService;
2429        }
2430
2431        @Override
2432        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2433            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2434                    != PackageManager.PERMISSION_GRANTED) {
2435                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2436                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2437                        + " without permission " + android.Manifest.permission.DUMP);
2438                return;
2439            }
2440
2441            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2442        }
2443    }
2444
2445    static class DbBinder extends Binder {
2446        ActivityManagerService mActivityManagerService;
2447        DbBinder(ActivityManagerService activityManagerService) {
2448            mActivityManagerService = activityManagerService;
2449        }
2450
2451        @Override
2452        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2453            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2454                    != PackageManager.PERMISSION_GRANTED) {
2455                pw.println("Permission Denial: can't dump dbinfo from from pid="
2456                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2457                        + " without permission " + android.Manifest.permission.DUMP);
2458                return;
2459            }
2460
2461            mActivityManagerService.dumpDbInfo(fd, pw, args);
2462        }
2463    }
2464
2465    static class CpuBinder extends Binder {
2466        ActivityManagerService mActivityManagerService;
2467        CpuBinder(ActivityManagerService activityManagerService) {
2468            mActivityManagerService = activityManagerService;
2469        }
2470
2471        @Override
2472        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2473            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2474                    != PackageManager.PERMISSION_GRANTED) {
2475                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2476                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2477                        + " without permission " + android.Manifest.permission.DUMP);
2478                return;
2479            }
2480
2481            synchronized (mActivityManagerService.mProcessCpuTracker) {
2482                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2483                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2484                        SystemClock.uptimeMillis()));
2485            }
2486        }
2487    }
2488
2489    public static final class Lifecycle extends SystemService {
2490        private final ActivityManagerService mService;
2491
2492        public Lifecycle(Context context) {
2493            super(context);
2494            mService = new ActivityManagerService(context);
2495        }
2496
2497        @Override
2498        public void onStart() {
2499            mService.start();
2500        }
2501
2502        public ActivityManagerService getService() {
2503            return mService;
2504        }
2505    }
2506
2507    // Note: This method is invoked on the main thread but may need to attach various
2508    // handlers to other threads.  So take care to be explicit about the looper.
2509    public ActivityManagerService(Context systemContext) {
2510        mContext = systemContext;
2511        mFactoryTest = FactoryTest.getMode();
2512        mSystemThread = ActivityThread.currentActivityThread();
2513
2514        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2515
2516        mHandlerThread = new ServiceThread(TAG,
2517                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2518        mHandlerThread.start();
2519        mHandler = new MainHandler(mHandlerThread.getLooper());
2520        mUiHandler = new UiHandler();
2521
2522        /* static; one-time init here */
2523        if (sKillHandler == null) {
2524            sKillThread = new ServiceThread(TAG + ":kill",
2525                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2526            sKillThread.start();
2527            sKillHandler = new KillHandler(sKillThread.getLooper());
2528        }
2529
2530        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2531                "foreground", BROADCAST_FG_TIMEOUT, false);
2532        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2533                "background", BROADCAST_BG_TIMEOUT, true);
2534        mBroadcastQueues[0] = mFgBroadcastQueue;
2535        mBroadcastQueues[1] = mBgBroadcastQueue;
2536
2537        mServices = new ActiveServices(this);
2538        mProviderMap = new ProviderMap(this);
2539        mAppErrors = new AppErrors(mContext, this);
2540
2541        // TODO: Move creation of battery stats service outside of activity manager service.
2542        File dataDir = Environment.getDataDirectory();
2543        File systemDir = new File(dataDir, "system");
2544        systemDir.mkdirs();
2545        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2546        mBatteryStatsService.getActiveStatistics().readLocked();
2547        mBatteryStatsService.scheduleWriteToDisk();
2548        mOnBattery = DEBUG_POWER ? true
2549                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2550        mBatteryStatsService.getActiveStatistics().setCallback(this);
2551
2552        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2553
2554        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2555        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2556                new IAppOpsCallback.Stub() {
2557                    @Override public void opChanged(int op, int uid, String packageName) {
2558                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2559                            if (mAppOpsService.checkOperation(op, uid, packageName)
2560                                    != AppOpsManager.MODE_ALLOWED) {
2561                                runInBackgroundDisabled(uid);
2562                            }
2563                        }
2564                    }
2565                });
2566
2567        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2568
2569        mUserController = new UserController(this);
2570
2571        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2572            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2573
2574        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2575
2576        mConfiguration.setToDefaults();
2577        mConfiguration.setLocales(LocaleList.getDefault());
2578
2579        mConfigurationSeq = mConfiguration.seq = 1;
2580        mProcessCpuTracker.init();
2581
2582        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2583        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2584        mStackSupervisor = new ActivityStackSupervisor(this);
2585        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2586        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2587
2588        mProcessCpuThread = new Thread("CpuTracker") {
2589            @Override
2590            public void run() {
2591                while (true) {
2592                    try {
2593                        try {
2594                            synchronized(this) {
2595                                final long now = SystemClock.uptimeMillis();
2596                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2597                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2598                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2599                                //        + ", write delay=" + nextWriteDelay);
2600                                if (nextWriteDelay < nextCpuDelay) {
2601                                    nextCpuDelay = nextWriteDelay;
2602                                }
2603                                if (nextCpuDelay > 0) {
2604                                    mProcessCpuMutexFree.set(true);
2605                                    this.wait(nextCpuDelay);
2606                                }
2607                            }
2608                        } catch (InterruptedException e) {
2609                        }
2610                        updateCpuStatsNow();
2611                    } catch (Exception e) {
2612                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2613                    }
2614                }
2615            }
2616        };
2617
2618        Watchdog.getInstance().addMonitor(this);
2619        Watchdog.getInstance().addThread(mHandler);
2620    }
2621
2622    public void setSystemServiceManager(SystemServiceManager mgr) {
2623        mSystemServiceManager = mgr;
2624    }
2625
2626    public void setInstaller(Installer installer) {
2627        mInstaller = installer;
2628    }
2629
2630    private void start() {
2631        Process.removeAllProcessGroups();
2632        mProcessCpuThread.start();
2633
2634        mBatteryStatsService.publish(mContext);
2635        mAppOpsService.publish(mContext);
2636        Slog.d("AppOps", "AppOpsService published");
2637        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2638    }
2639
2640    void onUserStoppedLocked(int userId) {
2641        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2642    }
2643
2644    public void initPowerManagement() {
2645        mStackSupervisor.initPowerManagement();
2646        mBatteryStatsService.initPowerManagement();
2647        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2648        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2649        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2650        mVoiceWakeLock.setReferenceCounted(false);
2651    }
2652
2653    @Override
2654    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2655            throws RemoteException {
2656        if (code == SYSPROPS_TRANSACTION) {
2657            // We need to tell all apps about the system property change.
2658            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2659            synchronized(this) {
2660                final int NP = mProcessNames.getMap().size();
2661                for (int ip=0; ip<NP; ip++) {
2662                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2663                    final int NA = apps.size();
2664                    for (int ia=0; ia<NA; ia++) {
2665                        ProcessRecord app = apps.valueAt(ia);
2666                        if (app.thread != null) {
2667                            procs.add(app.thread.asBinder());
2668                        }
2669                    }
2670                }
2671            }
2672
2673            int N = procs.size();
2674            for (int i=0; i<N; i++) {
2675                Parcel data2 = Parcel.obtain();
2676                try {
2677                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2678                } catch (RemoteException e) {
2679                }
2680                data2.recycle();
2681            }
2682        }
2683        try {
2684            return super.onTransact(code, data, reply, flags);
2685        } catch (RuntimeException e) {
2686            // The activity manager only throws security exceptions, so let's
2687            // log all others.
2688            if (!(e instanceof SecurityException)) {
2689                Slog.wtf(TAG, "Activity Manager Crash", e);
2690            }
2691            throw e;
2692        }
2693    }
2694
2695    void updateCpuStats() {
2696        final long now = SystemClock.uptimeMillis();
2697        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2698            return;
2699        }
2700        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2701            synchronized (mProcessCpuThread) {
2702                mProcessCpuThread.notify();
2703            }
2704        }
2705    }
2706
2707    void updateCpuStatsNow() {
2708        synchronized (mProcessCpuTracker) {
2709            mProcessCpuMutexFree.set(false);
2710            final long now = SystemClock.uptimeMillis();
2711            boolean haveNewCpuStats = false;
2712
2713            if (MONITOR_CPU_USAGE &&
2714                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2715                mLastCpuTime.set(now);
2716                mProcessCpuTracker.update();
2717                if (mProcessCpuTracker.hasGoodLastStats()) {
2718                    haveNewCpuStats = true;
2719                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2720                    //Slog.i(TAG, "Total CPU usage: "
2721                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2722
2723                    // Slog the cpu usage if the property is set.
2724                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2725                        int user = mProcessCpuTracker.getLastUserTime();
2726                        int system = mProcessCpuTracker.getLastSystemTime();
2727                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2728                        int irq = mProcessCpuTracker.getLastIrqTime();
2729                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2730                        int idle = mProcessCpuTracker.getLastIdleTime();
2731
2732                        int total = user + system + iowait + irq + softIrq + idle;
2733                        if (total == 0) total = 1;
2734
2735                        EventLog.writeEvent(EventLogTags.CPU,
2736                                ((user+system+iowait+irq+softIrq) * 100) / total,
2737                                (user * 100) / total,
2738                                (system * 100) / total,
2739                                (iowait * 100) / total,
2740                                (irq * 100) / total,
2741                                (softIrq * 100) / total);
2742                    }
2743                }
2744            }
2745
2746            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2747            synchronized(bstats) {
2748                synchronized(mPidsSelfLocked) {
2749                    if (haveNewCpuStats) {
2750                        if (bstats.startAddingCpuLocked()) {
2751                            int totalUTime = 0;
2752                            int totalSTime = 0;
2753                            final int N = mProcessCpuTracker.countStats();
2754                            for (int i=0; i<N; i++) {
2755                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2756                                if (!st.working) {
2757                                    continue;
2758                                }
2759                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2760                                totalUTime += st.rel_utime;
2761                                totalSTime += st.rel_stime;
2762                                if (pr != null) {
2763                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2764                                    if (ps == null || !ps.isActive()) {
2765                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2766                                                pr.info.uid, pr.processName);
2767                                    }
2768                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2769                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2770                                } else {
2771                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2772                                    if (ps == null || !ps.isActive()) {
2773                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2774                                                bstats.mapUid(st.uid), st.name);
2775                                    }
2776                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2777                                }
2778                            }
2779                            final int userTime = mProcessCpuTracker.getLastUserTime();
2780                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2781                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2782                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2783                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2784                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2785                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2786                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2787                        }
2788                    }
2789                }
2790
2791                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2792                    mLastWriteTime = now;
2793                    mBatteryStatsService.scheduleWriteToDisk();
2794                }
2795            }
2796        }
2797    }
2798
2799    @Override
2800    public void batteryNeedsCpuUpdate() {
2801        updateCpuStatsNow();
2802    }
2803
2804    @Override
2805    public void batteryPowerChanged(boolean onBattery) {
2806        // When plugging in, update the CPU stats first before changing
2807        // the plug state.
2808        updateCpuStatsNow();
2809        synchronized (this) {
2810            synchronized(mPidsSelfLocked) {
2811                mOnBattery = DEBUG_POWER ? true : onBattery;
2812            }
2813        }
2814    }
2815
2816    @Override
2817    public void batterySendBroadcast(Intent intent) {
2818        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2819                AppOpsManager.OP_NONE, null, false, false,
2820                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2821    }
2822
2823    /**
2824     * Initialize the application bind args. These are passed to each
2825     * process when the bindApplication() IPC is sent to the process. They're
2826     * lazily setup to make sure the services are running when they're asked for.
2827     */
2828    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2829        if (mAppBindArgs == null) {
2830            mAppBindArgs = new HashMap<>();
2831
2832            // Isolated processes won't get this optimization, so that we don't
2833            // violate the rules about which services they have access to.
2834            if (!isolated) {
2835                // Setup the application init args
2836                mAppBindArgs.put("package", ServiceManager.getService("package"));
2837                mAppBindArgs.put("window", ServiceManager.getService("window"));
2838                mAppBindArgs.put(Context.ALARM_SERVICE,
2839                        ServiceManager.getService(Context.ALARM_SERVICE));
2840            }
2841        }
2842        return mAppBindArgs;
2843    }
2844
2845    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2846        if (r == null || mFocusedActivity == r) {
2847            return false;
2848        }
2849
2850        if (!r.isFocusable()) {
2851            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2852            return false;
2853        }
2854
2855        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2856
2857        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2858        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2859                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2860        mDoingSetFocusedActivity = true;
2861
2862        final ActivityRecord last = mFocusedActivity;
2863        mFocusedActivity = r;
2864        if (r.task.isApplicationTask()) {
2865            if (mCurAppTimeTracker != r.appTimeTracker) {
2866                // We are switching app tracking.  Complete the current one.
2867                if (mCurAppTimeTracker != null) {
2868                    mCurAppTimeTracker.stop();
2869                    mHandler.obtainMessage(
2870                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2871                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2872                    mCurAppTimeTracker = null;
2873                }
2874                if (r.appTimeTracker != null) {
2875                    mCurAppTimeTracker = r.appTimeTracker;
2876                    startTimeTrackingFocusedActivityLocked();
2877                }
2878            } else {
2879                startTimeTrackingFocusedActivityLocked();
2880            }
2881        } else {
2882            r.appTimeTracker = null;
2883        }
2884        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2885        // TODO: Probably not, because we don't want to resume voice on switching
2886        // back to this activity
2887        if (r.task.voiceInteractor != null) {
2888            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2889        } else {
2890            finishRunningVoiceLocked();
2891            IVoiceInteractionSession session;
2892            if (last != null && ((session = last.task.voiceSession) != null
2893                    || (session = last.voiceSession) != null)) {
2894                // We had been in a voice interaction session, but now focused has
2895                // move to something different.  Just finish the session, we can't
2896                // return to it and retain the proper state and synchronization with
2897                // the voice interaction service.
2898                finishVoiceTask(session);
2899            }
2900        }
2901        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2902            mWindowManager.setFocusedApp(r.appToken, true);
2903        }
2904        applyUpdateLockStateLocked(r);
2905        applyUpdateVrModeLocked(r);
2906        if (mFocusedActivity.userId != mLastFocusedUserId) {
2907            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2908            mHandler.obtainMessage(
2909                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2910            mLastFocusedUserId = mFocusedActivity.userId;
2911        }
2912
2913        // Log a warning if the focused app is changed during the process. This could
2914        // indicate a problem of the focus setting logic!
2915        if (mFocusedActivity != r) Slog.w(TAG,
2916                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2917        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2918
2919        EventLogTags.writeAmFocusedActivity(
2920                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2921                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2922                reason);
2923        return true;
2924    }
2925
2926    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2927        if (mFocusedActivity != goingAway) {
2928            return;
2929        }
2930
2931        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2932        if (focusedStack != null) {
2933            final ActivityRecord top = focusedStack.topActivity();
2934            if (top != null && top.userId != mLastFocusedUserId) {
2935                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2936                mHandler.sendMessage(
2937                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2938                mLastFocusedUserId = top.userId;
2939            }
2940        }
2941
2942        // Try to move focus to another activity if possible.
2943        if (setFocusedActivityLocked(
2944                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2945            return;
2946        }
2947
2948        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2949                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2950        mFocusedActivity = null;
2951        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2952    }
2953
2954    @Override
2955    public void setFocusedStack(int stackId) {
2956        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2957        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2958        final long callingId = Binder.clearCallingIdentity();
2959        try {
2960            synchronized (this) {
2961                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2962                if (stack == null) {
2963                    return;
2964                }
2965                final ActivityRecord r = stack.topRunningActivityLocked();
2966                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2967                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2968                }
2969            }
2970        } finally {
2971            Binder.restoreCallingIdentity(callingId);
2972        }
2973    }
2974
2975    @Override
2976    public void setFocusedTask(int taskId) {
2977        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2978        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2979        final long callingId = Binder.clearCallingIdentity();
2980        try {
2981            synchronized (this) {
2982                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2983                if (task == null) {
2984                    return;
2985                }
2986                final ActivityRecord r = task.topRunningActivityLocked();
2987                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2988                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2989                }
2990            }
2991        } finally {
2992            Binder.restoreCallingIdentity(callingId);
2993        }
2994    }
2995
2996    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2997    @Override
2998    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2999        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3000        synchronized (this) {
3001            if (listener != null) {
3002                mTaskStackListeners.register(listener);
3003            }
3004        }
3005    }
3006
3007    @Override
3008    public void notifyActivityDrawn(IBinder token) {
3009        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3010        synchronized (this) {
3011            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3012            if (r != null) {
3013                r.task.stack.notifyActivityDrawnLocked(r);
3014            }
3015        }
3016    }
3017
3018    final void applyUpdateLockStateLocked(ActivityRecord r) {
3019        // Modifications to the UpdateLock state are done on our handler, outside
3020        // the activity manager's locks.  The new state is determined based on the
3021        // state *now* of the relevant activity record.  The object is passed to
3022        // the handler solely for logging detail, not to be consulted/modified.
3023        final boolean nextState = r != null && r.immersive;
3024        mHandler.sendMessage(
3025                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3026    }
3027
3028    final void applyUpdateVrModeLocked(ActivityRecord r) {
3029        mHandler.sendMessage(
3030                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3031    }
3032
3033    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3034        mHandler.sendMessage(
3035                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3036    }
3037
3038    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3039        Message msg = Message.obtain();
3040        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3041        msg.obj = r.task.askedCompatMode ? null : r;
3042        mUiHandler.sendMessage(msg);
3043    }
3044
3045    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3046            String what, Object obj, ProcessRecord srcApp) {
3047        app.lastActivityTime = now;
3048
3049        if (app.activities.size() > 0) {
3050            // Don't want to touch dependent processes that are hosting activities.
3051            return index;
3052        }
3053
3054        int lrui = mLruProcesses.lastIndexOf(app);
3055        if (lrui < 0) {
3056            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3057                    + what + " " + obj + " from " + srcApp);
3058            return index;
3059        }
3060
3061        if (lrui >= index) {
3062            // Don't want to cause this to move dependent processes *back* in the
3063            // list as if they were less frequently used.
3064            return index;
3065        }
3066
3067        if (lrui >= mLruProcessActivityStart) {
3068            // Don't want to touch dependent processes that are hosting activities.
3069            return index;
3070        }
3071
3072        mLruProcesses.remove(lrui);
3073        if (index > 0) {
3074            index--;
3075        }
3076        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3077                + " in LRU list: " + app);
3078        mLruProcesses.add(index, app);
3079        return index;
3080    }
3081
3082    static void killProcessGroup(int uid, int pid) {
3083        if (sKillHandler != null) {
3084            sKillHandler.sendMessage(
3085                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3086        } else {
3087            Slog.w(TAG, "Asked to kill process group before system bringup!");
3088            Process.killProcessGroup(uid, pid);
3089        }
3090    }
3091
3092    final void removeLruProcessLocked(ProcessRecord app) {
3093        int lrui = mLruProcesses.lastIndexOf(app);
3094        if (lrui >= 0) {
3095            if (!app.killed) {
3096                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3097                Process.killProcessQuiet(app.pid);
3098                killProcessGroup(app.uid, app.pid);
3099            }
3100            if (lrui <= mLruProcessActivityStart) {
3101                mLruProcessActivityStart--;
3102            }
3103            if (lrui <= mLruProcessServiceStart) {
3104                mLruProcessServiceStart--;
3105            }
3106            mLruProcesses.remove(lrui);
3107        }
3108    }
3109
3110    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3111            ProcessRecord client) {
3112        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3113                || app.treatLikeActivity;
3114        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3115        if (!activityChange && hasActivity) {
3116            // The process has activities, so we are only allowing activity-based adjustments
3117            // to move it.  It should be kept in the front of the list with other
3118            // processes that have activities, and we don't want those to change their
3119            // order except due to activity operations.
3120            return;
3121        }
3122
3123        mLruSeq++;
3124        final long now = SystemClock.uptimeMillis();
3125        app.lastActivityTime = now;
3126
3127        // First a quick reject: if the app is already at the position we will
3128        // put it, then there is nothing to do.
3129        if (hasActivity) {
3130            final int N = mLruProcesses.size();
3131            if (N > 0 && mLruProcesses.get(N-1) == app) {
3132                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3133                return;
3134            }
3135        } else {
3136            if (mLruProcessServiceStart > 0
3137                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3138                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3139                return;
3140            }
3141        }
3142
3143        int lrui = mLruProcesses.lastIndexOf(app);
3144
3145        if (app.persistent && lrui >= 0) {
3146            // We don't care about the position of persistent processes, as long as
3147            // they are in the list.
3148            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3149            return;
3150        }
3151
3152        /* In progress: compute new position first, so we can avoid doing work
3153           if the process is not actually going to move.  Not yet working.
3154        int addIndex;
3155        int nextIndex;
3156        boolean inActivity = false, inService = false;
3157        if (hasActivity) {
3158            // Process has activities, put it at the very tipsy-top.
3159            addIndex = mLruProcesses.size();
3160            nextIndex = mLruProcessServiceStart;
3161            inActivity = true;
3162        } else if (hasService) {
3163            // Process has services, put it at the top of the service list.
3164            addIndex = mLruProcessActivityStart;
3165            nextIndex = mLruProcessServiceStart;
3166            inActivity = true;
3167            inService = true;
3168        } else  {
3169            // Process not otherwise of interest, it goes to the top of the non-service area.
3170            addIndex = mLruProcessServiceStart;
3171            if (client != null) {
3172                int clientIndex = mLruProcesses.lastIndexOf(client);
3173                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3174                        + app);
3175                if (clientIndex >= 0 && addIndex > clientIndex) {
3176                    addIndex = clientIndex;
3177                }
3178            }
3179            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3180        }
3181
3182        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3183                + mLruProcessActivityStart + "): " + app);
3184        */
3185
3186        if (lrui >= 0) {
3187            if (lrui < mLruProcessActivityStart) {
3188                mLruProcessActivityStart--;
3189            }
3190            if (lrui < mLruProcessServiceStart) {
3191                mLruProcessServiceStart--;
3192            }
3193            /*
3194            if (addIndex > lrui) {
3195                addIndex--;
3196            }
3197            if (nextIndex > lrui) {
3198                nextIndex--;
3199            }
3200            */
3201            mLruProcesses.remove(lrui);
3202        }
3203
3204        /*
3205        mLruProcesses.add(addIndex, app);
3206        if (inActivity) {
3207            mLruProcessActivityStart++;
3208        }
3209        if (inService) {
3210            mLruProcessActivityStart++;
3211        }
3212        */
3213
3214        int nextIndex;
3215        if (hasActivity) {
3216            final int N = mLruProcesses.size();
3217            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3218                // Process doesn't have activities, but has clients with
3219                // activities...  move it up, but one below the top (the top
3220                // should always have a real activity).
3221                if (DEBUG_LRU) Slog.d(TAG_LRU,
3222                        "Adding to second-top of LRU activity list: " + app);
3223                mLruProcesses.add(N - 1, app);
3224                // To keep it from spamming the LRU list (by making a bunch of clients),
3225                // we will push down any other entries owned by the app.
3226                final int uid = app.info.uid;
3227                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3228                    ProcessRecord subProc = mLruProcesses.get(i);
3229                    if (subProc.info.uid == uid) {
3230                        // We want to push this one down the list.  If the process after
3231                        // it is for the same uid, however, don't do so, because we don't
3232                        // want them internally to be re-ordered.
3233                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3234                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3235                                    "Pushing uid " + uid + " swapping at " + i + ": "
3236                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3237                            ProcessRecord tmp = mLruProcesses.get(i);
3238                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3239                            mLruProcesses.set(i - 1, tmp);
3240                            i--;
3241                        }
3242                    } else {
3243                        // A gap, we can stop here.
3244                        break;
3245                    }
3246                }
3247            } else {
3248                // Process has activities, put it at the very tipsy-top.
3249                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3250                mLruProcesses.add(app);
3251            }
3252            nextIndex = mLruProcessServiceStart;
3253        } else if (hasService) {
3254            // Process has services, put it at the top of the service list.
3255            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3256            mLruProcesses.add(mLruProcessActivityStart, app);
3257            nextIndex = mLruProcessServiceStart;
3258            mLruProcessActivityStart++;
3259        } else  {
3260            // Process not otherwise of interest, it goes to the top of the non-service area.
3261            int index = mLruProcessServiceStart;
3262            if (client != null) {
3263                // If there is a client, don't allow the process to be moved up higher
3264                // in the list than that client.
3265                int clientIndex = mLruProcesses.lastIndexOf(client);
3266                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3267                        + " when updating " + app);
3268                if (clientIndex <= lrui) {
3269                    // Don't allow the client index restriction to push it down farther in the
3270                    // list than it already is.
3271                    clientIndex = lrui;
3272                }
3273                if (clientIndex >= 0 && index > clientIndex) {
3274                    index = clientIndex;
3275                }
3276            }
3277            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3278            mLruProcesses.add(index, app);
3279            nextIndex = index-1;
3280            mLruProcessActivityStart++;
3281            mLruProcessServiceStart++;
3282        }
3283
3284        // If the app is currently using a content provider or service,
3285        // bump those processes as well.
3286        for (int j=app.connections.size()-1; j>=0; j--) {
3287            ConnectionRecord cr = app.connections.valueAt(j);
3288            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3289                    && cr.binding.service.app != null
3290                    && cr.binding.service.app.lruSeq != mLruSeq
3291                    && !cr.binding.service.app.persistent) {
3292                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3293                        "service connection", cr, app);
3294            }
3295        }
3296        for (int j=app.conProviders.size()-1; j>=0; j--) {
3297            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3298            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3299                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3300                        "provider reference", cpr, app);
3301            }
3302        }
3303    }
3304
3305    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3306        if (uid == Process.SYSTEM_UID) {
3307            // The system gets to run in any process.  If there are multiple
3308            // processes with the same uid, just pick the first (this
3309            // should never happen).
3310            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3311            if (procs == null) return null;
3312            final int procCount = procs.size();
3313            for (int i = 0; i < procCount; i++) {
3314                final int procUid = procs.keyAt(i);
3315                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3316                    // Don't use an app process or different user process for system component.
3317                    continue;
3318                }
3319                return procs.valueAt(i);
3320            }
3321        }
3322        ProcessRecord proc = mProcessNames.get(processName, uid);
3323        if (false && proc != null && !keepIfLarge
3324                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3325                && proc.lastCachedPss >= 4000) {
3326            // Turn this condition on to cause killing to happen regularly, for testing.
3327            if (proc.baseProcessTracker != null) {
3328                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3329            }
3330            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3331        } else if (proc != null && !keepIfLarge
3332                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3333                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3334            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3335            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3336                if (proc.baseProcessTracker != null) {
3337                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3338                }
3339                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3340            }
3341        }
3342        return proc;
3343    }
3344
3345    void notifyPackageUse(String packageName) {
3346        IPackageManager pm = AppGlobals.getPackageManager();
3347        try {
3348            pm.notifyPackageUse(packageName);
3349        } catch (RemoteException e) {
3350        }
3351    }
3352
3353    boolean isNextTransitionForward() {
3354        int transit = mWindowManager.getPendingAppTransition();
3355        return transit == TRANSIT_ACTIVITY_OPEN
3356                || transit == TRANSIT_TASK_OPEN
3357                || transit == TRANSIT_TASK_TO_FRONT;
3358    }
3359
3360    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3361            String processName, String abiOverride, int uid, Runnable crashHandler) {
3362        synchronized(this) {
3363            ApplicationInfo info = new ApplicationInfo();
3364            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3365            // For isolated processes, the former contains the parent's uid and the latter the
3366            // actual uid of the isolated process.
3367            // In the special case introduced by this method (which is, starting an isolated
3368            // process directly from the SystemServer without an actual parent app process) the
3369            // closest thing to a parent's uid is SYSTEM_UID.
3370            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3371            // the |isolated| logic in the ProcessRecord constructor.
3372            info.uid = Process.SYSTEM_UID;
3373            info.processName = processName;
3374            info.className = entryPoint;
3375            info.packageName = "android";
3376            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3377                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3378                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3379                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3380                    crashHandler);
3381            return proc != null ? proc.pid : 0;
3382        }
3383    }
3384
3385    final ProcessRecord startProcessLocked(String processName,
3386            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3387            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3388            boolean isolated, boolean keepIfLarge) {
3389        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3390                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3391                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3392                null /* crashHandler */);
3393    }
3394
3395    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3396            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3397            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3398            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3399        long startTime = SystemClock.elapsedRealtime();
3400        ProcessRecord app;
3401        if (!isolated) {
3402            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3403            checkTime(startTime, "startProcess: after getProcessRecord");
3404
3405            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3406                // If we are in the background, then check to see if this process
3407                // is bad.  If so, we will just silently fail.
3408                if (mAppErrors.isBadProcessLocked(info)) {
3409                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3410                            + "/" + info.processName);
3411                    return null;
3412                }
3413            } else {
3414                // When the user is explicitly starting a process, then clear its
3415                // crash count so that we won't make it bad until they see at
3416                // least one crash dialog again, and make the process good again
3417                // if it had been bad.
3418                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3419                        + "/" + info.processName);
3420                mAppErrors.resetProcessCrashTimeLocked(info);
3421                if (mAppErrors.isBadProcessLocked(info)) {
3422                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3423                            UserHandle.getUserId(info.uid), info.uid,
3424                            info.processName);
3425                    mAppErrors.clearBadProcessLocked(info);
3426                    if (app != null) {
3427                        app.bad = false;
3428                    }
3429                }
3430            }
3431        } else {
3432            // If this is an isolated process, it can't re-use an existing process.
3433            app = null;
3434        }
3435
3436        // app launch boost for big.little configurations
3437        // use cpusets to migrate freshly launched tasks to big cores
3438        synchronized(ActivityManagerService.this) {
3439            nativeMigrateToBoost();
3440            mIsBoosted = true;
3441            mBoostStartTime = SystemClock.uptimeMillis();
3442            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3443            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3444        }
3445
3446        // We don't have to do anything more if:
3447        // (1) There is an existing application record; and
3448        // (2) The caller doesn't think it is dead, OR there is no thread
3449        //     object attached to it so we know it couldn't have crashed; and
3450        // (3) There is a pid assigned to it, so it is either starting or
3451        //     already running.
3452        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3453                + " app=" + app + " knownToBeDead=" + knownToBeDead
3454                + " thread=" + (app != null ? app.thread : null)
3455                + " pid=" + (app != null ? app.pid : -1));
3456        if (app != null && app.pid > 0) {
3457            if (!knownToBeDead || app.thread == null) {
3458                // We already have the app running, or are waiting for it to
3459                // come up (we have a pid but not yet its thread), so keep it.
3460                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3461                // If this is a new package in the process, add the package to the list
3462                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3463                checkTime(startTime, "startProcess: done, added package to proc");
3464                return app;
3465            }
3466
3467            // An application record is attached to a previous process,
3468            // clean it up now.
3469            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3470            checkTime(startTime, "startProcess: bad proc running, killing");
3471            killProcessGroup(app.uid, app.pid);
3472            handleAppDiedLocked(app, true, true);
3473            checkTime(startTime, "startProcess: done killing old proc");
3474        }
3475
3476        String hostingNameStr = hostingName != null
3477                ? hostingName.flattenToShortString() : null;
3478
3479        if (app == null) {
3480            checkTime(startTime, "startProcess: creating new process record");
3481            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3482            if (app == null) {
3483                Slog.w(TAG, "Failed making new process record for "
3484                        + processName + "/" + info.uid + " isolated=" + isolated);
3485                return null;
3486            }
3487            app.crashHandler = crashHandler;
3488            checkTime(startTime, "startProcess: done creating new process record");
3489        } else {
3490            // If this is a new package in the process, add the package to the list
3491            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3492            checkTime(startTime, "startProcess: added package to existing proc");
3493        }
3494
3495        // If the system is not ready yet, then hold off on starting this
3496        // process until it is.
3497        if (!mProcessesReady
3498                && !isAllowedWhileBooting(info)
3499                && !allowWhileBooting) {
3500            if (!mProcessesOnHold.contains(app)) {
3501                mProcessesOnHold.add(app);
3502            }
3503            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3504                    "System not ready, putting on hold: " + app);
3505            checkTime(startTime, "startProcess: returning with proc on hold");
3506            return app;
3507        }
3508
3509        checkTime(startTime, "startProcess: stepping in to startProcess");
3510        startProcessLocked(
3511                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3512        checkTime(startTime, "startProcess: done starting proc!");
3513        return (app.pid != 0) ? app : null;
3514    }
3515
3516    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3517        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3518    }
3519
3520    private final void startProcessLocked(ProcessRecord app,
3521            String hostingType, String hostingNameStr) {
3522        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3523                null /* entryPoint */, null /* entryPointArgs */);
3524    }
3525
3526    private final void startProcessLocked(ProcessRecord app, String hostingType,
3527            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3528        long startTime = SystemClock.elapsedRealtime();
3529        if (app.pid > 0 && app.pid != MY_PID) {
3530            checkTime(startTime, "startProcess: removing from pids map");
3531            synchronized (mPidsSelfLocked) {
3532                mPidsSelfLocked.remove(app.pid);
3533                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3534            }
3535            checkTime(startTime, "startProcess: done removing from pids map");
3536            app.setPid(0);
3537        }
3538
3539        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3540                "startProcessLocked removing on hold: " + app);
3541        mProcessesOnHold.remove(app);
3542
3543        checkTime(startTime, "startProcess: starting to update cpu stats");
3544        updateCpuStats();
3545        checkTime(startTime, "startProcess: done updating cpu stats");
3546
3547        try {
3548            try {
3549                final int userId = UserHandle.getUserId(app.uid);
3550                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3551            } catch (RemoteException e) {
3552                throw e.rethrowAsRuntimeException();
3553            }
3554
3555            int uid = app.uid;
3556            int[] gids = null;
3557            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3558            if (!app.isolated) {
3559                int[] permGids = null;
3560                try {
3561                    checkTime(startTime, "startProcess: getting gids from package manager");
3562                    final IPackageManager pm = AppGlobals.getPackageManager();
3563                    permGids = pm.getPackageGids(app.info.packageName,
3564                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3565                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3566                            MountServiceInternal.class);
3567                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3568                            app.info.packageName);
3569                } catch (RemoteException e) {
3570                    throw e.rethrowAsRuntimeException();
3571                }
3572
3573                /*
3574                 * Add shared application and profile GIDs so applications can share some
3575                 * resources like shared libraries and access user-wide resources
3576                 */
3577                if (ArrayUtils.isEmpty(permGids)) {
3578                    gids = new int[2];
3579                } else {
3580                    gids = new int[permGids.length + 2];
3581                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3582                }
3583                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3584                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3585            }
3586            checkTime(startTime, "startProcess: building args");
3587            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3588                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3589                        && mTopComponent != null
3590                        && app.processName.equals(mTopComponent.getPackageName())) {
3591                    uid = 0;
3592                }
3593                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3594                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3595                    uid = 0;
3596                }
3597            }
3598            int debugFlags = 0;
3599            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3600                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3601                // Also turn on CheckJNI for debuggable apps. It's quite
3602                // awkward to turn on otherwise.
3603                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3604            }
3605            // Run the app in safe mode if its manifest requests so or the
3606            // system is booted in safe mode.
3607            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3608                mSafeMode == true) {
3609                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3610            }
3611            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3612                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3613            }
3614            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3615            if ("true".equals(genDebugInfoProperty)) {
3616                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3617            }
3618            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3619                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3620            }
3621            if ("1".equals(SystemProperties.get("debug.assert"))) {
3622                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3623            }
3624            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3625                // Enable all debug flags required by the native debugger.
3626                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3627                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3628                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3629                mNativeDebuggingApp = null;
3630            }
3631
3632            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3633            if (requiredAbi == null) {
3634                requiredAbi = Build.SUPPORTED_ABIS[0];
3635            }
3636
3637            String instructionSet = null;
3638            if (app.info.primaryCpuAbi != null) {
3639                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3640            }
3641
3642            app.gids = gids;
3643            app.requiredAbi = requiredAbi;
3644            app.instructionSet = instructionSet;
3645
3646            // Start the process.  It will either succeed and return a result containing
3647            // the PID of the new process, or else throw a RuntimeException.
3648            boolean isActivityProcess = (entryPoint == null);
3649            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3650            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3651                    app.processName);
3652            checkTime(startTime, "startProcess: asking zygote to start proc");
3653            Process.ProcessStartResult startResult = Process.start(entryPoint,
3654                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3655                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3656                    app.info.dataDir, entryPointArgs);
3657            checkTime(startTime, "startProcess: returned from zygote!");
3658            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3659
3660            if (app.isolated) {
3661                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3662            }
3663            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3664            checkTime(startTime, "startProcess: done updating battery stats");
3665
3666            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3667                    UserHandle.getUserId(uid), startResult.pid, uid,
3668                    app.processName, hostingType,
3669                    hostingNameStr != null ? hostingNameStr : "");
3670
3671            try {
3672                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3673                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3674            } catch (RemoteException ex) {
3675                // Ignore
3676            }
3677
3678            if (app.persistent) {
3679                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3680            }
3681
3682            if (DEBUG_PROCESSES) {
3683                checkTime(startTime, "startProcess: building log message");
3684                StringBuilder buf = mStringBuilder;
3685                buf.setLength(0);
3686                buf.append("Start proc ");
3687                buf.append(startResult.pid);
3688                buf.append(':');
3689                buf.append(app.processName);
3690                buf.append('/');
3691                UserHandle.formatUid(buf, uid);
3692                if (!isActivityProcess) {
3693                    buf.append(" [");
3694                    buf.append(entryPoint);
3695                    buf.append("]");
3696                }
3697                buf.append(" for ");
3698                buf.append(hostingType);
3699                if (hostingNameStr != null) {
3700                    buf.append(" ");
3701                    buf.append(hostingNameStr);
3702                }
3703                Slog.i(TAG, buf.toString());
3704            }
3705            app.setPid(startResult.pid);
3706            app.usingWrapper = startResult.usingWrapper;
3707            app.removed = false;
3708            app.killed = false;
3709            app.killedByAm = false;
3710            checkTime(startTime, "startProcess: starting to update pids map");
3711            synchronized (mPidsSelfLocked) {
3712                this.mPidsSelfLocked.put(startResult.pid, app);
3713                if (isActivityProcess) {
3714                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3715                    msg.obj = app;
3716                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3717                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3718                }
3719            }
3720            checkTime(startTime, "startProcess: done updating pids map");
3721        } catch (RuntimeException e) {
3722            // XXX do better error recovery.
3723            app.setPid(0);
3724            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3725            if (app.isolated) {
3726                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3727            }
3728            Slog.e(TAG, "Failure starting process " + app.processName, e);
3729        }
3730    }
3731
3732    void updateUsageStats(ActivityRecord component, boolean resumed) {
3733        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3734                "updateUsageStats: comp=" + component + "res=" + resumed);
3735        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3736        if (resumed) {
3737            if (mUsageStatsService != null) {
3738                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3739                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3740            }
3741            synchronized (stats) {
3742                stats.noteActivityResumedLocked(component.app.uid);
3743            }
3744        } else {
3745            if (mUsageStatsService != null) {
3746                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3747                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3748            }
3749            synchronized (stats) {
3750                stats.noteActivityPausedLocked(component.app.uid);
3751            }
3752        }
3753    }
3754
3755    Intent getHomeIntent() {
3756        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3757        intent.setComponent(mTopComponent);
3758        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3759        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3760            intent.addCategory(Intent.CATEGORY_HOME);
3761        }
3762        return intent;
3763    }
3764
3765    boolean startHomeActivityLocked(int userId, String reason) {
3766        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3767                && mTopAction == null) {
3768            // We are running in factory test mode, but unable to find
3769            // the factory test app, so just sit around displaying the
3770            // error message and don't try to start anything.
3771            return false;
3772        }
3773        Intent intent = getHomeIntent();
3774        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3775        if (aInfo != null) {
3776            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3777            // Don't do this if the home app is currently being
3778            // instrumented.
3779            aInfo = new ActivityInfo(aInfo);
3780            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3781            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3782                    aInfo.applicationInfo.uid, true);
3783            if (app == null || app.instrumentationClass == null) {
3784                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3785                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3786            }
3787        }
3788
3789        return true;
3790    }
3791
3792    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3793        ActivityInfo ai = null;
3794        ComponentName comp = intent.getComponent();
3795        try {
3796            if (comp != null) {
3797                // Factory test.
3798                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3799            } else {
3800                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3801                        intent,
3802                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3803                        flags, userId);
3804
3805                if (info != null) {
3806                    ai = info.activityInfo;
3807                }
3808            }
3809        } catch (RemoteException e) {
3810            // ignore
3811        }
3812
3813        return ai;
3814    }
3815
3816    /**
3817     * Starts the "new version setup screen" if appropriate.
3818     */
3819    void startSetupActivityLocked() {
3820        // Only do this once per boot.
3821        if (mCheckedForSetup) {
3822            return;
3823        }
3824
3825        // We will show this screen if the current one is a different
3826        // version than the last one shown, and we are not running in
3827        // low-level factory test mode.
3828        final ContentResolver resolver = mContext.getContentResolver();
3829        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3830                Settings.Global.getInt(resolver,
3831                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3832            mCheckedForSetup = true;
3833
3834            // See if we should be showing the platform update setup UI.
3835            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3836            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3837                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3838            if (!ris.isEmpty()) {
3839                final ResolveInfo ri = ris.get(0);
3840                String vers = ri.activityInfo.metaData != null
3841                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3842                        : null;
3843                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3844                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3845                            Intent.METADATA_SETUP_VERSION);
3846                }
3847                String lastVers = Settings.Secure.getString(
3848                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3849                if (vers != null && !vers.equals(lastVers)) {
3850                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3851                    intent.setComponent(new ComponentName(
3852                            ri.activityInfo.packageName, ri.activityInfo.name));
3853                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3854                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3855                            null, 0, 0, 0, null, false, false, null, null, null);
3856                }
3857            }
3858        }
3859    }
3860
3861    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3862        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3863    }
3864
3865    void enforceNotIsolatedCaller(String caller) {
3866        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3867            throw new SecurityException("Isolated process not allowed to call " + caller);
3868        }
3869    }
3870
3871    void enforceShellRestriction(String restriction, int userHandle) {
3872        if (Binder.getCallingUid() == Process.SHELL_UID) {
3873            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3874                throw new SecurityException("Shell does not have permission to access user "
3875                        + userHandle);
3876            }
3877        }
3878    }
3879
3880    @Override
3881    public int getFrontActivityScreenCompatMode() {
3882        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3883        synchronized (this) {
3884            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3885        }
3886    }
3887
3888    @Override
3889    public void setFrontActivityScreenCompatMode(int mode) {
3890        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3891                "setFrontActivityScreenCompatMode");
3892        synchronized (this) {
3893            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3894        }
3895    }
3896
3897    @Override
3898    public int getPackageScreenCompatMode(String packageName) {
3899        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3900        synchronized (this) {
3901            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3902        }
3903    }
3904
3905    @Override
3906    public void setPackageScreenCompatMode(String packageName, int mode) {
3907        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3908                "setPackageScreenCompatMode");
3909        synchronized (this) {
3910            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3911        }
3912    }
3913
3914    @Override
3915    public boolean getPackageAskScreenCompat(String packageName) {
3916        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3917        synchronized (this) {
3918            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3919        }
3920    }
3921
3922    @Override
3923    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3924        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3925                "setPackageAskScreenCompat");
3926        synchronized (this) {
3927            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3928        }
3929    }
3930
3931    private boolean hasUsageStatsPermission(String callingPackage) {
3932        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3933                Binder.getCallingUid(), callingPackage);
3934        if (mode == AppOpsManager.MODE_DEFAULT) {
3935            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3936                    == PackageManager.PERMISSION_GRANTED;
3937        }
3938        return mode == AppOpsManager.MODE_ALLOWED;
3939    }
3940
3941    @Override
3942    public int getPackageProcessState(String packageName, String callingPackage) {
3943        if (!hasUsageStatsPermission(callingPackage)) {
3944            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3945                    "getPackageProcessState");
3946        }
3947
3948        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3949        synchronized (this) {
3950            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3951                final ProcessRecord proc = mLruProcesses.get(i);
3952                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3953                        || procState > proc.setProcState) {
3954                    boolean found = false;
3955                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3956                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3957                            procState = proc.setProcState;
3958                            found = true;
3959                        }
3960                    }
3961                    if (proc.pkgDeps != null && !found) {
3962                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3963                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3964                                procState = proc.setProcState;
3965                                break;
3966                            }
3967                        }
3968                    }
3969                }
3970            }
3971        }
3972        return procState;
3973    }
3974
3975    @Override
3976    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3977        synchronized (this) {
3978            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3979            if (app == null) {
3980                return false;
3981            }
3982            if (app.trimMemoryLevel < level && app.thread != null &&
3983                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3984                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3985                try {
3986                    app.thread.scheduleTrimMemory(level);
3987                    app.trimMemoryLevel = level;
3988                    return true;
3989                } catch (RemoteException e) {
3990                    // Fallthrough to failure case.
3991                }
3992            }
3993        }
3994        return false;
3995    }
3996
3997    private void dispatchProcessesChanged() {
3998        int N;
3999        synchronized (this) {
4000            N = mPendingProcessChanges.size();
4001            if (mActiveProcessChanges.length < N) {
4002                mActiveProcessChanges = new ProcessChangeItem[N];
4003            }
4004            mPendingProcessChanges.toArray(mActiveProcessChanges);
4005            mPendingProcessChanges.clear();
4006            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4007                    "*** Delivering " + N + " process changes");
4008        }
4009
4010        int i = mProcessObservers.beginBroadcast();
4011        while (i > 0) {
4012            i--;
4013            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4014            if (observer != null) {
4015                try {
4016                    for (int j=0; j<N; j++) {
4017                        ProcessChangeItem item = mActiveProcessChanges[j];
4018                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4019                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4020                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4021                                    + item.uid + ": " + item.foregroundActivities);
4022                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4023                                    item.foregroundActivities);
4024                        }
4025                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4026                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4027                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4028                                    + ": " + item.processState);
4029                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4030                        }
4031                    }
4032                } catch (RemoteException e) {
4033                }
4034            }
4035        }
4036        mProcessObservers.finishBroadcast();
4037
4038        synchronized (this) {
4039            for (int j=0; j<N; j++) {
4040                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4041            }
4042        }
4043    }
4044
4045    private void dispatchProcessDied(int pid, int uid) {
4046        int i = mProcessObservers.beginBroadcast();
4047        while (i > 0) {
4048            i--;
4049            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4050            if (observer != null) {
4051                try {
4052                    observer.onProcessDied(pid, uid);
4053                } catch (RemoteException e) {
4054                }
4055            }
4056        }
4057        mProcessObservers.finishBroadcast();
4058    }
4059
4060    private void dispatchUidsChanged() {
4061        int N;
4062        synchronized (this) {
4063            N = mPendingUidChanges.size();
4064            if (mActiveUidChanges.length < N) {
4065                mActiveUidChanges = new UidRecord.ChangeItem[N];
4066            }
4067            for (int i=0; i<N; i++) {
4068                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4069                mActiveUidChanges[i] = change;
4070                if (change.uidRecord != null) {
4071                    change.uidRecord.pendingChange = null;
4072                    change.uidRecord = null;
4073                }
4074            }
4075            mPendingUidChanges.clear();
4076            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4077                    "*** Delivering " + N + " uid changes");
4078        }
4079
4080        if (mLocalPowerManager != null) {
4081            for (int j=0; j<N; j++) {
4082                UidRecord.ChangeItem item = mActiveUidChanges[j];
4083                if (item.change == UidRecord.CHANGE_GONE
4084                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4085                    mLocalPowerManager.uidGone(item.uid);
4086                } else {
4087                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4088                }
4089            }
4090        }
4091
4092        int i = mUidObservers.beginBroadcast();
4093        while (i > 0) {
4094            i--;
4095            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4096            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4097            if (observer != null) {
4098                try {
4099                    for (int j=0; j<N; j++) {
4100                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4101                        final int change = item.change;
4102                        UidRecord validateUid = null;
4103                        if (VALIDATE_UID_STATES && i == 0) {
4104                            validateUid = mValidateUids.get(item.uid);
4105                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4106                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4107                                validateUid = new UidRecord(item.uid);
4108                                mValidateUids.put(item.uid, validateUid);
4109                            }
4110                        }
4111                        if (change == UidRecord.CHANGE_IDLE
4112                                || change == UidRecord.CHANGE_GONE_IDLE) {
4113                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4114                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4115                                        "UID idle uid=" + item.uid);
4116                                observer.onUidIdle(item.uid);
4117                            }
4118                            if (VALIDATE_UID_STATES && i == 0) {
4119                                if (validateUid != null) {
4120                                    validateUid.idle = true;
4121                                }
4122                            }
4123                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4124                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4125                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4126                                        "UID active uid=" + item.uid);
4127                                observer.onUidActive(item.uid);
4128                            }
4129                            if (VALIDATE_UID_STATES && i == 0) {
4130                                validateUid.idle = false;
4131                            }
4132                        }
4133                        if (change == UidRecord.CHANGE_GONE
4134                                || change == UidRecord.CHANGE_GONE_IDLE) {
4135                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4136                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4137                                        "UID gone uid=" + item.uid);
4138                                observer.onUidGone(item.uid);
4139                            }
4140                            if (VALIDATE_UID_STATES && i == 0) {
4141                                if (validateUid != null) {
4142                                    mValidateUids.remove(item.uid);
4143                                }
4144                            }
4145                        } else {
4146                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4147                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4148                                        "UID CHANGED uid=" + item.uid
4149                                                + ": " + item.processState);
4150                                observer.onUidStateChanged(item.uid, item.processState);
4151                            }
4152                            if (VALIDATE_UID_STATES && i == 0) {
4153                                validateUid.curProcState = validateUid.setProcState
4154                                        = item.processState;
4155                            }
4156                        }
4157                    }
4158                } catch (RemoteException e) {
4159                }
4160            }
4161        }
4162        mUidObservers.finishBroadcast();
4163
4164        synchronized (this) {
4165            for (int j=0; j<N; j++) {
4166                mAvailUidChanges.add(mActiveUidChanges[j]);
4167            }
4168        }
4169    }
4170
4171    @Override
4172    public final int startActivity(IApplicationThread caller, String callingPackage,
4173            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4174            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4175        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4176                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4177                UserHandle.getCallingUserId());
4178    }
4179
4180    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4181        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4182        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4183                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4184                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4185
4186        // TODO: Switch to user app stacks here.
4187        String mimeType = intent.getType();
4188        final Uri data = intent.getData();
4189        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4190            mimeType = getProviderMimeType(data, userId);
4191        }
4192        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4193
4194        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4195        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4196                null, 0, 0, null, null, null, null, false, userId, container, null);
4197    }
4198
4199    @Override
4200    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4201            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4202            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4203        enforceNotIsolatedCaller("startActivity");
4204        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4205                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4206        // TODO: Switch to user app stacks here.
4207        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4208                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4209                profilerInfo, null, null, bOptions, false, userId, null, null);
4210    }
4211
4212    @Override
4213    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4214            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4215            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4216            int userId) {
4217
4218        // This is very dangerous -- it allows you to perform a start activity (including
4219        // permission grants) as any app that may launch one of your own activities.  So
4220        // we will only allow this to be done from activities that are part of the core framework,
4221        // and then only when they are running as the system.
4222        final ActivityRecord sourceRecord;
4223        final int targetUid;
4224        final String targetPackage;
4225        synchronized (this) {
4226            if (resultTo == null) {
4227                throw new SecurityException("Must be called from an activity");
4228            }
4229            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4230            if (sourceRecord == null) {
4231                throw new SecurityException("Called with bad activity token: " + resultTo);
4232            }
4233            if (!sourceRecord.info.packageName.equals("android")) {
4234                throw new SecurityException(
4235                        "Must be called from an activity that is declared in the android package");
4236            }
4237            if (sourceRecord.app == null) {
4238                throw new SecurityException("Called without a process attached to activity");
4239            }
4240            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4241                // This is still okay, as long as this activity is running under the
4242                // uid of the original calling activity.
4243                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4244                    throw new SecurityException(
4245                            "Calling activity in uid " + sourceRecord.app.uid
4246                                    + " must be system uid or original calling uid "
4247                                    + sourceRecord.launchedFromUid);
4248                }
4249            }
4250            if (ignoreTargetSecurity) {
4251                if (intent.getComponent() == null) {
4252                    throw new SecurityException(
4253                            "Component must be specified with ignoreTargetSecurity");
4254                }
4255                if (intent.getSelector() != null) {
4256                    throw new SecurityException(
4257                            "Selector not allowed with ignoreTargetSecurity");
4258                }
4259            }
4260            targetUid = sourceRecord.launchedFromUid;
4261            targetPackage = sourceRecord.launchedFromPackage;
4262        }
4263
4264        if (userId == UserHandle.USER_NULL) {
4265            userId = UserHandle.getUserId(sourceRecord.app.uid);
4266        }
4267
4268        // TODO: Switch to user app stacks here.
4269        try {
4270            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4271                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4272                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4273            return ret;
4274        } catch (SecurityException e) {
4275            // XXX need to figure out how to propagate to original app.
4276            // A SecurityException here is generally actually a fault of the original
4277            // calling activity (such as a fairly granting permissions), so propagate it
4278            // back to them.
4279            /*
4280            StringBuilder msg = new StringBuilder();
4281            msg.append("While launching");
4282            msg.append(intent.toString());
4283            msg.append(": ");
4284            msg.append(e.getMessage());
4285            */
4286            throw e;
4287        }
4288    }
4289
4290    @Override
4291    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4292            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4293            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4294        enforceNotIsolatedCaller("startActivityAndWait");
4295        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4296                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4297        WaitResult res = new WaitResult();
4298        // TODO: Switch to user app stacks here.
4299        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4300                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4301                bOptions, false, userId, null, null);
4302        return res;
4303    }
4304
4305    @Override
4306    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4307            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4308            int startFlags, Configuration config, Bundle bOptions, int userId) {
4309        enforceNotIsolatedCaller("startActivityWithConfig");
4310        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4311                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4312        // TODO: Switch to user app stacks here.
4313        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4314                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4315                null, null, config, bOptions, false, userId, null, null);
4316        return ret;
4317    }
4318
4319    @Override
4320    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4321            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4322            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4323            throws TransactionTooLargeException {
4324        enforceNotIsolatedCaller("startActivityIntentSender");
4325        // Refuse possible leaked file descriptors
4326        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4327            throw new IllegalArgumentException("File descriptors passed in Intent");
4328        }
4329
4330        IIntentSender sender = intent.getTarget();
4331        if (!(sender instanceof PendingIntentRecord)) {
4332            throw new IllegalArgumentException("Bad PendingIntent object");
4333        }
4334
4335        PendingIntentRecord pir = (PendingIntentRecord)sender;
4336
4337        synchronized (this) {
4338            // If this is coming from the currently resumed activity, it is
4339            // effectively saying that app switches are allowed at this point.
4340            final ActivityStack stack = getFocusedStack();
4341            if (stack.mResumedActivity != null &&
4342                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4343                mAppSwitchesAllowedTime = 0;
4344            }
4345        }
4346        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4347                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4348        return ret;
4349    }
4350
4351    @Override
4352    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4353            Intent intent, String resolvedType, IVoiceInteractionSession session,
4354            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4355            Bundle bOptions, int userId) {
4356        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4357                != PackageManager.PERMISSION_GRANTED) {
4358            String msg = "Permission Denial: startVoiceActivity() from pid="
4359                    + Binder.getCallingPid()
4360                    + ", uid=" + Binder.getCallingUid()
4361                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4362            Slog.w(TAG, msg);
4363            throw new SecurityException(msg);
4364        }
4365        if (session == null || interactor == null) {
4366            throw new NullPointerException("null session or interactor");
4367        }
4368        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4369                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4370        // TODO: Switch to user app stacks here.
4371        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4372                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4373                null, bOptions, false, userId, null, null);
4374    }
4375
4376    @Override
4377    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4378            throws RemoteException {
4379        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4380        synchronized (this) {
4381            ActivityRecord activity = getFocusedStack().topActivity();
4382            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4383                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4384            }
4385            if (mRunningVoice != null || activity.task.voiceSession != null
4386                    || activity.voiceSession != null) {
4387                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4388                return;
4389            }
4390            if (activity.pendingVoiceInteractionStart) {
4391                Slog.w(TAG, "Pending start of voice interaction already.");
4392                return;
4393            }
4394            activity.pendingVoiceInteractionStart = true;
4395        }
4396        LocalServices.getService(VoiceInteractionManagerInternal.class)
4397                .startLocalVoiceInteraction(callingActivity, options);
4398    }
4399
4400    @Override
4401    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4402        LocalServices.getService(VoiceInteractionManagerInternal.class)
4403                .stopLocalVoiceInteraction(callingActivity);
4404    }
4405
4406    @Override
4407    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4408        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4409                .supportsLocalVoiceInteraction();
4410    }
4411
4412    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4413            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4414        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4415        if (activityToCallback == null) return;
4416        activityToCallback.setVoiceSessionLocked(voiceSession);
4417
4418        // Inform the activity
4419        try {
4420            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4421                    voiceInteractor);
4422            long token = Binder.clearCallingIdentity();
4423            try {
4424                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4425            } finally {
4426                Binder.restoreCallingIdentity(token);
4427            }
4428            // TODO: VI Should we cache the activity so that it's easier to find later
4429            // rather than scan through all the stacks and activities?
4430        } catch (RemoteException re) {
4431            activityToCallback.clearVoiceSessionLocked();
4432            // TODO: VI Should this terminate the voice session?
4433        }
4434    }
4435
4436    @Override
4437    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4438        synchronized (this) {
4439            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4440                if (keepAwake) {
4441                    mVoiceWakeLock.acquire();
4442                } else {
4443                    mVoiceWakeLock.release();
4444                }
4445            }
4446        }
4447    }
4448
4449    @Override
4450    public boolean startNextMatchingActivity(IBinder callingActivity,
4451            Intent intent, Bundle bOptions) {
4452        // Refuse possible leaked file descriptors
4453        if (intent != null && intent.hasFileDescriptors() == true) {
4454            throw new IllegalArgumentException("File descriptors passed in Intent");
4455        }
4456        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4457
4458        synchronized (this) {
4459            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4460            if (r == null) {
4461                ActivityOptions.abort(options);
4462                return false;
4463            }
4464            if (r.app == null || r.app.thread == null) {
4465                // The caller is not running...  d'oh!
4466                ActivityOptions.abort(options);
4467                return false;
4468            }
4469            intent = new Intent(intent);
4470            // The caller is not allowed to change the data.
4471            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4472            // And we are resetting to find the next component...
4473            intent.setComponent(null);
4474
4475            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4476
4477            ActivityInfo aInfo = null;
4478            try {
4479                List<ResolveInfo> resolves =
4480                    AppGlobals.getPackageManager().queryIntentActivities(
4481                            intent, r.resolvedType,
4482                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4483                            UserHandle.getCallingUserId()).getList();
4484
4485                // Look for the original activity in the list...
4486                final int N = resolves != null ? resolves.size() : 0;
4487                for (int i=0; i<N; i++) {
4488                    ResolveInfo rInfo = resolves.get(i);
4489                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4490                            && rInfo.activityInfo.name.equals(r.info.name)) {
4491                        // We found the current one...  the next matching is
4492                        // after it.
4493                        i++;
4494                        if (i<N) {
4495                            aInfo = resolves.get(i).activityInfo;
4496                        }
4497                        if (debug) {
4498                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4499                                    + "/" + r.info.name);
4500                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4501                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4502                        }
4503                        break;
4504                    }
4505                }
4506            } catch (RemoteException e) {
4507            }
4508
4509            if (aInfo == null) {
4510                // Nobody who is next!
4511                ActivityOptions.abort(options);
4512                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4513                return false;
4514            }
4515
4516            intent.setComponent(new ComponentName(
4517                    aInfo.applicationInfo.packageName, aInfo.name));
4518            intent.setFlags(intent.getFlags()&~(
4519                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4520                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4521                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4522                    Intent.FLAG_ACTIVITY_NEW_TASK));
4523
4524            // Okay now we need to start the new activity, replacing the
4525            // currently running activity.  This is a little tricky because
4526            // we want to start the new one as if the current one is finished,
4527            // but not finish the current one first so that there is no flicker.
4528            // And thus...
4529            final boolean wasFinishing = r.finishing;
4530            r.finishing = true;
4531
4532            // Propagate reply information over to the new activity.
4533            final ActivityRecord resultTo = r.resultTo;
4534            final String resultWho = r.resultWho;
4535            final int requestCode = r.requestCode;
4536            r.resultTo = null;
4537            if (resultTo != null) {
4538                resultTo.removeResultsLocked(r, resultWho, requestCode);
4539            }
4540
4541            final long origId = Binder.clearCallingIdentity();
4542            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4543                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4544                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4545                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4546                    false, false, null, null, null);
4547            Binder.restoreCallingIdentity(origId);
4548
4549            r.finishing = wasFinishing;
4550            if (res != ActivityManager.START_SUCCESS) {
4551                return false;
4552            }
4553            return true;
4554        }
4555    }
4556
4557    @Override
4558    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4559        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4560            String msg = "Permission Denial: startActivityFromRecents called without " +
4561                    START_TASKS_FROM_RECENTS;
4562            Slog.w(TAG, msg);
4563            throw new SecurityException(msg);
4564        }
4565        final long origId = Binder.clearCallingIdentity();
4566        try {
4567            synchronized (this) {
4568                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4569            }
4570        } finally {
4571            Binder.restoreCallingIdentity(origId);
4572        }
4573    }
4574
4575    final int startActivityInPackage(int uid, String callingPackage,
4576            Intent intent, String resolvedType, IBinder resultTo,
4577            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4578            IActivityContainer container, TaskRecord inTask) {
4579
4580        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4581                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4582
4583        // TODO: Switch to user app stacks here.
4584        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4585                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4586                null, null, null, bOptions, false, userId, container, inTask);
4587        return ret;
4588    }
4589
4590    @Override
4591    public final int startActivities(IApplicationThread caller, String callingPackage,
4592            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4593            int userId) {
4594        enforceNotIsolatedCaller("startActivities");
4595        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4596                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4597        // TODO: Switch to user app stacks here.
4598        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4599                resolvedTypes, resultTo, bOptions, userId);
4600        return ret;
4601    }
4602
4603    final int startActivitiesInPackage(int uid, String callingPackage,
4604            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4605            Bundle bOptions, int userId) {
4606
4607        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4608                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4609        // TODO: Switch to user app stacks here.
4610        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4611                resultTo, bOptions, userId);
4612        return ret;
4613    }
4614
4615    @Override
4616    public void reportActivityFullyDrawn(IBinder token) {
4617        synchronized (this) {
4618            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4619            if (r == null) {
4620                return;
4621            }
4622            r.reportFullyDrawnLocked();
4623        }
4624    }
4625
4626    @Override
4627    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4628        synchronized (this) {
4629            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4630            if (r == null) {
4631                return;
4632            }
4633            TaskRecord task = r.task;
4634            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4635                // Fixed screen orientation isn't supported when activities aren't in full screen
4636                // mode.
4637                return;
4638            }
4639            final long origId = Binder.clearCallingIdentity();
4640            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4641            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4642                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4643            if (config != null) {
4644                r.frozenBeforeDestroy = true;
4645                if (!updateConfigurationLocked(config, r, false)) {
4646                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4647                }
4648            }
4649            Binder.restoreCallingIdentity(origId);
4650        }
4651    }
4652
4653    @Override
4654    public int getRequestedOrientation(IBinder token) {
4655        synchronized (this) {
4656            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4657            if (r == null) {
4658                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4659            }
4660            return mWindowManager.getAppOrientation(r.appToken);
4661        }
4662    }
4663
4664    /**
4665     * This is the internal entry point for handling Activity.finish().
4666     *
4667     * @param token The Binder token referencing the Activity we want to finish.
4668     * @param resultCode Result code, if any, from this Activity.
4669     * @param resultData Result data (Intent), if any, from this Activity.
4670     * @param finishTask Whether to finish the task associated with this Activity.
4671     *
4672     * @return Returns true if the activity successfully finished, or false if it is still running.
4673     */
4674    @Override
4675    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4676            int finishTask) {
4677        // Refuse possible leaked file descriptors
4678        if (resultData != null && resultData.hasFileDescriptors() == true) {
4679            throw new IllegalArgumentException("File descriptors passed in Intent");
4680        }
4681
4682        synchronized(this) {
4683            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4684            if (r == null) {
4685                return true;
4686            }
4687            // Keep track of the root activity of the task before we finish it
4688            TaskRecord tr = r.task;
4689            ActivityRecord rootR = tr.getRootActivity();
4690            if (rootR == null) {
4691                Slog.w(TAG, "Finishing task with all activities already finished");
4692            }
4693            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4694            // finish.
4695            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4696                    mStackSupervisor.isLastLockedTask(tr)) {
4697                Slog.i(TAG, "Not finishing task in lock task mode");
4698                mStackSupervisor.showLockTaskToast();
4699                return false;
4700            }
4701            if (mController != null) {
4702                // Find the first activity that is not finishing.
4703                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4704                if (next != null) {
4705                    // ask watcher if this is allowed
4706                    boolean resumeOK = true;
4707                    try {
4708                        resumeOK = mController.activityResuming(next.packageName);
4709                    } catch (RemoteException e) {
4710                        mController = null;
4711                        Watchdog.getInstance().setActivityController(null);
4712                    }
4713
4714                    if (!resumeOK) {
4715                        Slog.i(TAG, "Not finishing activity because controller resumed");
4716                        return false;
4717                    }
4718                }
4719            }
4720            final long origId = Binder.clearCallingIdentity();
4721            try {
4722                boolean res;
4723                final boolean finishWithRootActivity =
4724                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4725                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4726                        || (finishWithRootActivity && r == rootR)) {
4727                    // If requested, remove the task that is associated to this activity only if it
4728                    // was the root activity in the task. The result code and data is ignored
4729                    // because we don't support returning them across task boundaries. Also, to
4730                    // keep backwards compatibility we remove the task from recents when finishing
4731                    // task with root activity.
4732                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4733                    if (!res) {
4734                        Slog.i(TAG, "Removing task failed to finish activity");
4735                    }
4736                } else {
4737                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4738                            resultData, "app-request", true);
4739                    if (!res) {
4740                        Slog.i(TAG, "Failed to finish by app-request");
4741                    }
4742                }
4743                return res;
4744            } finally {
4745                Binder.restoreCallingIdentity(origId);
4746            }
4747        }
4748    }
4749
4750    @Override
4751    public final void finishHeavyWeightApp() {
4752        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4753                != PackageManager.PERMISSION_GRANTED) {
4754            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4755                    + Binder.getCallingPid()
4756                    + ", uid=" + Binder.getCallingUid()
4757                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4758            Slog.w(TAG, msg);
4759            throw new SecurityException(msg);
4760        }
4761
4762        synchronized(this) {
4763            if (mHeavyWeightProcess == null) {
4764                return;
4765            }
4766
4767            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4768            for (int i = 0; i < activities.size(); i++) {
4769                ActivityRecord r = activities.get(i);
4770                if (!r.finishing && r.isInStackLocked()) {
4771                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4772                            null, "finish-heavy", true);
4773                }
4774            }
4775
4776            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4777                    mHeavyWeightProcess.userId, 0));
4778            mHeavyWeightProcess = null;
4779        }
4780    }
4781
4782    @Override
4783    public void crashApplication(int uid, int initialPid, String packageName,
4784            String message) {
4785        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4786                != PackageManager.PERMISSION_GRANTED) {
4787            String msg = "Permission Denial: crashApplication() from pid="
4788                    + Binder.getCallingPid()
4789                    + ", uid=" + Binder.getCallingUid()
4790                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4791            Slog.w(TAG, msg);
4792            throw new SecurityException(msg);
4793        }
4794
4795        synchronized(this) {
4796            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4797        }
4798    }
4799
4800    @Override
4801    public final void finishSubActivity(IBinder token, String resultWho,
4802            int requestCode) {
4803        synchronized(this) {
4804            final long origId = Binder.clearCallingIdentity();
4805            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4806            if (r != null) {
4807                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4808            }
4809            Binder.restoreCallingIdentity(origId);
4810        }
4811    }
4812
4813    @Override
4814    public boolean finishActivityAffinity(IBinder token) {
4815        synchronized(this) {
4816            final long origId = Binder.clearCallingIdentity();
4817            try {
4818                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4819                if (r == null) {
4820                    return false;
4821                }
4822
4823                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4824                // can finish.
4825                final TaskRecord task = r.task;
4826                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4827                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4828                    mStackSupervisor.showLockTaskToast();
4829                    return false;
4830                }
4831                return task.stack.finishActivityAffinityLocked(r);
4832            } finally {
4833                Binder.restoreCallingIdentity(origId);
4834            }
4835        }
4836    }
4837
4838    @Override
4839    public void finishVoiceTask(IVoiceInteractionSession session) {
4840        synchronized (this) {
4841            final long origId = Binder.clearCallingIdentity();
4842            try {
4843                // TODO: VI Consider treating local voice interactions and voice tasks
4844                // differently here
4845                mStackSupervisor.finishVoiceTask(session);
4846            } finally {
4847                Binder.restoreCallingIdentity(origId);
4848            }
4849        }
4850
4851    }
4852
4853    @Override
4854    public boolean releaseActivityInstance(IBinder token) {
4855        synchronized(this) {
4856            final long origId = Binder.clearCallingIdentity();
4857            try {
4858                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4859                if (r == null) {
4860                    return false;
4861                }
4862                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4863            } finally {
4864                Binder.restoreCallingIdentity(origId);
4865            }
4866        }
4867    }
4868
4869    @Override
4870    public void releaseSomeActivities(IApplicationThread appInt) {
4871        synchronized(this) {
4872            final long origId = Binder.clearCallingIdentity();
4873            try {
4874                ProcessRecord app = getRecordForAppLocked(appInt);
4875                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4876            } finally {
4877                Binder.restoreCallingIdentity(origId);
4878            }
4879        }
4880    }
4881
4882    @Override
4883    public boolean willActivityBeVisible(IBinder token) {
4884        synchronized(this) {
4885            ActivityStack stack = ActivityRecord.getStackLocked(token);
4886            if (stack != null) {
4887                return stack.willActivityBeVisibleLocked(token);
4888            }
4889            return false;
4890        }
4891    }
4892
4893    @Override
4894    public void overridePendingTransition(IBinder token, String packageName,
4895            int enterAnim, int exitAnim) {
4896        synchronized(this) {
4897            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4898            if (self == null) {
4899                return;
4900            }
4901
4902            final long origId = Binder.clearCallingIdentity();
4903
4904            if (self.state == ActivityState.RESUMED
4905                    || self.state == ActivityState.PAUSING) {
4906                mWindowManager.overridePendingAppTransition(packageName,
4907                        enterAnim, exitAnim, null);
4908            }
4909
4910            Binder.restoreCallingIdentity(origId);
4911        }
4912    }
4913
4914    /**
4915     * Main function for removing an existing process from the activity manager
4916     * as a result of that process going away.  Clears out all connections
4917     * to the process.
4918     */
4919    private final void handleAppDiedLocked(ProcessRecord app,
4920            boolean restarting, boolean allowRestart) {
4921        int pid = app.pid;
4922        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4923        if (!kept && !restarting) {
4924            removeLruProcessLocked(app);
4925            if (pid > 0) {
4926                ProcessList.remove(pid);
4927            }
4928        }
4929
4930        if (mProfileProc == app) {
4931            clearProfilerLocked();
4932        }
4933
4934        // Remove this application's activities from active lists.
4935        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4936
4937        app.activities.clear();
4938
4939        if (app.instrumentationClass != null) {
4940            Slog.w(TAG, "Crash of app " + app.processName
4941                  + " running instrumentation " + app.instrumentationClass);
4942            Bundle info = new Bundle();
4943            info.putString("shortMsg", "Process crashed.");
4944            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4945        }
4946
4947        if (!restarting && hasVisibleActivities
4948                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4949            // If there was nothing to resume, and we are not already restarting this process, but
4950            // there is a visible activity that is hosted by the process...  then make sure all
4951            // visible activities are running, taking care of restarting this process.
4952            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4953        }
4954    }
4955
4956    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4957        IBinder threadBinder = thread.asBinder();
4958        // Find the application record.
4959        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4960            ProcessRecord rec = mLruProcesses.get(i);
4961            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4962                return i;
4963            }
4964        }
4965        return -1;
4966    }
4967
4968    final ProcessRecord getRecordForAppLocked(
4969            IApplicationThread thread) {
4970        if (thread == null) {
4971            return null;
4972        }
4973
4974        int appIndex = getLRURecordIndexForAppLocked(thread);
4975        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4976    }
4977
4978    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4979        // If there are no longer any background processes running,
4980        // and the app that died was not running instrumentation,
4981        // then tell everyone we are now low on memory.
4982        boolean haveBg = false;
4983        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4984            ProcessRecord rec = mLruProcesses.get(i);
4985            if (rec.thread != null
4986                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4987                haveBg = true;
4988                break;
4989            }
4990        }
4991
4992        if (!haveBg) {
4993            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4994            if (doReport) {
4995                long now = SystemClock.uptimeMillis();
4996                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4997                    doReport = false;
4998                } else {
4999                    mLastMemUsageReportTime = now;
5000                }
5001            }
5002            final ArrayList<ProcessMemInfo> memInfos
5003                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5004            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5005            long now = SystemClock.uptimeMillis();
5006            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5007                ProcessRecord rec = mLruProcesses.get(i);
5008                if (rec == dyingProc || rec.thread == null) {
5009                    continue;
5010                }
5011                if (doReport) {
5012                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5013                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5014                }
5015                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5016                    // The low memory report is overriding any current
5017                    // state for a GC request.  Make sure to do
5018                    // heavy/important/visible/foreground processes first.
5019                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5020                        rec.lastRequestedGc = 0;
5021                    } else {
5022                        rec.lastRequestedGc = rec.lastLowMemory;
5023                    }
5024                    rec.reportLowMemory = true;
5025                    rec.lastLowMemory = now;
5026                    mProcessesToGc.remove(rec);
5027                    addProcessToGcListLocked(rec);
5028                }
5029            }
5030            if (doReport) {
5031                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5032                mHandler.sendMessage(msg);
5033            }
5034            scheduleAppGcsLocked();
5035        }
5036    }
5037
5038    final void appDiedLocked(ProcessRecord app) {
5039       appDiedLocked(app, app.pid, app.thread, false);
5040    }
5041
5042    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5043            boolean fromBinderDied) {
5044        // First check if this ProcessRecord is actually active for the pid.
5045        synchronized (mPidsSelfLocked) {
5046            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5047            if (curProc != app) {
5048                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5049                return;
5050            }
5051        }
5052
5053        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5054        synchronized (stats) {
5055            stats.noteProcessDiedLocked(app.info.uid, pid);
5056        }
5057
5058        if (!app.killed) {
5059            if (!fromBinderDied) {
5060                Process.killProcessQuiet(pid);
5061            }
5062            killProcessGroup(app.uid, pid);
5063            app.killed = true;
5064        }
5065
5066        // Clean up already done if the process has been re-started.
5067        if (app.pid == pid && app.thread != null &&
5068                app.thread.asBinder() == thread.asBinder()) {
5069            boolean doLowMem = app.instrumentationClass == null;
5070            boolean doOomAdj = doLowMem;
5071            if (!app.killedByAm) {
5072                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5073                        + ") has died");
5074                mAllowLowerMemLevel = true;
5075            } else {
5076                // Note that we always want to do oom adj to update our state with the
5077                // new number of procs.
5078                mAllowLowerMemLevel = false;
5079                doLowMem = false;
5080            }
5081            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5082            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5083                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5084            handleAppDiedLocked(app, false, true);
5085
5086            if (doOomAdj) {
5087                updateOomAdjLocked();
5088            }
5089            if (doLowMem) {
5090                doLowMemReportIfNeededLocked(app);
5091            }
5092        } else if (app.pid != pid) {
5093            // A new process has already been started.
5094            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5095                    + ") has died and restarted (pid " + app.pid + ").");
5096            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5097        } else if (DEBUG_PROCESSES) {
5098            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5099                    + thread.asBinder());
5100        }
5101    }
5102
5103    /**
5104     * If a stack trace dump file is configured, dump process stack traces.
5105     * @param clearTraces causes the dump file to be erased prior to the new
5106     *    traces being written, if true; when false, the new traces will be
5107     *    appended to any existing file content.
5108     * @param firstPids of dalvik VM processes to dump stack traces for first
5109     * @param lastPids of dalvik VM processes to dump stack traces for last
5110     * @param nativeProcs optional list of native process names to dump stack crawls
5111     * @return file containing stack traces, or null if no dump file is configured
5112     */
5113    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5114            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5115        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5116        if (tracesPath == null || tracesPath.length() == 0) {
5117            return null;
5118        }
5119
5120        File tracesFile = new File(tracesPath);
5121        try {
5122            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5123            tracesFile.createNewFile();
5124            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5125        } catch (IOException e) {
5126            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5127            return null;
5128        }
5129
5130        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5131        return tracesFile;
5132    }
5133
5134    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5135            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5136        // Use a FileObserver to detect when traces finish writing.
5137        // The order of traces is considered important to maintain for legibility.
5138        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5139            @Override
5140            public synchronized void onEvent(int event, String path) { notify(); }
5141        };
5142
5143        try {
5144            observer.startWatching();
5145
5146            // First collect all of the stacks of the most important pids.
5147            if (firstPids != null) {
5148                try {
5149                    int num = firstPids.size();
5150                    for (int i = 0; i < num; i++) {
5151                        synchronized (observer) {
5152                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5153                                    + firstPids.get(i));
5154                            final long sime = SystemClock.elapsedRealtime();
5155                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5156                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5157                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5158                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5159                        }
5160                    }
5161                } catch (InterruptedException e) {
5162                    Slog.wtf(TAG, e);
5163                }
5164            }
5165
5166            // Next collect the stacks of the native pids
5167            if (nativeProcs != null) {
5168                int[] pids = Process.getPidsForCommands(nativeProcs);
5169                if (pids != null) {
5170                    for (int pid : pids) {
5171                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5172                        final long sime = SystemClock.elapsedRealtime();
5173                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5174                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5175                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5176                    }
5177                }
5178            }
5179
5180            // Lastly, measure CPU usage.
5181            if (processCpuTracker != null) {
5182                processCpuTracker.init();
5183                System.gc();
5184                processCpuTracker.update();
5185                try {
5186                    synchronized (processCpuTracker) {
5187                        processCpuTracker.wait(500); // measure over 1/2 second.
5188                    }
5189                } catch (InterruptedException e) {
5190                }
5191                processCpuTracker.update();
5192
5193                // We'll take the stack crawls of just the top apps using CPU.
5194                final int N = processCpuTracker.countWorkingStats();
5195                int numProcs = 0;
5196                for (int i=0; i<N && numProcs<5; i++) {
5197                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5198                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5199                        numProcs++;
5200                        try {
5201                            synchronized (observer) {
5202                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5203                                        + stats.pid);
5204                                final long stime = SystemClock.elapsedRealtime();
5205                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5206                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5207                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5208                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5209                            }
5210                        } catch (InterruptedException e) {
5211                            Slog.wtf(TAG, e);
5212                        }
5213                    } else if (DEBUG_ANR) {
5214                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5215                                + stats.pid);
5216                    }
5217                }
5218            }
5219        } finally {
5220            observer.stopWatching();
5221        }
5222    }
5223
5224    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5225        if (true || IS_USER_BUILD) {
5226            return;
5227        }
5228        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5229        if (tracesPath == null || tracesPath.length() == 0) {
5230            return;
5231        }
5232
5233        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5234        StrictMode.allowThreadDiskWrites();
5235        try {
5236            final File tracesFile = new File(tracesPath);
5237            final File tracesDir = tracesFile.getParentFile();
5238            final File tracesTmp = new File(tracesDir, "__tmp__");
5239            try {
5240                if (tracesFile.exists()) {
5241                    tracesTmp.delete();
5242                    tracesFile.renameTo(tracesTmp);
5243                }
5244                StringBuilder sb = new StringBuilder();
5245                Time tobj = new Time();
5246                tobj.set(System.currentTimeMillis());
5247                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5248                sb.append(": ");
5249                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5250                sb.append(" since ");
5251                sb.append(msg);
5252                FileOutputStream fos = new FileOutputStream(tracesFile);
5253                fos.write(sb.toString().getBytes());
5254                if (app == null) {
5255                    fos.write("\n*** No application process!".getBytes());
5256                }
5257                fos.close();
5258                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5259            } catch (IOException e) {
5260                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5261                return;
5262            }
5263
5264            if (app != null) {
5265                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5266                firstPids.add(app.pid);
5267                dumpStackTraces(tracesPath, firstPids, null, null, null);
5268            }
5269
5270            File lastTracesFile = null;
5271            File curTracesFile = null;
5272            for (int i=9; i>=0; i--) {
5273                String name = String.format(Locale.US, "slow%02d.txt", i);
5274                curTracesFile = new File(tracesDir, name);
5275                if (curTracesFile.exists()) {
5276                    if (lastTracesFile != null) {
5277                        curTracesFile.renameTo(lastTracesFile);
5278                    } else {
5279                        curTracesFile.delete();
5280                    }
5281                }
5282                lastTracesFile = curTracesFile;
5283            }
5284            tracesFile.renameTo(curTracesFile);
5285            if (tracesTmp.exists()) {
5286                tracesTmp.renameTo(tracesFile);
5287            }
5288        } finally {
5289            StrictMode.setThreadPolicy(oldPolicy);
5290        }
5291    }
5292
5293    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5294        if (!mLaunchWarningShown) {
5295            mLaunchWarningShown = true;
5296            mUiHandler.post(new Runnable() {
5297                @Override
5298                public void run() {
5299                    synchronized (ActivityManagerService.this) {
5300                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5301                        d.show();
5302                        mUiHandler.postDelayed(new Runnable() {
5303                            @Override
5304                            public void run() {
5305                                synchronized (ActivityManagerService.this) {
5306                                    d.dismiss();
5307                                    mLaunchWarningShown = false;
5308                                }
5309                            }
5310                        }, 4000);
5311                    }
5312                }
5313            });
5314        }
5315    }
5316
5317    @Override
5318    public boolean clearApplicationUserData(final String packageName,
5319            final IPackageDataObserver observer, int userId) {
5320        enforceNotIsolatedCaller("clearApplicationUserData");
5321        int uid = Binder.getCallingUid();
5322        int pid = Binder.getCallingPid();
5323        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5324                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5325
5326        final DevicePolicyManagerInternal dpmi = LocalServices
5327                .getService(DevicePolicyManagerInternal.class);
5328        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5329            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5330        }
5331
5332        long callingId = Binder.clearCallingIdentity();
5333        try {
5334            IPackageManager pm = AppGlobals.getPackageManager();
5335            int pkgUid = -1;
5336            synchronized(this) {
5337                try {
5338                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5339                } catch (RemoteException e) {
5340                }
5341                if (pkgUid == -1) {
5342                    Slog.w(TAG, "Invalid packageName: " + packageName);
5343                    if (observer != null) {
5344                        try {
5345                            observer.onRemoveCompleted(packageName, false);
5346                        } catch (RemoteException e) {
5347                            Slog.i(TAG, "Observer no longer exists.");
5348                        }
5349                    }
5350                    return false;
5351                }
5352                if (uid == pkgUid || checkComponentPermission(
5353                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5354                        pid, uid, -1, true)
5355                        == PackageManager.PERMISSION_GRANTED) {
5356                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5357                } else {
5358                    throw new SecurityException("PID " + pid + " does not have permission "
5359                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5360                                    + " of package " + packageName);
5361                }
5362
5363                // Remove all tasks match the cleared application package and user
5364                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5365                    final TaskRecord tr = mRecentTasks.get(i);
5366                    final String taskPackageName =
5367                            tr.getBaseIntent().getComponent().getPackageName();
5368                    if (tr.userId != userId) continue;
5369                    if (!taskPackageName.equals(packageName)) continue;
5370                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5371                }
5372            }
5373
5374            try {
5375                // Clear application user data
5376                pm.clearApplicationUserData(packageName, observer, userId);
5377
5378                synchronized(this) {
5379                    // Remove all permissions granted from/to this package
5380                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5381                }
5382
5383                // Remove all zen rules created by this package; revoke it's zen access.
5384                INotificationManager inm = NotificationManager.getService();
5385                inm.removeAutomaticZenRules(packageName);
5386                inm.setNotificationPolicyAccessGranted(packageName, false);
5387
5388                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5389                        Uri.fromParts("package", packageName, null));
5390                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5391                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5392                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5393                        null, null, 0, null, null, null, null, false, false, userId);
5394            } catch (RemoteException e) {
5395            }
5396        } finally {
5397            Binder.restoreCallingIdentity(callingId);
5398        }
5399        return true;
5400    }
5401
5402    @Override
5403    public void killBackgroundProcesses(final String packageName, int userId) {
5404        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5405                != PackageManager.PERMISSION_GRANTED &&
5406                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5407                        != PackageManager.PERMISSION_GRANTED) {
5408            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5409                    + Binder.getCallingPid()
5410                    + ", uid=" + Binder.getCallingUid()
5411                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5412            Slog.w(TAG, msg);
5413            throw new SecurityException(msg);
5414        }
5415
5416        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5417                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5418        long callingId = Binder.clearCallingIdentity();
5419        try {
5420            IPackageManager pm = AppGlobals.getPackageManager();
5421            synchronized(this) {
5422                int appId = -1;
5423                try {
5424                    appId = UserHandle.getAppId(
5425                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5426                } catch (RemoteException e) {
5427                }
5428                if (appId == -1) {
5429                    Slog.w(TAG, "Invalid packageName: " + packageName);
5430                    return;
5431                }
5432                killPackageProcessesLocked(packageName, appId, userId,
5433                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5434            }
5435        } finally {
5436            Binder.restoreCallingIdentity(callingId);
5437        }
5438    }
5439
5440    @Override
5441    public void killAllBackgroundProcesses() {
5442        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5443                != PackageManager.PERMISSION_GRANTED) {
5444            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5445                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5446                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5447            Slog.w(TAG, msg);
5448            throw new SecurityException(msg);
5449        }
5450
5451        final long callingId = Binder.clearCallingIdentity();
5452        try {
5453            synchronized (this) {
5454                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5455                final int NP = mProcessNames.getMap().size();
5456                for (int ip = 0; ip < NP; ip++) {
5457                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5458                    final int NA = apps.size();
5459                    for (int ia = 0; ia < NA; ia++) {
5460                        final ProcessRecord app = apps.valueAt(ia);
5461                        if (app.persistent) {
5462                            // We don't kill persistent processes.
5463                            continue;
5464                        }
5465                        if (app.removed) {
5466                            procs.add(app);
5467                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5468                            app.removed = true;
5469                            procs.add(app);
5470                        }
5471                    }
5472                }
5473
5474                final int N = procs.size();
5475                for (int i = 0; i < N; i++) {
5476                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5477                }
5478
5479                mAllowLowerMemLevel = true;
5480
5481                updateOomAdjLocked();
5482                doLowMemReportIfNeededLocked(null);
5483            }
5484        } finally {
5485            Binder.restoreCallingIdentity(callingId);
5486        }
5487    }
5488
5489    /**
5490     * Kills all background processes, except those matching any of the
5491     * specified properties.
5492     *
5493     * @param minTargetSdk the target SDK version at or above which to preserve
5494     *                     processes, or {@code -1} to ignore the target SDK
5495     * @param maxProcState the process state at or below which to preserve
5496     *                     processes, or {@code -1} to ignore the process state
5497     */
5498    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5499        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5500                != PackageManager.PERMISSION_GRANTED) {
5501            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5502                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5503                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5504            Slog.w(TAG, msg);
5505            throw new SecurityException(msg);
5506        }
5507
5508        final long callingId = Binder.clearCallingIdentity();
5509        try {
5510            synchronized (this) {
5511                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5512                final int NP = mProcessNames.getMap().size();
5513                for (int ip = 0; ip < NP; ip++) {
5514                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5515                    final int NA = apps.size();
5516                    for (int ia = 0; ia < NA; ia++) {
5517                        final ProcessRecord app = apps.valueAt(ia);
5518                        if (app.removed) {
5519                            procs.add(app);
5520                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5521                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5522                            app.removed = true;
5523                            procs.add(app);
5524                        }
5525                    }
5526                }
5527
5528                final int N = procs.size();
5529                for (int i = 0; i < N; i++) {
5530                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5531                }
5532            }
5533        } finally {
5534            Binder.restoreCallingIdentity(callingId);
5535        }
5536    }
5537
5538    @Override
5539    public void forceStopPackage(final String packageName, int userId) {
5540        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5541                != PackageManager.PERMISSION_GRANTED) {
5542            String msg = "Permission Denial: forceStopPackage() from pid="
5543                    + Binder.getCallingPid()
5544                    + ", uid=" + Binder.getCallingUid()
5545                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5546            Slog.w(TAG, msg);
5547            throw new SecurityException(msg);
5548        }
5549        final int callingPid = Binder.getCallingPid();
5550        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5551                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5552        long callingId = Binder.clearCallingIdentity();
5553        try {
5554            IPackageManager pm = AppGlobals.getPackageManager();
5555            synchronized(this) {
5556                int[] users = userId == UserHandle.USER_ALL
5557                        ? mUserController.getUsers() : new int[] { userId };
5558                for (int user : users) {
5559                    int pkgUid = -1;
5560                    try {
5561                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5562                                user);
5563                    } catch (RemoteException e) {
5564                    }
5565                    if (pkgUid == -1) {
5566                        Slog.w(TAG, "Invalid packageName: " + packageName);
5567                        continue;
5568                    }
5569                    try {
5570                        pm.setPackageStoppedState(packageName, true, user);
5571                    } catch (RemoteException e) {
5572                    } catch (IllegalArgumentException e) {
5573                        Slog.w(TAG, "Failed trying to unstop package "
5574                                + packageName + ": " + e);
5575                    }
5576                    if (mUserController.isUserRunningLocked(user, 0)) {
5577                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5578                    }
5579                }
5580            }
5581        } finally {
5582            Binder.restoreCallingIdentity(callingId);
5583        }
5584    }
5585
5586    @Override
5587    public void addPackageDependency(String packageName) {
5588        synchronized (this) {
5589            int callingPid = Binder.getCallingPid();
5590            if (callingPid == Process.myPid()) {
5591                //  Yeah, um, no.
5592                return;
5593            }
5594            ProcessRecord proc;
5595            synchronized (mPidsSelfLocked) {
5596                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5597            }
5598            if (proc != null) {
5599                if (proc.pkgDeps == null) {
5600                    proc.pkgDeps = new ArraySet<String>(1);
5601                }
5602                proc.pkgDeps.add(packageName);
5603            }
5604        }
5605    }
5606
5607    /*
5608     * The pkg name and app id have to be specified.
5609     */
5610    @Override
5611    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5612        if (pkg == null) {
5613            return;
5614        }
5615        // Make sure the uid is valid.
5616        if (appid < 0) {
5617            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5618            return;
5619        }
5620        int callerUid = Binder.getCallingUid();
5621        // Only the system server can kill an application
5622        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5623            // Post an aysnc message to kill the application
5624            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5625            msg.arg1 = appid;
5626            msg.arg2 = 0;
5627            Bundle bundle = new Bundle();
5628            bundle.putString("pkg", pkg);
5629            bundle.putString("reason", reason);
5630            msg.obj = bundle;
5631            mHandler.sendMessage(msg);
5632        } else {
5633            throw new SecurityException(callerUid + " cannot kill pkg: " +
5634                    pkg);
5635        }
5636    }
5637
5638    @Override
5639    public void closeSystemDialogs(String reason) {
5640        enforceNotIsolatedCaller("closeSystemDialogs");
5641
5642        final int pid = Binder.getCallingPid();
5643        final int uid = Binder.getCallingUid();
5644        final long origId = Binder.clearCallingIdentity();
5645        try {
5646            synchronized (this) {
5647                // Only allow this from foreground processes, so that background
5648                // applications can't abuse it to prevent system UI from being shown.
5649                if (uid >= Process.FIRST_APPLICATION_UID) {
5650                    ProcessRecord proc;
5651                    synchronized (mPidsSelfLocked) {
5652                        proc = mPidsSelfLocked.get(pid);
5653                    }
5654                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5655                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5656                                + " from background process " + proc);
5657                        return;
5658                    }
5659                }
5660                closeSystemDialogsLocked(reason);
5661            }
5662        } finally {
5663            Binder.restoreCallingIdentity(origId);
5664        }
5665    }
5666
5667    void closeSystemDialogsLocked(String reason) {
5668        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5669        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5670                | Intent.FLAG_RECEIVER_FOREGROUND);
5671        if (reason != null) {
5672            intent.putExtra("reason", reason);
5673        }
5674        mWindowManager.closeSystemDialogs(reason);
5675
5676        mStackSupervisor.closeSystemDialogsLocked();
5677
5678        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5679                AppOpsManager.OP_NONE, null, false, false,
5680                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5681    }
5682
5683    @Override
5684    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5685        enforceNotIsolatedCaller("getProcessMemoryInfo");
5686        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5687        for (int i=pids.length-1; i>=0; i--) {
5688            ProcessRecord proc;
5689            int oomAdj;
5690            synchronized (this) {
5691                synchronized (mPidsSelfLocked) {
5692                    proc = mPidsSelfLocked.get(pids[i]);
5693                    oomAdj = proc != null ? proc.setAdj : 0;
5694                }
5695            }
5696            infos[i] = new Debug.MemoryInfo();
5697            Debug.getMemoryInfo(pids[i], infos[i]);
5698            if (proc != null) {
5699                synchronized (this) {
5700                    if (proc.thread != null && proc.setAdj == oomAdj) {
5701                        // Record this for posterity if the process has been stable.
5702                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5703                                infos[i].getTotalUss(), false, proc.pkgList);
5704                    }
5705                }
5706            }
5707        }
5708        return infos;
5709    }
5710
5711    @Override
5712    public long[] getProcessPss(int[] pids) {
5713        enforceNotIsolatedCaller("getProcessPss");
5714        long[] pss = new long[pids.length];
5715        for (int i=pids.length-1; i>=0; i--) {
5716            ProcessRecord proc;
5717            int oomAdj;
5718            synchronized (this) {
5719                synchronized (mPidsSelfLocked) {
5720                    proc = mPidsSelfLocked.get(pids[i]);
5721                    oomAdj = proc != null ? proc.setAdj : 0;
5722                }
5723            }
5724            long[] tmpUss = new long[1];
5725            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5726            if (proc != null) {
5727                synchronized (this) {
5728                    if (proc.thread != null && proc.setAdj == oomAdj) {
5729                        // Record this for posterity if the process has been stable.
5730                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5731                    }
5732                }
5733            }
5734        }
5735        return pss;
5736    }
5737
5738    @Override
5739    public void killApplicationProcess(String processName, int uid) {
5740        if (processName == null) {
5741            return;
5742        }
5743
5744        int callerUid = Binder.getCallingUid();
5745        // Only the system server can kill an application
5746        if (callerUid == Process.SYSTEM_UID) {
5747            synchronized (this) {
5748                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5749                if (app != null && app.thread != null) {
5750                    try {
5751                        app.thread.scheduleSuicide();
5752                    } catch (RemoteException e) {
5753                        // If the other end already died, then our work here is done.
5754                    }
5755                } else {
5756                    Slog.w(TAG, "Process/uid not found attempting kill of "
5757                            + processName + " / " + uid);
5758                }
5759            }
5760        } else {
5761            throw new SecurityException(callerUid + " cannot kill app process: " +
5762                    processName);
5763        }
5764    }
5765
5766    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5767        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5768                false, true, false, false, UserHandle.getUserId(uid), reason);
5769        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5770                Uri.fromParts("package", packageName, null));
5771        if (!mProcessesReady) {
5772            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5773                    | Intent.FLAG_RECEIVER_FOREGROUND);
5774        }
5775        intent.putExtra(Intent.EXTRA_UID, uid);
5776        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5777        broadcastIntentLocked(null, null, intent,
5778                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5779                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5780    }
5781
5782
5783    private final boolean killPackageProcessesLocked(String packageName, int appId,
5784            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5785            boolean doit, boolean evenPersistent, String reason) {
5786        ArrayList<ProcessRecord> procs = new ArrayList<>();
5787
5788        // Remove all processes this package may have touched: all with the
5789        // same UID (except for the system or root user), and all whose name
5790        // matches the package name.
5791        final int NP = mProcessNames.getMap().size();
5792        for (int ip=0; ip<NP; ip++) {
5793            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5794            final int NA = apps.size();
5795            for (int ia=0; ia<NA; ia++) {
5796                ProcessRecord app = apps.valueAt(ia);
5797                if (app.persistent && !evenPersistent) {
5798                    // we don't kill persistent processes
5799                    continue;
5800                }
5801                if (app.removed) {
5802                    if (doit) {
5803                        procs.add(app);
5804                    }
5805                    continue;
5806                }
5807
5808                // Skip process if it doesn't meet our oom adj requirement.
5809                if (app.setAdj < minOomAdj) {
5810                    continue;
5811                }
5812
5813                // If no package is specified, we call all processes under the
5814                // give user id.
5815                if (packageName == null) {
5816                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5817                        continue;
5818                    }
5819                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5820                        continue;
5821                    }
5822                // Package has been specified, we want to hit all processes
5823                // that match it.  We need to qualify this by the processes
5824                // that are running under the specified app and user ID.
5825                } else {
5826                    final boolean isDep = app.pkgDeps != null
5827                            && app.pkgDeps.contains(packageName);
5828                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5829                        continue;
5830                    }
5831                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5832                        continue;
5833                    }
5834                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5835                        continue;
5836                    }
5837                }
5838
5839                // Process has passed all conditions, kill it!
5840                if (!doit) {
5841                    return true;
5842                }
5843                app.removed = true;
5844                procs.add(app);
5845            }
5846        }
5847
5848        int N = procs.size();
5849        for (int i=0; i<N; i++) {
5850            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5851        }
5852        updateOomAdjLocked();
5853        return N > 0;
5854    }
5855
5856    private void cleanupDisabledPackageComponentsLocked(
5857            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5858
5859        Set<String> disabledClasses = null;
5860        boolean packageDisabled = false;
5861        IPackageManager pm = AppGlobals.getPackageManager();
5862
5863        if (changedClasses == null) {
5864            // Nothing changed...
5865            return;
5866        }
5867
5868        // Determine enable/disable state of the package and its components.
5869        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5870        for (int i = changedClasses.length - 1; i >= 0; i--) {
5871            final String changedClass = changedClasses[i];
5872
5873            if (changedClass.equals(packageName)) {
5874                try {
5875                    // Entire package setting changed
5876                    enabled = pm.getApplicationEnabledSetting(packageName,
5877                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5878                } catch (Exception e) {
5879                    // No such package/component; probably racing with uninstall.  In any
5880                    // event it means we have nothing further to do here.
5881                    return;
5882                }
5883                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5884                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5885                if (packageDisabled) {
5886                    // Entire package is disabled.
5887                    // No need to continue to check component states.
5888                    disabledClasses = null;
5889                    break;
5890                }
5891            } else {
5892                try {
5893                    enabled = pm.getComponentEnabledSetting(
5894                            new ComponentName(packageName, changedClass),
5895                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5896                } catch (Exception e) {
5897                    // As above, probably racing with uninstall.
5898                    return;
5899                }
5900                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5901                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5902                    if (disabledClasses == null) {
5903                        disabledClasses = new ArraySet<>(changedClasses.length);
5904                    }
5905                    disabledClasses.add(changedClass);
5906                }
5907            }
5908        }
5909
5910        if (!packageDisabled && disabledClasses == null) {
5911            // Nothing to do here...
5912            return;
5913        }
5914
5915        // Clean-up disabled activities.
5916        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5917                packageName, disabledClasses, true, false, userId) && mBooted) {
5918            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5919            mStackSupervisor.scheduleIdleLocked();
5920        }
5921
5922        // Clean-up disabled tasks
5923        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5924
5925        // Clean-up disabled services.
5926        mServices.bringDownDisabledPackageServicesLocked(
5927                packageName, disabledClasses, userId, false, killProcess, true);
5928
5929        // Clean-up disabled providers.
5930        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5931        mProviderMap.collectPackageProvidersLocked(
5932                packageName, disabledClasses, true, false, userId, providers);
5933        for (int i = providers.size() - 1; i >= 0; i--) {
5934            removeDyingProviderLocked(null, providers.get(i), true);
5935        }
5936
5937        // Clean-up disabled broadcast receivers.
5938        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5939            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5940                    packageName, disabledClasses, userId, true);
5941        }
5942
5943    }
5944
5945    final boolean forceStopPackageLocked(String packageName, int appId,
5946            boolean callerWillRestart, boolean purgeCache, boolean doit,
5947            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5948        int i;
5949
5950        if (userId == UserHandle.USER_ALL && packageName == null) {
5951            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5952        }
5953
5954        if (appId < 0 && packageName != null) {
5955            try {
5956                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5957                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5958            } catch (RemoteException e) {
5959            }
5960        }
5961
5962        if (doit) {
5963            if (packageName != null) {
5964                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5965                        + " user=" + userId + ": " + reason);
5966            } else {
5967                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5968            }
5969
5970            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5971        }
5972
5973        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5974                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5975                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5976
5977        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5978                packageName, null, doit, evenPersistent, userId)) {
5979            if (!doit) {
5980                return true;
5981            }
5982            didSomething = true;
5983        }
5984
5985        if (mServices.bringDownDisabledPackageServicesLocked(
5986                packageName, null, userId, evenPersistent, true, doit)) {
5987            if (!doit) {
5988                return true;
5989            }
5990            didSomething = true;
5991        }
5992
5993        if (packageName == null) {
5994            // Remove all sticky broadcasts from this user.
5995            mStickyBroadcasts.remove(userId);
5996        }
5997
5998        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5999        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6000                userId, providers)) {
6001            if (!doit) {
6002                return true;
6003            }
6004            didSomething = true;
6005        }
6006        for (i = providers.size() - 1; i >= 0; i--) {
6007            removeDyingProviderLocked(null, providers.get(i), true);
6008        }
6009
6010        // Remove transient permissions granted from/to this package/user
6011        removeUriPermissionsForPackageLocked(packageName, userId, false);
6012
6013        if (doit) {
6014            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6015                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6016                        packageName, null, userId, doit);
6017            }
6018        }
6019
6020        if (packageName == null || uninstalling) {
6021            // Remove pending intents.  For now we only do this when force
6022            // stopping users, because we have some problems when doing this
6023            // for packages -- app widgets are not currently cleaned up for
6024            // such packages, so they can be left with bad pending intents.
6025            if (mIntentSenderRecords.size() > 0) {
6026                Iterator<WeakReference<PendingIntentRecord>> it
6027                        = mIntentSenderRecords.values().iterator();
6028                while (it.hasNext()) {
6029                    WeakReference<PendingIntentRecord> wpir = it.next();
6030                    if (wpir == null) {
6031                        it.remove();
6032                        continue;
6033                    }
6034                    PendingIntentRecord pir = wpir.get();
6035                    if (pir == null) {
6036                        it.remove();
6037                        continue;
6038                    }
6039                    if (packageName == null) {
6040                        // Stopping user, remove all objects for the user.
6041                        if (pir.key.userId != userId) {
6042                            // Not the same user, skip it.
6043                            continue;
6044                        }
6045                    } else {
6046                        if (UserHandle.getAppId(pir.uid) != appId) {
6047                            // Different app id, skip it.
6048                            continue;
6049                        }
6050                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6051                            // Different user, skip it.
6052                            continue;
6053                        }
6054                        if (!pir.key.packageName.equals(packageName)) {
6055                            // Different package, skip it.
6056                            continue;
6057                        }
6058                    }
6059                    if (!doit) {
6060                        return true;
6061                    }
6062                    didSomething = true;
6063                    it.remove();
6064                    pir.canceled = true;
6065                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6066                        pir.key.activity.pendingResults.remove(pir.ref);
6067                    }
6068                }
6069            }
6070        }
6071
6072        if (doit) {
6073            if (purgeCache && packageName != null) {
6074                AttributeCache ac = AttributeCache.instance();
6075                if (ac != null) {
6076                    ac.removePackage(packageName);
6077                }
6078            }
6079            if (mBooted) {
6080                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6081                mStackSupervisor.scheduleIdleLocked();
6082            }
6083        }
6084
6085        return didSomething;
6086    }
6087
6088    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6089        ProcessRecord old = mProcessNames.remove(name, uid);
6090        if (old != null) {
6091            old.uidRecord.numProcs--;
6092            if (old.uidRecord.numProcs == 0) {
6093                // No more processes using this uid, tell clients it is gone.
6094                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6095                        "No more processes in " + old.uidRecord);
6096                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6097                mActiveUids.remove(uid);
6098                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6099            }
6100            old.uidRecord = null;
6101        }
6102        mIsolatedProcesses.remove(uid);
6103        return old;
6104    }
6105
6106    private final void addProcessNameLocked(ProcessRecord proc) {
6107        // We shouldn't already have a process under this name, but just in case we
6108        // need to clean up whatever may be there now.
6109        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6110        if (old == proc && proc.persistent) {
6111            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6112            Slog.w(TAG, "Re-adding persistent process " + proc);
6113        } else if (old != null) {
6114            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6115        }
6116        UidRecord uidRec = mActiveUids.get(proc.uid);
6117        if (uidRec == null) {
6118            uidRec = new UidRecord(proc.uid);
6119            // This is the first appearance of the uid, report it now!
6120            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6121                    "Creating new process uid: " + uidRec);
6122            mActiveUids.put(proc.uid, uidRec);
6123            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6124            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6125        }
6126        proc.uidRecord = uidRec;
6127        uidRec.numProcs++;
6128        mProcessNames.put(proc.processName, proc.uid, proc);
6129        if (proc.isolated) {
6130            mIsolatedProcesses.put(proc.uid, proc);
6131        }
6132    }
6133
6134    boolean removeProcessLocked(ProcessRecord app,
6135            boolean callerWillRestart, boolean allowRestart, String reason) {
6136        final String name = app.processName;
6137        final int uid = app.uid;
6138        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6139            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6140
6141        removeProcessNameLocked(name, uid);
6142        if (mHeavyWeightProcess == app) {
6143            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6144                    mHeavyWeightProcess.userId, 0));
6145            mHeavyWeightProcess = null;
6146        }
6147        boolean needRestart = false;
6148        if (app.pid > 0 && app.pid != MY_PID) {
6149            int pid = app.pid;
6150            synchronized (mPidsSelfLocked) {
6151                mPidsSelfLocked.remove(pid);
6152                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6153            }
6154            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6155            if (app.isolated) {
6156                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6157            }
6158            boolean willRestart = false;
6159            if (app.persistent && !app.isolated) {
6160                if (!callerWillRestart) {
6161                    willRestart = true;
6162                } else {
6163                    needRestart = true;
6164                }
6165            }
6166            app.kill(reason, true);
6167            handleAppDiedLocked(app, willRestart, allowRestart);
6168            if (willRestart) {
6169                removeLruProcessLocked(app);
6170                addAppLocked(app.info, false, null /* ABI override */);
6171            }
6172        } else {
6173            mRemovedProcesses.add(app);
6174        }
6175
6176        return needRestart;
6177    }
6178
6179    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6180        cleanupAppInLaunchingProvidersLocked(app, true);
6181        removeProcessLocked(app, false, true, "timeout publishing content providers");
6182    }
6183
6184    private final void processStartTimedOutLocked(ProcessRecord app) {
6185        final int pid = app.pid;
6186        boolean gone = false;
6187        synchronized (mPidsSelfLocked) {
6188            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6189            if (knownApp != null && knownApp.thread == null) {
6190                mPidsSelfLocked.remove(pid);
6191                gone = true;
6192            }
6193        }
6194
6195        if (gone) {
6196            Slog.w(TAG, "Process " + app + " failed to attach");
6197            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6198                    pid, app.uid, app.processName);
6199            removeProcessNameLocked(app.processName, app.uid);
6200            if (mHeavyWeightProcess == app) {
6201                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6202                        mHeavyWeightProcess.userId, 0));
6203                mHeavyWeightProcess = null;
6204            }
6205            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6206            if (app.isolated) {
6207                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6208            }
6209            // Take care of any launching providers waiting for this process.
6210            cleanupAppInLaunchingProvidersLocked(app, true);
6211            // Take care of any services that are waiting for the process.
6212            mServices.processStartTimedOutLocked(app);
6213            app.kill("start timeout", true);
6214            removeLruProcessLocked(app);
6215            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6216                Slog.w(TAG, "Unattached app died before backup, skipping");
6217                try {
6218                    IBackupManager bm = IBackupManager.Stub.asInterface(
6219                            ServiceManager.getService(Context.BACKUP_SERVICE));
6220                    bm.agentDisconnected(app.info.packageName);
6221                } catch (RemoteException e) {
6222                    // Can't happen; the backup manager is local
6223                }
6224            }
6225            if (isPendingBroadcastProcessLocked(pid)) {
6226                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6227                skipPendingBroadcastLocked(pid);
6228            }
6229        } else {
6230            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6231        }
6232    }
6233
6234    private final boolean attachApplicationLocked(IApplicationThread thread,
6235            int pid) {
6236
6237        // Find the application record that is being attached...  either via
6238        // the pid if we are running in multiple processes, or just pull the
6239        // next app record if we are emulating process with anonymous threads.
6240        ProcessRecord app;
6241        if (pid != MY_PID && pid >= 0) {
6242            synchronized (mPidsSelfLocked) {
6243                app = mPidsSelfLocked.get(pid);
6244            }
6245        } else {
6246            app = null;
6247        }
6248
6249        if (app == null) {
6250            Slog.w(TAG, "No pending application record for pid " + pid
6251                    + " (IApplicationThread " + thread + "); dropping process");
6252            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6253            if (pid > 0 && pid != MY_PID) {
6254                Process.killProcessQuiet(pid);
6255                //TODO: killProcessGroup(app.info.uid, pid);
6256            } else {
6257                try {
6258                    thread.scheduleExit();
6259                } catch (Exception e) {
6260                    // Ignore exceptions.
6261                }
6262            }
6263            return false;
6264        }
6265
6266        // If this application record is still attached to a previous
6267        // process, clean it up now.
6268        if (app.thread != null) {
6269            handleAppDiedLocked(app, true, true);
6270        }
6271
6272        // Tell the process all about itself.
6273
6274        if (DEBUG_ALL) Slog.v(
6275                TAG, "Binding process pid " + pid + " to record " + app);
6276
6277        final String processName = app.processName;
6278        try {
6279            AppDeathRecipient adr = new AppDeathRecipient(
6280                    app, pid, thread);
6281            thread.asBinder().linkToDeath(adr, 0);
6282            app.deathRecipient = adr;
6283        } catch (RemoteException e) {
6284            app.resetPackageList(mProcessStats);
6285            startProcessLocked(app, "link fail", processName);
6286            return false;
6287        }
6288
6289        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6290
6291        app.makeActive(thread, mProcessStats);
6292        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6293        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6294        app.forcingToForeground = null;
6295        updateProcessForegroundLocked(app, false, false);
6296        app.hasShownUi = false;
6297        app.debugging = false;
6298        app.cached = false;
6299        app.killedByAm = false;
6300        app.unlocked = mContext.getSystemService(UserManager.class).isUserUnlocked(app.userId);
6301
6302        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6303
6304        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6305        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6306
6307        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6308            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6309            msg.obj = app;
6310            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6311        }
6312
6313        if (!normalMode) {
6314            Slog.i(TAG, "Launching preboot mode app: " + app);
6315        }
6316
6317        if (DEBUG_ALL) Slog.v(
6318            TAG, "New app record " + app
6319            + " thread=" + thread.asBinder() + " pid=" + pid);
6320        try {
6321            int testMode = IApplicationThread.DEBUG_OFF;
6322            if (mDebugApp != null && mDebugApp.equals(processName)) {
6323                testMode = mWaitForDebugger
6324                    ? IApplicationThread.DEBUG_WAIT
6325                    : IApplicationThread.DEBUG_ON;
6326                app.debugging = true;
6327                if (mDebugTransient) {
6328                    mDebugApp = mOrigDebugApp;
6329                    mWaitForDebugger = mOrigWaitForDebugger;
6330                }
6331            }
6332            String profileFile = app.instrumentationProfileFile;
6333            ParcelFileDescriptor profileFd = null;
6334            int samplingInterval = 0;
6335            boolean profileAutoStop = false;
6336            if (mProfileApp != null && mProfileApp.equals(processName)) {
6337                mProfileProc = app;
6338                profileFile = mProfileFile;
6339                profileFd = mProfileFd;
6340                samplingInterval = mSamplingInterval;
6341                profileAutoStop = mAutoStopProfiler;
6342            }
6343            boolean enableTrackAllocation = false;
6344            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6345                enableTrackAllocation = true;
6346                mTrackAllocationApp = null;
6347            }
6348
6349            // If the app is being launched for restore or full backup, set it up specially
6350            boolean isRestrictedBackupMode = false;
6351            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6352                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6353                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6354                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6355                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6356            }
6357
6358            notifyPackageUse(app.instrumentationInfo != null
6359                    ? app.instrumentationInfo.packageName
6360                    : app.info.packageName);
6361            if (app.instrumentationClass != null) {
6362                notifyPackageUse(app.instrumentationClass.getPackageName());
6363            }
6364            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6365                    + processName + " with config " + mConfiguration);
6366            ApplicationInfo appInfo = app.instrumentationInfo != null
6367                    ? app.instrumentationInfo : app.info;
6368            app.compat = compatibilityInfoForPackageLocked(appInfo);
6369            if (profileFd != null) {
6370                profileFd = profileFd.dup();
6371            }
6372            ProfilerInfo profilerInfo = profileFile == null ? null
6373                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6374            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6375                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6376                    app.instrumentationUiAutomationConnection, testMode,
6377                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6378                    isRestrictedBackupMode || !normalMode, app.persistent,
6379                    new Configuration(mConfiguration), app.compat,
6380                    getCommonServicesLocked(app.isolated),
6381                    mCoreSettingsObserver.getCoreSettingsLocked());
6382            updateLruProcessLocked(app, false, null);
6383            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6384        } catch (Exception e) {
6385            // todo: Yikes!  What should we do?  For now we will try to
6386            // start another process, but that could easily get us in
6387            // an infinite loop of restarting processes...
6388            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6389
6390            app.resetPackageList(mProcessStats);
6391            app.unlinkDeathRecipient();
6392            startProcessLocked(app, "bind fail", processName);
6393            return false;
6394        }
6395
6396        // Remove this record from the list of starting applications.
6397        mPersistentStartingProcesses.remove(app);
6398        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6399                "Attach application locked removing on hold: " + app);
6400        mProcessesOnHold.remove(app);
6401
6402        boolean badApp = false;
6403        boolean didSomething = false;
6404
6405        // See if the top visible activity is waiting to run in this process...
6406        if (normalMode) {
6407            try {
6408                if (mStackSupervisor.attachApplicationLocked(app)) {
6409                    didSomething = true;
6410                }
6411            } catch (Exception e) {
6412                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6413                badApp = true;
6414            }
6415        }
6416
6417        // Find any services that should be running in this process...
6418        if (!badApp) {
6419            try {
6420                didSomething |= mServices.attachApplicationLocked(app, processName);
6421            } catch (Exception e) {
6422                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6423                badApp = true;
6424            }
6425        }
6426
6427        // Check if a next-broadcast receiver is in this process...
6428        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6429            try {
6430                didSomething |= sendPendingBroadcastsLocked(app);
6431            } catch (Exception e) {
6432                // If the app died trying to launch the receiver we declare it 'bad'
6433                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6434                badApp = true;
6435            }
6436        }
6437
6438        // Check whether the next backup agent is in this process...
6439        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6440            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6441                    "New app is backup target, launching agent for " + app);
6442            notifyPackageUse(mBackupTarget.appInfo.packageName);
6443            try {
6444                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6445                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6446                        mBackupTarget.backupMode);
6447            } catch (Exception e) {
6448                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6449                badApp = true;
6450            }
6451        }
6452
6453        if (badApp) {
6454            app.kill("error during init", true);
6455            handleAppDiedLocked(app, false, true);
6456            return false;
6457        }
6458
6459        if (!didSomething) {
6460            updateOomAdjLocked();
6461        }
6462
6463        return true;
6464    }
6465
6466    @Override
6467    public final void attachApplication(IApplicationThread thread) {
6468        synchronized (this) {
6469            int callingPid = Binder.getCallingPid();
6470            final long origId = Binder.clearCallingIdentity();
6471            attachApplicationLocked(thread, callingPid);
6472            Binder.restoreCallingIdentity(origId);
6473        }
6474    }
6475
6476    @Override
6477    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6478        final long origId = Binder.clearCallingIdentity();
6479        synchronized (this) {
6480            ActivityStack stack = ActivityRecord.getStackLocked(token);
6481            if (stack != null) {
6482                ActivityRecord r =
6483                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6484                if (stopProfiling) {
6485                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6486                        try {
6487                            mProfileFd.close();
6488                        } catch (IOException e) {
6489                        }
6490                        clearProfilerLocked();
6491                    }
6492                }
6493            }
6494        }
6495        Binder.restoreCallingIdentity(origId);
6496    }
6497
6498    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6499        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6500                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6501    }
6502
6503    void enableScreenAfterBoot() {
6504        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6505                SystemClock.uptimeMillis());
6506        mWindowManager.enableScreenAfterBoot();
6507
6508        synchronized (this) {
6509            updateEventDispatchingLocked();
6510        }
6511    }
6512
6513    @Override
6514    public void showBootMessage(final CharSequence msg, final boolean always) {
6515        if (Binder.getCallingUid() != Process.myUid()) {
6516            // These days only the core system can call this, so apps can't get in
6517            // the way of what we show about running them.
6518        }
6519        mWindowManager.showBootMessage(msg, always);
6520    }
6521
6522    @Override
6523    public void keyguardWaitingForActivityDrawn() {
6524        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6525        final long token = Binder.clearCallingIdentity();
6526        try {
6527            synchronized (this) {
6528                if (DEBUG_LOCKSCREEN) logLockScreen("");
6529                mWindowManager.keyguardWaitingForActivityDrawn();
6530                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6531                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6532                    updateSleepIfNeededLocked();
6533                }
6534            }
6535        } finally {
6536            Binder.restoreCallingIdentity(token);
6537        }
6538    }
6539
6540    @Override
6541    public void keyguardGoingAway(int flags) {
6542        enforceNotIsolatedCaller("keyguardGoingAway");
6543        final long token = Binder.clearCallingIdentity();
6544        try {
6545            synchronized (this) {
6546                if (DEBUG_LOCKSCREEN) logLockScreen("");
6547                mWindowManager.keyguardGoingAway(flags);
6548                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6549                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6550                    updateSleepIfNeededLocked();
6551
6552                    // Some stack visibility might change (e.g. docked stack)
6553                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6554                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6555                }
6556            }
6557        } finally {
6558            Binder.restoreCallingIdentity(token);
6559        }
6560    }
6561
6562    final void finishBooting() {
6563        synchronized (this) {
6564            if (!mBootAnimationComplete) {
6565                mCallFinishBooting = true;
6566                return;
6567            }
6568            mCallFinishBooting = false;
6569        }
6570
6571        ArraySet<String> completedIsas = new ArraySet<String>();
6572        for (String abi : Build.SUPPORTED_ABIS) {
6573            Process.establishZygoteConnectionForAbi(abi);
6574            final String instructionSet = VMRuntime.getInstructionSet(abi);
6575            if (!completedIsas.contains(instructionSet)) {
6576                try {
6577                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6578                } catch (InstallerException e) {
6579                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6580                }
6581                completedIsas.add(instructionSet);
6582            }
6583        }
6584
6585        IntentFilter pkgFilter = new IntentFilter();
6586        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6587        pkgFilter.addDataScheme("package");
6588        mContext.registerReceiver(new BroadcastReceiver() {
6589            @Override
6590            public void onReceive(Context context, Intent intent) {
6591                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6592                if (pkgs != null) {
6593                    for (String pkg : pkgs) {
6594                        synchronized (ActivityManagerService.this) {
6595                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6596                                    0, "query restart")) {
6597                                setResultCode(Activity.RESULT_OK);
6598                                return;
6599                            }
6600                        }
6601                    }
6602                }
6603            }
6604        }, pkgFilter);
6605
6606        IntentFilter dumpheapFilter = new IntentFilter();
6607        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6608        mContext.registerReceiver(new BroadcastReceiver() {
6609            @Override
6610            public void onReceive(Context context, Intent intent) {
6611                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6612                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6613                } else {
6614                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6615                }
6616            }
6617        }, dumpheapFilter);
6618
6619        // Let system services know.
6620        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6621
6622        synchronized (this) {
6623            // Ensure that any processes we had put on hold are now started
6624            // up.
6625            final int NP = mProcessesOnHold.size();
6626            if (NP > 0) {
6627                ArrayList<ProcessRecord> procs =
6628                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6629                for (int ip=0; ip<NP; ip++) {
6630                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6631                            + procs.get(ip));
6632                    startProcessLocked(procs.get(ip), "on-hold", null);
6633                }
6634            }
6635
6636            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6637                // Start looking for apps that are abusing wake locks.
6638                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6639                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6640                // Tell anyone interested that we are done booting!
6641                SystemProperties.set("sys.boot_completed", "1");
6642
6643                // And trigger dev.bootcomplete if we are not showing encryption progress
6644                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6645                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6646                    SystemProperties.set("dev.bootcomplete", "1");
6647                }
6648                mUserController.sendBootCompletedLocked(
6649                        new IIntentReceiver.Stub() {
6650                            @Override
6651                            public void performReceive(Intent intent, int resultCode,
6652                                    String data, Bundle extras, boolean ordered,
6653                                    boolean sticky, int sendingUser) {
6654                                synchronized (ActivityManagerService.this) {
6655                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6656                                            true, false);
6657                                }
6658                            }
6659                        });
6660                scheduleStartProfilesLocked();
6661            }
6662        }
6663    }
6664
6665    @Override
6666    public void bootAnimationComplete() {
6667        final boolean callFinishBooting;
6668        synchronized (this) {
6669            callFinishBooting = mCallFinishBooting;
6670            mBootAnimationComplete = true;
6671        }
6672        if (callFinishBooting) {
6673            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6674            finishBooting();
6675            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6676        }
6677    }
6678
6679    final void ensureBootCompleted() {
6680        boolean booting;
6681        boolean enableScreen;
6682        synchronized (this) {
6683            booting = mBooting;
6684            mBooting = false;
6685            enableScreen = !mBooted;
6686            mBooted = true;
6687        }
6688
6689        if (booting) {
6690            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6691            finishBooting();
6692            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6693        }
6694
6695        if (enableScreen) {
6696            enableScreenAfterBoot();
6697        }
6698    }
6699
6700    @Override
6701    public final void activityResumed(IBinder token) {
6702        final long origId = Binder.clearCallingIdentity();
6703        synchronized(this) {
6704            ActivityStack stack = ActivityRecord.getStackLocked(token);
6705            if (stack != null) {
6706                stack.activityResumedLocked(token);
6707            }
6708        }
6709        Binder.restoreCallingIdentity(origId);
6710    }
6711
6712    @Override
6713    public final void activityPaused(IBinder token) {
6714        final long origId = Binder.clearCallingIdentity();
6715        synchronized(this) {
6716            ActivityStack stack = ActivityRecord.getStackLocked(token);
6717            if (stack != null) {
6718                stack.activityPausedLocked(token, false);
6719            }
6720        }
6721        Binder.restoreCallingIdentity(origId);
6722    }
6723
6724    @Override
6725    public final void activityStopped(IBinder token, Bundle icicle,
6726            PersistableBundle persistentState, CharSequence description) {
6727        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6728
6729        // Refuse possible leaked file descriptors
6730        if (icicle != null && icicle.hasFileDescriptors()) {
6731            throw new IllegalArgumentException("File descriptors passed in Bundle");
6732        }
6733
6734        final long origId = Binder.clearCallingIdentity();
6735
6736        synchronized (this) {
6737            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6738            if (r != null) {
6739                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6740            }
6741        }
6742
6743        trimApplications();
6744
6745        Binder.restoreCallingIdentity(origId);
6746    }
6747
6748    @Override
6749    public final void activityDestroyed(IBinder token) {
6750        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6751        synchronized (this) {
6752            ActivityStack stack = ActivityRecord.getStackLocked(token);
6753            if (stack != null) {
6754                stack.activityDestroyedLocked(token, "activityDestroyed");
6755            }
6756        }
6757    }
6758
6759    @Override
6760    public final void activityRelaunched(IBinder token) {
6761        final long origId = Binder.clearCallingIdentity();
6762        synchronized (this) {
6763            mStackSupervisor.activityRelaunchedLocked(token);
6764        }
6765        Binder.restoreCallingIdentity(origId);
6766    }
6767
6768    @Override
6769    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6770            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6771        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6772                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6773        synchronized (this) {
6774            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6775            if (record == null) {
6776                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6777                        + "found for: " + token);
6778            }
6779            record.setSizeConfigurations(horizontalSizeConfiguration,
6780                    verticalSizeConfigurations, smallestSizeConfigurations);
6781        }
6782    }
6783
6784    @Override
6785    public final void backgroundResourcesReleased(IBinder token) {
6786        final long origId = Binder.clearCallingIdentity();
6787        try {
6788            synchronized (this) {
6789                ActivityStack stack = ActivityRecord.getStackLocked(token);
6790                if (stack != null) {
6791                    stack.backgroundResourcesReleased();
6792                }
6793            }
6794        } finally {
6795            Binder.restoreCallingIdentity(origId);
6796        }
6797    }
6798
6799    @Override
6800    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6801        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6802    }
6803
6804    @Override
6805    public final void notifyEnterAnimationComplete(IBinder token) {
6806        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6807    }
6808
6809    @Override
6810    public String getCallingPackage(IBinder token) {
6811        synchronized (this) {
6812            ActivityRecord r = getCallingRecordLocked(token);
6813            return r != null ? r.info.packageName : null;
6814        }
6815    }
6816
6817    @Override
6818    public ComponentName getCallingActivity(IBinder token) {
6819        synchronized (this) {
6820            ActivityRecord r = getCallingRecordLocked(token);
6821            return r != null ? r.intent.getComponent() : null;
6822        }
6823    }
6824
6825    private ActivityRecord getCallingRecordLocked(IBinder token) {
6826        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6827        if (r == null) {
6828            return null;
6829        }
6830        return r.resultTo;
6831    }
6832
6833    @Override
6834    public ComponentName getActivityClassForToken(IBinder token) {
6835        synchronized(this) {
6836            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6837            if (r == null) {
6838                return null;
6839            }
6840            return r.intent.getComponent();
6841        }
6842    }
6843
6844    @Override
6845    public String getPackageForToken(IBinder token) {
6846        synchronized(this) {
6847            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6848            if (r == null) {
6849                return null;
6850            }
6851            return r.packageName;
6852        }
6853    }
6854
6855    @Override
6856    public boolean isRootVoiceInteraction(IBinder token) {
6857        synchronized(this) {
6858            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6859            if (r == null) {
6860                return false;
6861            }
6862            return r.rootVoiceInteraction;
6863        }
6864    }
6865
6866    @Override
6867    public IIntentSender getIntentSender(int type,
6868            String packageName, IBinder token, String resultWho,
6869            int requestCode, Intent[] intents, String[] resolvedTypes,
6870            int flags, Bundle bOptions, int userId) {
6871        enforceNotIsolatedCaller("getIntentSender");
6872        // Refuse possible leaked file descriptors
6873        if (intents != null) {
6874            if (intents.length < 1) {
6875                throw new IllegalArgumentException("Intents array length must be >= 1");
6876            }
6877            for (int i=0; i<intents.length; i++) {
6878                Intent intent = intents[i];
6879                if (intent != null) {
6880                    if (intent.hasFileDescriptors()) {
6881                        throw new IllegalArgumentException("File descriptors passed in Intent");
6882                    }
6883                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6884                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6885                        throw new IllegalArgumentException(
6886                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6887                    }
6888                    intents[i] = new Intent(intent);
6889                }
6890            }
6891            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6892                throw new IllegalArgumentException(
6893                        "Intent array length does not match resolvedTypes length");
6894            }
6895        }
6896        if (bOptions != null) {
6897            if (bOptions.hasFileDescriptors()) {
6898                throw new IllegalArgumentException("File descriptors passed in options");
6899            }
6900        }
6901
6902        synchronized(this) {
6903            int callingUid = Binder.getCallingUid();
6904            int origUserId = userId;
6905            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6906                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6907                    ALLOW_NON_FULL, "getIntentSender", null);
6908            if (origUserId == UserHandle.USER_CURRENT) {
6909                // We don't want to evaluate this until the pending intent is
6910                // actually executed.  However, we do want to always do the
6911                // security checking for it above.
6912                userId = UserHandle.USER_CURRENT;
6913            }
6914            try {
6915                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6916                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6917                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6918                    if (!UserHandle.isSameApp(callingUid, uid)) {
6919                        String msg = "Permission Denial: getIntentSender() from pid="
6920                            + Binder.getCallingPid()
6921                            + ", uid=" + Binder.getCallingUid()
6922                            + ", (need uid=" + uid + ")"
6923                            + " is not allowed to send as package " + packageName;
6924                        Slog.w(TAG, msg);
6925                        throw new SecurityException(msg);
6926                    }
6927                }
6928
6929                return getIntentSenderLocked(type, packageName, callingUid, userId,
6930                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6931
6932            } catch (RemoteException e) {
6933                throw new SecurityException(e);
6934            }
6935        }
6936    }
6937
6938    IIntentSender getIntentSenderLocked(int type, String packageName,
6939            int callingUid, int userId, IBinder token, String resultWho,
6940            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6941            Bundle bOptions) {
6942        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6943        ActivityRecord activity = null;
6944        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6945            activity = ActivityRecord.isInStackLocked(token);
6946            if (activity == null) {
6947                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6948                return null;
6949            }
6950            if (activity.finishing) {
6951                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6952                return null;
6953            }
6954        }
6955
6956        // We're going to be splicing together extras before sending, so we're
6957        // okay poking into any contained extras.
6958        if (intents != null) {
6959            for (int i = 0; i < intents.length; i++) {
6960                intents[i].setDefusable(true);
6961            }
6962        }
6963        Bundle.setDefusable(bOptions, true);
6964
6965        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6966        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6967        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6968        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6969                |PendingIntent.FLAG_UPDATE_CURRENT);
6970
6971        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6972                type, packageName, activity, resultWho,
6973                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6974        WeakReference<PendingIntentRecord> ref;
6975        ref = mIntentSenderRecords.get(key);
6976        PendingIntentRecord rec = ref != null ? ref.get() : null;
6977        if (rec != null) {
6978            if (!cancelCurrent) {
6979                if (updateCurrent) {
6980                    if (rec.key.requestIntent != null) {
6981                        rec.key.requestIntent.replaceExtras(intents != null ?
6982                                intents[intents.length - 1] : null);
6983                    }
6984                    if (intents != null) {
6985                        intents[intents.length-1] = rec.key.requestIntent;
6986                        rec.key.allIntents = intents;
6987                        rec.key.allResolvedTypes = resolvedTypes;
6988                    } else {
6989                        rec.key.allIntents = null;
6990                        rec.key.allResolvedTypes = null;
6991                    }
6992                }
6993                return rec;
6994            }
6995            rec.canceled = true;
6996            mIntentSenderRecords.remove(key);
6997        }
6998        if (noCreate) {
6999            return rec;
7000        }
7001        rec = new PendingIntentRecord(this, key, callingUid);
7002        mIntentSenderRecords.put(key, rec.ref);
7003        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7004            if (activity.pendingResults == null) {
7005                activity.pendingResults
7006                        = new HashSet<WeakReference<PendingIntentRecord>>();
7007            }
7008            activity.pendingResults.add(rec.ref);
7009        }
7010        return rec;
7011    }
7012
7013    @Override
7014    public void cancelIntentSender(IIntentSender sender) {
7015        if (!(sender instanceof PendingIntentRecord)) {
7016            return;
7017        }
7018        synchronized(this) {
7019            PendingIntentRecord rec = (PendingIntentRecord)sender;
7020            try {
7021                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7022                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7023                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7024                    String msg = "Permission Denial: cancelIntentSender() from pid="
7025                        + Binder.getCallingPid()
7026                        + ", uid=" + Binder.getCallingUid()
7027                        + " is not allowed to cancel packges "
7028                        + rec.key.packageName;
7029                    Slog.w(TAG, msg);
7030                    throw new SecurityException(msg);
7031                }
7032            } catch (RemoteException e) {
7033                throw new SecurityException(e);
7034            }
7035            cancelIntentSenderLocked(rec, true);
7036        }
7037    }
7038
7039    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7040        rec.canceled = true;
7041        mIntentSenderRecords.remove(rec.key);
7042        if (cleanActivity && rec.key.activity != null) {
7043            rec.key.activity.pendingResults.remove(rec.ref);
7044        }
7045    }
7046
7047    @Override
7048    public String getPackageForIntentSender(IIntentSender pendingResult) {
7049        if (!(pendingResult instanceof PendingIntentRecord)) {
7050            return null;
7051        }
7052        try {
7053            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7054            return res.key.packageName;
7055        } catch (ClassCastException e) {
7056        }
7057        return null;
7058    }
7059
7060    @Override
7061    public int getUidForIntentSender(IIntentSender sender) {
7062        if (sender instanceof PendingIntentRecord) {
7063            try {
7064                PendingIntentRecord res = (PendingIntentRecord)sender;
7065                return res.uid;
7066            } catch (ClassCastException e) {
7067            }
7068        }
7069        return -1;
7070    }
7071
7072    @Override
7073    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7074        if (!(pendingResult instanceof PendingIntentRecord)) {
7075            return false;
7076        }
7077        try {
7078            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7079            if (res.key.allIntents == null) {
7080                return false;
7081            }
7082            for (int i=0; i<res.key.allIntents.length; i++) {
7083                Intent intent = res.key.allIntents[i];
7084                if (intent.getPackage() != null && intent.getComponent() != null) {
7085                    return false;
7086                }
7087            }
7088            return true;
7089        } catch (ClassCastException e) {
7090        }
7091        return false;
7092    }
7093
7094    @Override
7095    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7096        if (!(pendingResult instanceof PendingIntentRecord)) {
7097            return false;
7098        }
7099        try {
7100            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7101            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7102                return true;
7103            }
7104            return false;
7105        } catch (ClassCastException e) {
7106        }
7107        return false;
7108    }
7109
7110    @Override
7111    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7112        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7113                "getIntentForIntentSender()");
7114        if (!(pendingResult instanceof PendingIntentRecord)) {
7115            return null;
7116        }
7117        try {
7118            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7119            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7120        } catch (ClassCastException e) {
7121        }
7122        return null;
7123    }
7124
7125    @Override
7126    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7127        if (!(pendingResult instanceof PendingIntentRecord)) {
7128            return null;
7129        }
7130        try {
7131            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7132            synchronized (this) {
7133                return getTagForIntentSenderLocked(res, prefix);
7134            }
7135        } catch (ClassCastException e) {
7136        }
7137        return null;
7138    }
7139
7140    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7141        final Intent intent = res.key.requestIntent;
7142        if (intent != null) {
7143            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7144                    || res.lastTagPrefix.equals(prefix))) {
7145                return res.lastTag;
7146            }
7147            res.lastTagPrefix = prefix;
7148            final StringBuilder sb = new StringBuilder(128);
7149            if (prefix != null) {
7150                sb.append(prefix);
7151            }
7152            if (intent.getAction() != null) {
7153                sb.append(intent.getAction());
7154            } else if (intent.getComponent() != null) {
7155                intent.getComponent().appendShortString(sb);
7156            } else {
7157                sb.append("?");
7158            }
7159            return res.lastTag = sb.toString();
7160        }
7161        return null;
7162    }
7163
7164    @Override
7165    public void setProcessLimit(int max) {
7166        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7167                "setProcessLimit()");
7168        synchronized (this) {
7169            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7170            mProcessLimitOverride = max;
7171        }
7172        trimApplications();
7173    }
7174
7175    @Override
7176    public int getProcessLimit() {
7177        synchronized (this) {
7178            return mProcessLimitOverride;
7179        }
7180    }
7181
7182    void foregroundTokenDied(ForegroundToken token) {
7183        synchronized (ActivityManagerService.this) {
7184            synchronized (mPidsSelfLocked) {
7185                ForegroundToken cur
7186                    = mForegroundProcesses.get(token.pid);
7187                if (cur != token) {
7188                    return;
7189                }
7190                mForegroundProcesses.remove(token.pid);
7191                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7192                if (pr == null) {
7193                    return;
7194                }
7195                pr.forcingToForeground = null;
7196                updateProcessForegroundLocked(pr, false, false);
7197            }
7198            updateOomAdjLocked();
7199        }
7200    }
7201
7202    @Override
7203    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7204        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7205                "setProcessForeground()");
7206        synchronized(this) {
7207            boolean changed = false;
7208
7209            synchronized (mPidsSelfLocked) {
7210                ProcessRecord pr = mPidsSelfLocked.get(pid);
7211                if (pr == null && isForeground) {
7212                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7213                    return;
7214                }
7215                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7216                if (oldToken != null) {
7217                    oldToken.token.unlinkToDeath(oldToken, 0);
7218                    mForegroundProcesses.remove(pid);
7219                    if (pr != null) {
7220                        pr.forcingToForeground = null;
7221                    }
7222                    changed = true;
7223                }
7224                if (isForeground && token != null) {
7225                    ForegroundToken newToken = new ForegroundToken() {
7226                        @Override
7227                        public void binderDied() {
7228                            foregroundTokenDied(this);
7229                        }
7230                    };
7231                    newToken.pid = pid;
7232                    newToken.token = token;
7233                    try {
7234                        token.linkToDeath(newToken, 0);
7235                        mForegroundProcesses.put(pid, newToken);
7236                        pr.forcingToForeground = token;
7237                        changed = true;
7238                    } catch (RemoteException e) {
7239                        // If the process died while doing this, we will later
7240                        // do the cleanup with the process death link.
7241                    }
7242                }
7243            }
7244
7245            if (changed) {
7246                updateOomAdjLocked();
7247            }
7248        }
7249    }
7250
7251    @Override
7252    public boolean isAppForeground(int uid) throws RemoteException {
7253        synchronized (this) {
7254            UidRecord uidRec = mActiveUids.get(uid);
7255            if (uidRec == null || uidRec.idle) {
7256                return false;
7257            }
7258            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7259        }
7260    }
7261
7262    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7263    // be guarded by permission checking.
7264    int getUidState(int uid) {
7265        synchronized (this) {
7266            UidRecord uidRec = mActiveUids.get(uid);
7267            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7268        }
7269    }
7270
7271    @Override
7272    public boolean isInMultiWindowMode(IBinder token) {
7273        final long origId = Binder.clearCallingIdentity();
7274        try {
7275            synchronized(this) {
7276                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7277                if (r == null) {
7278                    return false;
7279                }
7280                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7281                return !r.task.mFullscreen;
7282            }
7283        } finally {
7284            Binder.restoreCallingIdentity(origId);
7285        }
7286    }
7287
7288    @Override
7289    public boolean isInPictureInPictureMode(IBinder token) {
7290        final long origId = Binder.clearCallingIdentity();
7291        try {
7292            synchronized(this) {
7293                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7294                if (stack == null) {
7295                    return false;
7296                }
7297                return stack.mStackId == PINNED_STACK_ID;
7298            }
7299        } finally {
7300            Binder.restoreCallingIdentity(origId);
7301        }
7302    }
7303
7304    @Override
7305    public void enterPictureInPictureMode(IBinder token) {
7306        final long origId = Binder.clearCallingIdentity();
7307        try {
7308            synchronized(this) {
7309                if (!mSupportsPictureInPicture) {
7310                    throw new IllegalStateException("enterPictureInPictureMode: "
7311                            + "Device doesn't support picture-in-picture mode.");
7312                }
7313
7314                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7315
7316                if (r == null) {
7317                    throw new IllegalStateException("enterPictureInPictureMode: "
7318                            + "Can't find activity for token=" + token);
7319                }
7320
7321                if (!r.supportsPictureInPicture()) {
7322                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7323                            + "Picture-In-Picture not supported for r=" + r);
7324                }
7325
7326                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7327                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7328                        ? mDefaultPinnedStackBounds : null;
7329
7330                mStackSupervisor.moveActivityToPinnedStackLocked(
7331                        r, "enterPictureInPictureMode", bounds);
7332            }
7333        } finally {
7334            Binder.restoreCallingIdentity(origId);
7335        }
7336    }
7337
7338    // =========================================================
7339    // PROCESS INFO
7340    // =========================================================
7341
7342    static class ProcessInfoService extends IProcessInfoService.Stub {
7343        final ActivityManagerService mActivityManagerService;
7344        ProcessInfoService(ActivityManagerService activityManagerService) {
7345            mActivityManagerService = activityManagerService;
7346        }
7347
7348        @Override
7349        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7350            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7351                    /*in*/ pids, /*out*/ states, null);
7352        }
7353
7354        @Override
7355        public void getProcessStatesAndOomScoresFromPids(
7356                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7357            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7358                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7359        }
7360    }
7361
7362    /**
7363     * For each PID in the given input array, write the current process state
7364     * for that process into the states array, or -1 to indicate that no
7365     * process with the given PID exists. If scores array is provided, write
7366     * the oom score for the process into the scores array, with INVALID_ADJ
7367     * indicating the PID doesn't exist.
7368     */
7369    public void getProcessStatesAndOomScoresForPIDs(
7370            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7371        if (scores != null) {
7372            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7373                    "getProcessStatesAndOomScoresForPIDs()");
7374        }
7375
7376        if (pids == null) {
7377            throw new NullPointerException("pids");
7378        } else if (states == null) {
7379            throw new NullPointerException("states");
7380        } else if (pids.length != states.length) {
7381            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7382        } else if (scores != null && pids.length != scores.length) {
7383            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7384        }
7385
7386        synchronized (mPidsSelfLocked) {
7387            for (int i = 0; i < pids.length; i++) {
7388                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7389                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7390                        pr.curProcState;
7391                if (scores != null) {
7392                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7393                }
7394            }
7395        }
7396    }
7397
7398    // =========================================================
7399    // PERMISSIONS
7400    // =========================================================
7401
7402    static class PermissionController extends IPermissionController.Stub {
7403        ActivityManagerService mActivityManagerService;
7404        PermissionController(ActivityManagerService activityManagerService) {
7405            mActivityManagerService = activityManagerService;
7406        }
7407
7408        @Override
7409        public boolean checkPermission(String permission, int pid, int uid) {
7410            return mActivityManagerService.checkPermission(permission, pid,
7411                    uid) == PackageManager.PERMISSION_GRANTED;
7412        }
7413
7414        @Override
7415        public String[] getPackagesForUid(int uid) {
7416            return mActivityManagerService.mContext.getPackageManager()
7417                    .getPackagesForUid(uid);
7418        }
7419
7420        @Override
7421        public boolean isRuntimePermission(String permission) {
7422            try {
7423                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7424                        .getPermissionInfo(permission, 0);
7425                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7426            } catch (NameNotFoundException nnfe) {
7427                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7428            }
7429            return false;
7430        }
7431    }
7432
7433    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7434        @Override
7435        public int checkComponentPermission(String permission, int pid, int uid,
7436                int owningUid, boolean exported) {
7437            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7438                    owningUid, exported);
7439        }
7440
7441        @Override
7442        public Object getAMSLock() {
7443            return ActivityManagerService.this;
7444        }
7445    }
7446
7447    /**
7448     * This can be called with or without the global lock held.
7449     */
7450    int checkComponentPermission(String permission, int pid, int uid,
7451            int owningUid, boolean exported) {
7452        if (pid == MY_PID) {
7453            return PackageManager.PERMISSION_GRANTED;
7454        }
7455        return ActivityManager.checkComponentPermission(permission, uid,
7456                owningUid, exported);
7457    }
7458
7459    /**
7460     * As the only public entry point for permissions checking, this method
7461     * can enforce the semantic that requesting a check on a null global
7462     * permission is automatically denied.  (Internally a null permission
7463     * string is used when calling {@link #checkComponentPermission} in cases
7464     * when only uid-based security is needed.)
7465     *
7466     * This can be called with or without the global lock held.
7467     */
7468    @Override
7469    public int checkPermission(String permission, int pid, int uid) {
7470        if (permission == null) {
7471            return PackageManager.PERMISSION_DENIED;
7472        }
7473        return checkComponentPermission(permission, pid, uid, -1, true);
7474    }
7475
7476    @Override
7477    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7478        if (permission == null) {
7479            return PackageManager.PERMISSION_DENIED;
7480        }
7481
7482        // We might be performing an operation on behalf of an indirect binder
7483        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7484        // client identity accordingly before proceeding.
7485        Identity tlsIdentity = sCallerIdentity.get();
7486        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7487            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7488                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7489            uid = tlsIdentity.uid;
7490            pid = tlsIdentity.pid;
7491        }
7492
7493        return checkComponentPermission(permission, pid, uid, -1, true);
7494    }
7495
7496    /**
7497     * Binder IPC calls go through the public entry point.
7498     * This can be called with or without the global lock held.
7499     */
7500    int checkCallingPermission(String permission) {
7501        return checkPermission(permission,
7502                Binder.getCallingPid(),
7503                UserHandle.getAppId(Binder.getCallingUid()));
7504    }
7505
7506    /**
7507     * This can be called with or without the global lock held.
7508     */
7509    void enforceCallingPermission(String permission, String func) {
7510        if (checkCallingPermission(permission)
7511                == PackageManager.PERMISSION_GRANTED) {
7512            return;
7513        }
7514
7515        String msg = "Permission Denial: " + func + " from pid="
7516                + Binder.getCallingPid()
7517                + ", uid=" + Binder.getCallingUid()
7518                + " requires " + permission;
7519        Slog.w(TAG, msg);
7520        throw new SecurityException(msg);
7521    }
7522
7523    /**
7524     * Determine if UID is holding permissions required to access {@link Uri} in
7525     * the given {@link ProviderInfo}. Final permission checking is always done
7526     * in {@link ContentProvider}.
7527     */
7528    private final boolean checkHoldingPermissionsLocked(
7529            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7530        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7531                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7532        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7533            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7534                    != PERMISSION_GRANTED) {
7535                return false;
7536            }
7537        }
7538        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7539    }
7540
7541    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7542            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7543        if (pi.applicationInfo.uid == uid) {
7544            return true;
7545        } else if (!pi.exported) {
7546            return false;
7547        }
7548
7549        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7550        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7551        try {
7552            // check if target holds top-level <provider> permissions
7553            if (!readMet && pi.readPermission != null && considerUidPermissions
7554                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7555                readMet = true;
7556            }
7557            if (!writeMet && pi.writePermission != null && considerUidPermissions
7558                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7559                writeMet = true;
7560            }
7561
7562            // track if unprotected read/write is allowed; any denied
7563            // <path-permission> below removes this ability
7564            boolean allowDefaultRead = pi.readPermission == null;
7565            boolean allowDefaultWrite = pi.writePermission == null;
7566
7567            // check if target holds any <path-permission> that match uri
7568            final PathPermission[] pps = pi.pathPermissions;
7569            if (pps != null) {
7570                final String path = grantUri.uri.getPath();
7571                int i = pps.length;
7572                while (i > 0 && (!readMet || !writeMet)) {
7573                    i--;
7574                    PathPermission pp = pps[i];
7575                    if (pp.match(path)) {
7576                        if (!readMet) {
7577                            final String pprperm = pp.getReadPermission();
7578                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7579                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7580                                    + ": match=" + pp.match(path)
7581                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7582                            if (pprperm != null) {
7583                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7584                                        == PERMISSION_GRANTED) {
7585                                    readMet = true;
7586                                } else {
7587                                    allowDefaultRead = false;
7588                                }
7589                            }
7590                        }
7591                        if (!writeMet) {
7592                            final String ppwperm = pp.getWritePermission();
7593                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7594                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7595                                    + ": match=" + pp.match(path)
7596                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7597                            if (ppwperm != null) {
7598                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7599                                        == PERMISSION_GRANTED) {
7600                                    writeMet = true;
7601                                } else {
7602                                    allowDefaultWrite = false;
7603                                }
7604                            }
7605                        }
7606                    }
7607                }
7608            }
7609
7610            // grant unprotected <provider> read/write, if not blocked by
7611            // <path-permission> above
7612            if (allowDefaultRead) readMet = true;
7613            if (allowDefaultWrite) writeMet = true;
7614
7615        } catch (RemoteException e) {
7616            return false;
7617        }
7618
7619        return readMet && writeMet;
7620    }
7621
7622    public int getAppStartMode(int uid, String packageName) {
7623        synchronized (this) {
7624            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7625        }
7626    }
7627
7628    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7629            boolean allowWhenForeground) {
7630        UidRecord uidRec = mActiveUids.get(uid);
7631        if (!mLenientBackgroundCheck) {
7632            if (!allowWhenForeground || uidRec == null
7633                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7634                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7635                        packageName) != AppOpsManager.MODE_ALLOWED) {
7636                    return ActivityManager.APP_START_MODE_DELAYED;
7637                }
7638            }
7639
7640        } else if (uidRec == null || uidRec.idle) {
7641            if (callingPid >= 0) {
7642                ProcessRecord proc;
7643                synchronized (mPidsSelfLocked) {
7644                    proc = mPidsSelfLocked.get(callingPid);
7645                }
7646                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7647                    // Whoever is instigating this is in the foreground, so we will allow it
7648                    // to go through.
7649                    return ActivityManager.APP_START_MODE_NORMAL;
7650                }
7651            }
7652            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7653                    != AppOpsManager.MODE_ALLOWED) {
7654                return ActivityManager.APP_START_MODE_DELAYED;
7655            }
7656        }
7657        return ActivityManager.APP_START_MODE_NORMAL;
7658    }
7659
7660    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7661        ProviderInfo pi = null;
7662        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7663        if (cpr != null) {
7664            pi = cpr.info;
7665        } else {
7666            try {
7667                pi = AppGlobals.getPackageManager().resolveContentProvider(
7668                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7669            } catch (RemoteException ex) {
7670            }
7671        }
7672        return pi;
7673    }
7674
7675    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7676        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7677        if (targetUris != null) {
7678            return targetUris.get(grantUri);
7679        }
7680        return null;
7681    }
7682
7683    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7684            String targetPkg, int targetUid, GrantUri grantUri) {
7685        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7686        if (targetUris == null) {
7687            targetUris = Maps.newArrayMap();
7688            mGrantedUriPermissions.put(targetUid, targetUris);
7689        }
7690
7691        UriPermission perm = targetUris.get(grantUri);
7692        if (perm == null) {
7693            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7694            targetUris.put(grantUri, perm);
7695        }
7696
7697        return perm;
7698    }
7699
7700    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7701            final int modeFlags) {
7702        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7703        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7704                : UriPermission.STRENGTH_OWNED;
7705
7706        // Root gets to do everything.
7707        if (uid == 0) {
7708            return true;
7709        }
7710
7711        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7712        if (perms == null) return false;
7713
7714        // First look for exact match
7715        final UriPermission exactPerm = perms.get(grantUri);
7716        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7717            return true;
7718        }
7719
7720        // No exact match, look for prefixes
7721        final int N = perms.size();
7722        for (int i = 0; i < N; i++) {
7723            final UriPermission perm = perms.valueAt(i);
7724            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7725                    && perm.getStrength(modeFlags) >= minStrength) {
7726                return true;
7727            }
7728        }
7729
7730        return false;
7731    }
7732
7733    /**
7734     * @param uri This uri must NOT contain an embedded userId.
7735     * @param userId The userId in which the uri is to be resolved.
7736     */
7737    @Override
7738    public int checkUriPermission(Uri uri, int pid, int uid,
7739            final int modeFlags, int userId, IBinder callerToken) {
7740        enforceNotIsolatedCaller("checkUriPermission");
7741
7742        // Another redirected-binder-call permissions check as in
7743        // {@link checkPermissionWithToken}.
7744        Identity tlsIdentity = sCallerIdentity.get();
7745        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7746            uid = tlsIdentity.uid;
7747            pid = tlsIdentity.pid;
7748        }
7749
7750        // Our own process gets to do everything.
7751        if (pid == MY_PID) {
7752            return PackageManager.PERMISSION_GRANTED;
7753        }
7754        synchronized (this) {
7755            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7756                    ? PackageManager.PERMISSION_GRANTED
7757                    : PackageManager.PERMISSION_DENIED;
7758        }
7759    }
7760
7761    /**
7762     * Check if the targetPkg can be granted permission to access uri by
7763     * the callingUid using the given modeFlags.  Throws a security exception
7764     * if callingUid is not allowed to do this.  Returns the uid of the target
7765     * if the URI permission grant should be performed; returns -1 if it is not
7766     * needed (for example targetPkg already has permission to access the URI).
7767     * If you already know the uid of the target, you can supply it in
7768     * lastTargetUid else set that to -1.
7769     */
7770    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7771            final int modeFlags, int lastTargetUid) {
7772        if (!Intent.isAccessUriMode(modeFlags)) {
7773            return -1;
7774        }
7775
7776        if (targetPkg != null) {
7777            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7778                    "Checking grant " + targetPkg + " permission to " + grantUri);
7779        }
7780
7781        final IPackageManager pm = AppGlobals.getPackageManager();
7782
7783        // If this is not a content: uri, we can't do anything with it.
7784        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7785            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7786                    "Can't grant URI permission for non-content URI: " + grantUri);
7787            return -1;
7788        }
7789
7790        final String authority = grantUri.uri.getAuthority();
7791        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7792        if (pi == null) {
7793            Slog.w(TAG, "No content provider found for permission check: " +
7794                    grantUri.uri.toSafeString());
7795            return -1;
7796        }
7797
7798        int targetUid = lastTargetUid;
7799        if (targetUid < 0 && targetPkg != null) {
7800            try {
7801                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7802                        UserHandle.getUserId(callingUid));
7803                if (targetUid < 0) {
7804                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7805                            "Can't grant URI permission no uid for: " + targetPkg);
7806                    return -1;
7807                }
7808            } catch (RemoteException ex) {
7809                return -1;
7810            }
7811        }
7812
7813        if (targetUid >= 0) {
7814            // First...  does the target actually need this permission?
7815            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7816                // No need to grant the target this permission.
7817                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7818                        "Target " + targetPkg + " already has full permission to " + grantUri);
7819                return -1;
7820            }
7821        } else {
7822            // First...  there is no target package, so can anyone access it?
7823            boolean allowed = pi.exported;
7824            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7825                if (pi.readPermission != null) {
7826                    allowed = false;
7827                }
7828            }
7829            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7830                if (pi.writePermission != null) {
7831                    allowed = false;
7832                }
7833            }
7834            if (allowed) {
7835                return -1;
7836            }
7837        }
7838
7839        /* There is a special cross user grant if:
7840         * - The target is on another user.
7841         * - Apps on the current user can access the uri without any uid permissions.
7842         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7843         * grant uri permissions.
7844         */
7845        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7846                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7847                modeFlags, false /*without considering the uid permissions*/);
7848
7849        // Second...  is the provider allowing granting of URI permissions?
7850        if (!specialCrossUserGrant) {
7851            if (!pi.grantUriPermissions) {
7852                throw new SecurityException("Provider " + pi.packageName
7853                        + "/" + pi.name
7854                        + " does not allow granting of Uri permissions (uri "
7855                        + grantUri + ")");
7856            }
7857            if (pi.uriPermissionPatterns != null) {
7858                final int N = pi.uriPermissionPatterns.length;
7859                boolean allowed = false;
7860                for (int i=0; i<N; i++) {
7861                    if (pi.uriPermissionPatterns[i] != null
7862                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7863                        allowed = true;
7864                        break;
7865                    }
7866                }
7867                if (!allowed) {
7868                    throw new SecurityException("Provider " + pi.packageName
7869                            + "/" + pi.name
7870                            + " does not allow granting of permission to path of Uri "
7871                            + grantUri);
7872                }
7873            }
7874        }
7875
7876        // Third...  does the caller itself have permission to access
7877        // this uri?
7878        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7879            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7880                // Require they hold a strong enough Uri permission
7881                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7882                    throw new SecurityException("Uid " + callingUid
7883                            + " does not have permission to uri " + grantUri);
7884                }
7885            }
7886        }
7887        return targetUid;
7888    }
7889
7890    /**
7891     * @param uri This uri must NOT contain an embedded userId.
7892     * @param userId The userId in which the uri is to be resolved.
7893     */
7894    @Override
7895    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7896            final int modeFlags, int userId) {
7897        enforceNotIsolatedCaller("checkGrantUriPermission");
7898        synchronized(this) {
7899            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7900                    new GrantUri(userId, uri, false), modeFlags, -1);
7901        }
7902    }
7903
7904    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7905            final int modeFlags, UriPermissionOwner owner) {
7906        if (!Intent.isAccessUriMode(modeFlags)) {
7907            return;
7908        }
7909
7910        // So here we are: the caller has the assumed permission
7911        // to the uri, and the target doesn't.  Let's now give this to
7912        // the target.
7913
7914        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7915                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7916
7917        final String authority = grantUri.uri.getAuthority();
7918        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7919        if (pi == null) {
7920            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7921            return;
7922        }
7923
7924        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7925            grantUri.prefix = true;
7926        }
7927        final UriPermission perm = findOrCreateUriPermissionLocked(
7928                pi.packageName, targetPkg, targetUid, grantUri);
7929        perm.grantModes(modeFlags, owner);
7930    }
7931
7932    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7933            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7934        if (targetPkg == null) {
7935            throw new NullPointerException("targetPkg");
7936        }
7937        int targetUid;
7938        final IPackageManager pm = AppGlobals.getPackageManager();
7939        try {
7940            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7941        } catch (RemoteException ex) {
7942            return;
7943        }
7944
7945        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7946                targetUid);
7947        if (targetUid < 0) {
7948            return;
7949        }
7950
7951        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7952                owner);
7953    }
7954
7955    static class NeededUriGrants extends ArrayList<GrantUri> {
7956        final String targetPkg;
7957        final int targetUid;
7958        final int flags;
7959
7960        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7961            this.targetPkg = targetPkg;
7962            this.targetUid = targetUid;
7963            this.flags = flags;
7964        }
7965    }
7966
7967    /**
7968     * Like checkGrantUriPermissionLocked, but takes an Intent.
7969     */
7970    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7971            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7972        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7973                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7974                + " clip=" + (intent != null ? intent.getClipData() : null)
7975                + " from " + intent + "; flags=0x"
7976                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7977
7978        if (targetPkg == null) {
7979            throw new NullPointerException("targetPkg");
7980        }
7981
7982        if (intent == null) {
7983            return null;
7984        }
7985        Uri data = intent.getData();
7986        ClipData clip = intent.getClipData();
7987        if (data == null && clip == null) {
7988            return null;
7989        }
7990        // Default userId for uris in the intent (if they don't specify it themselves)
7991        int contentUserHint = intent.getContentUserHint();
7992        if (contentUserHint == UserHandle.USER_CURRENT) {
7993            contentUserHint = UserHandle.getUserId(callingUid);
7994        }
7995        final IPackageManager pm = AppGlobals.getPackageManager();
7996        int targetUid;
7997        if (needed != null) {
7998            targetUid = needed.targetUid;
7999        } else {
8000            try {
8001                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8002                        targetUserId);
8003            } catch (RemoteException ex) {
8004                return null;
8005            }
8006            if (targetUid < 0) {
8007                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8008                        "Can't grant URI permission no uid for: " + targetPkg
8009                        + " on user " + targetUserId);
8010                return null;
8011            }
8012        }
8013        if (data != null) {
8014            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8015            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8016                    targetUid);
8017            if (targetUid > 0) {
8018                if (needed == null) {
8019                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8020                }
8021                needed.add(grantUri);
8022            }
8023        }
8024        if (clip != null) {
8025            for (int i=0; i<clip.getItemCount(); i++) {
8026                Uri uri = clip.getItemAt(i).getUri();
8027                if (uri != null) {
8028                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8029                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8030                            targetUid);
8031                    if (targetUid > 0) {
8032                        if (needed == null) {
8033                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8034                        }
8035                        needed.add(grantUri);
8036                    }
8037                } else {
8038                    Intent clipIntent = clip.getItemAt(i).getIntent();
8039                    if (clipIntent != null) {
8040                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8041                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8042                        if (newNeeded != null) {
8043                            needed = newNeeded;
8044                        }
8045                    }
8046                }
8047            }
8048        }
8049
8050        return needed;
8051    }
8052
8053    /**
8054     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8055     */
8056    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8057            UriPermissionOwner owner) {
8058        if (needed != null) {
8059            for (int i=0; i<needed.size(); i++) {
8060                GrantUri grantUri = needed.get(i);
8061                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8062                        grantUri, needed.flags, owner);
8063            }
8064        }
8065    }
8066
8067    void grantUriPermissionFromIntentLocked(int callingUid,
8068            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8069        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8070                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8071        if (needed == null) {
8072            return;
8073        }
8074
8075        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8076    }
8077
8078    /**
8079     * @param uri This uri must NOT contain an embedded userId.
8080     * @param userId The userId in which the uri is to be resolved.
8081     */
8082    @Override
8083    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8084            final int modeFlags, int userId) {
8085        enforceNotIsolatedCaller("grantUriPermission");
8086        GrantUri grantUri = new GrantUri(userId, uri, false);
8087        synchronized(this) {
8088            final ProcessRecord r = getRecordForAppLocked(caller);
8089            if (r == null) {
8090                throw new SecurityException("Unable to find app for caller "
8091                        + caller
8092                        + " when granting permission to uri " + grantUri);
8093            }
8094            if (targetPkg == null) {
8095                throw new IllegalArgumentException("null target");
8096            }
8097            if (grantUri == null) {
8098                throw new IllegalArgumentException("null uri");
8099            }
8100
8101            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8102                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8103                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8104                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8105
8106            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8107                    UserHandle.getUserId(r.uid));
8108        }
8109    }
8110
8111    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8112        if (perm.modeFlags == 0) {
8113            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8114                    perm.targetUid);
8115            if (perms != null) {
8116                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8117                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8118
8119                perms.remove(perm.uri);
8120                if (perms.isEmpty()) {
8121                    mGrantedUriPermissions.remove(perm.targetUid);
8122                }
8123            }
8124        }
8125    }
8126
8127    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8128        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8129                "Revoking all granted permissions to " + grantUri);
8130
8131        final IPackageManager pm = AppGlobals.getPackageManager();
8132        final String authority = grantUri.uri.getAuthority();
8133        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8134        if (pi == null) {
8135            Slog.w(TAG, "No content provider found for permission revoke: "
8136                    + grantUri.toSafeString());
8137            return;
8138        }
8139
8140        // Does the caller have this permission on the URI?
8141        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8142            // If they don't have direct access to the URI, then revoke any
8143            // ownerless URI permissions that have been granted to them.
8144            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8145            if (perms != null) {
8146                boolean persistChanged = false;
8147                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8148                    final UriPermission perm = it.next();
8149                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8150                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8151                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8152                                "Revoking non-owned " + perm.targetUid
8153                                + " permission to " + perm.uri);
8154                        persistChanged |= perm.revokeModes(
8155                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8156                        if (perm.modeFlags == 0) {
8157                            it.remove();
8158                        }
8159                    }
8160                }
8161                if (perms.isEmpty()) {
8162                    mGrantedUriPermissions.remove(callingUid);
8163                }
8164                if (persistChanged) {
8165                    schedulePersistUriGrants();
8166                }
8167            }
8168            return;
8169        }
8170
8171        boolean persistChanged = false;
8172
8173        // Go through all of the permissions and remove any that match.
8174        int N = mGrantedUriPermissions.size();
8175        for (int i = 0; i < N; i++) {
8176            final int targetUid = mGrantedUriPermissions.keyAt(i);
8177            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8178
8179            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8180                final UriPermission perm = it.next();
8181                if (perm.uri.sourceUserId == grantUri.sourceUserId
8182                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8183                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8184                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8185                    persistChanged |= perm.revokeModes(
8186                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8187                    if (perm.modeFlags == 0) {
8188                        it.remove();
8189                    }
8190                }
8191            }
8192
8193            if (perms.isEmpty()) {
8194                mGrantedUriPermissions.remove(targetUid);
8195                N--;
8196                i--;
8197            }
8198        }
8199
8200        if (persistChanged) {
8201            schedulePersistUriGrants();
8202        }
8203    }
8204
8205    /**
8206     * @param uri This uri must NOT contain an embedded userId.
8207     * @param userId The userId in which the uri is to be resolved.
8208     */
8209    @Override
8210    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8211            int userId) {
8212        enforceNotIsolatedCaller("revokeUriPermission");
8213        synchronized(this) {
8214            final ProcessRecord r = getRecordForAppLocked(caller);
8215            if (r == null) {
8216                throw new SecurityException("Unable to find app for caller "
8217                        + caller
8218                        + " when revoking permission to uri " + uri);
8219            }
8220            if (uri == null) {
8221                Slog.w(TAG, "revokeUriPermission: null uri");
8222                return;
8223            }
8224
8225            if (!Intent.isAccessUriMode(modeFlags)) {
8226                return;
8227            }
8228
8229            final String authority = uri.getAuthority();
8230            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8231            if (pi == null) {
8232                Slog.w(TAG, "No content provider found for permission revoke: "
8233                        + uri.toSafeString());
8234                return;
8235            }
8236
8237            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8238        }
8239    }
8240
8241    /**
8242     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8243     * given package.
8244     *
8245     * @param packageName Package name to match, or {@code null} to apply to all
8246     *            packages.
8247     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8248     *            to all users.
8249     * @param persistable If persistable grants should be removed.
8250     */
8251    private void removeUriPermissionsForPackageLocked(
8252            String packageName, int userHandle, boolean persistable) {
8253        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8254            throw new IllegalArgumentException("Must narrow by either package or user");
8255        }
8256
8257        boolean persistChanged = false;
8258
8259        int N = mGrantedUriPermissions.size();
8260        for (int i = 0; i < N; i++) {
8261            final int targetUid = mGrantedUriPermissions.keyAt(i);
8262            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8263
8264            // Only inspect grants matching user
8265            if (userHandle == UserHandle.USER_ALL
8266                    || userHandle == UserHandle.getUserId(targetUid)) {
8267                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8268                    final UriPermission perm = it.next();
8269
8270                    // Only inspect grants matching package
8271                    if (packageName == null || perm.sourcePkg.equals(packageName)
8272                            || perm.targetPkg.equals(packageName)) {
8273                        persistChanged |= perm.revokeModes(persistable
8274                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8275
8276                        // Only remove when no modes remain; any persisted grants
8277                        // will keep this alive.
8278                        if (perm.modeFlags == 0) {
8279                            it.remove();
8280                        }
8281                    }
8282                }
8283
8284                if (perms.isEmpty()) {
8285                    mGrantedUriPermissions.remove(targetUid);
8286                    N--;
8287                    i--;
8288                }
8289            }
8290        }
8291
8292        if (persistChanged) {
8293            schedulePersistUriGrants();
8294        }
8295    }
8296
8297    @Override
8298    public IBinder newUriPermissionOwner(String name) {
8299        enforceNotIsolatedCaller("newUriPermissionOwner");
8300        synchronized(this) {
8301            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8302            return owner.getExternalTokenLocked();
8303        }
8304    }
8305
8306    @Override
8307    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8308        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8309        synchronized(this) {
8310            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8311            if (r == null) {
8312                throw new IllegalArgumentException("Activity does not exist; token="
8313                        + activityToken);
8314            }
8315            return r.getUriPermissionsLocked().getExternalTokenLocked();
8316        }
8317    }
8318    /**
8319     * @param uri This uri must NOT contain an embedded userId.
8320     * @param sourceUserId The userId in which the uri is to be resolved.
8321     * @param targetUserId The userId of the app that receives the grant.
8322     */
8323    @Override
8324    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8325            final int modeFlags, int sourceUserId, int targetUserId) {
8326        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8327                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8328                "grantUriPermissionFromOwner", null);
8329        synchronized(this) {
8330            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8331            if (owner == null) {
8332                throw new IllegalArgumentException("Unknown owner: " + token);
8333            }
8334            if (fromUid != Binder.getCallingUid()) {
8335                if (Binder.getCallingUid() != Process.myUid()) {
8336                    // Only system code can grant URI permissions on behalf
8337                    // of other users.
8338                    throw new SecurityException("nice try");
8339                }
8340            }
8341            if (targetPkg == null) {
8342                throw new IllegalArgumentException("null target");
8343            }
8344            if (uri == null) {
8345                throw new IllegalArgumentException("null uri");
8346            }
8347
8348            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8349                    modeFlags, owner, targetUserId);
8350        }
8351    }
8352
8353    /**
8354     * @param uri This uri must NOT contain an embedded userId.
8355     * @param userId The userId in which the uri is to be resolved.
8356     */
8357    @Override
8358    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8359        synchronized(this) {
8360            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8361            if (owner == null) {
8362                throw new IllegalArgumentException("Unknown owner: " + token);
8363            }
8364
8365            if (uri == null) {
8366                owner.removeUriPermissionsLocked(mode);
8367            } else {
8368                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8369            }
8370        }
8371    }
8372
8373    private void schedulePersistUriGrants() {
8374        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8375            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8376                    10 * DateUtils.SECOND_IN_MILLIS);
8377        }
8378    }
8379
8380    private void writeGrantedUriPermissions() {
8381        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8382
8383        // Snapshot permissions so we can persist without lock
8384        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8385        synchronized (this) {
8386            final int size = mGrantedUriPermissions.size();
8387            for (int i = 0; i < size; i++) {
8388                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8389                for (UriPermission perm : perms.values()) {
8390                    if (perm.persistedModeFlags != 0) {
8391                        persist.add(perm.snapshot());
8392                    }
8393                }
8394            }
8395        }
8396
8397        FileOutputStream fos = null;
8398        try {
8399            fos = mGrantFile.startWrite();
8400
8401            XmlSerializer out = new FastXmlSerializer();
8402            out.setOutput(fos, StandardCharsets.UTF_8.name());
8403            out.startDocument(null, true);
8404            out.startTag(null, TAG_URI_GRANTS);
8405            for (UriPermission.Snapshot perm : persist) {
8406                out.startTag(null, TAG_URI_GRANT);
8407                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8408                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8409                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8410                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8411                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8412                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8413                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8414                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8415                out.endTag(null, TAG_URI_GRANT);
8416            }
8417            out.endTag(null, TAG_URI_GRANTS);
8418            out.endDocument();
8419
8420            mGrantFile.finishWrite(fos);
8421        } catch (IOException e) {
8422            if (fos != null) {
8423                mGrantFile.failWrite(fos);
8424            }
8425        }
8426    }
8427
8428    private void readGrantedUriPermissionsLocked() {
8429        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8430
8431        final long now = System.currentTimeMillis();
8432
8433        FileInputStream fis = null;
8434        try {
8435            fis = mGrantFile.openRead();
8436            final XmlPullParser in = Xml.newPullParser();
8437            in.setInput(fis, StandardCharsets.UTF_8.name());
8438
8439            int type;
8440            while ((type = in.next()) != END_DOCUMENT) {
8441                final String tag = in.getName();
8442                if (type == START_TAG) {
8443                    if (TAG_URI_GRANT.equals(tag)) {
8444                        final int sourceUserId;
8445                        final int targetUserId;
8446                        final int userHandle = readIntAttribute(in,
8447                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8448                        if (userHandle != UserHandle.USER_NULL) {
8449                            // For backwards compatibility.
8450                            sourceUserId = userHandle;
8451                            targetUserId = userHandle;
8452                        } else {
8453                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8454                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8455                        }
8456                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8457                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8458                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8459                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8460                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8461                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8462
8463                        // Sanity check that provider still belongs to source package
8464                        final ProviderInfo pi = getProviderInfoLocked(
8465                                uri.getAuthority(), sourceUserId);
8466                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8467                            int targetUid = -1;
8468                            try {
8469                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8470                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8471                            } catch (RemoteException e) {
8472                            }
8473                            if (targetUid != -1) {
8474                                final UriPermission perm = findOrCreateUriPermissionLocked(
8475                                        sourcePkg, targetPkg, targetUid,
8476                                        new GrantUri(sourceUserId, uri, prefix));
8477                                perm.initPersistedModes(modeFlags, createdTime);
8478                            }
8479                        } else {
8480                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8481                                    + " but instead found " + pi);
8482                        }
8483                    }
8484                }
8485            }
8486        } catch (FileNotFoundException e) {
8487            // Missing grants is okay
8488        } catch (IOException e) {
8489            Slog.wtf(TAG, "Failed reading Uri grants", e);
8490        } catch (XmlPullParserException e) {
8491            Slog.wtf(TAG, "Failed reading Uri grants", e);
8492        } finally {
8493            IoUtils.closeQuietly(fis);
8494        }
8495    }
8496
8497    /**
8498     * @param uri This uri must NOT contain an embedded userId.
8499     * @param userId The userId in which the uri is to be resolved.
8500     */
8501    @Override
8502    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8503        enforceNotIsolatedCaller("takePersistableUriPermission");
8504
8505        Preconditions.checkFlagsArgument(modeFlags,
8506                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8507
8508        synchronized (this) {
8509            final int callingUid = Binder.getCallingUid();
8510            boolean persistChanged = false;
8511            GrantUri grantUri = new GrantUri(userId, uri, false);
8512
8513            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8514                    new GrantUri(userId, uri, false));
8515            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8516                    new GrantUri(userId, uri, true));
8517
8518            final boolean exactValid = (exactPerm != null)
8519                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8520            final boolean prefixValid = (prefixPerm != null)
8521                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8522
8523            if (!(exactValid || prefixValid)) {
8524                throw new SecurityException("No persistable permission grants found for UID "
8525                        + callingUid + " and Uri " + grantUri.toSafeString());
8526            }
8527
8528            if (exactValid) {
8529                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8530            }
8531            if (prefixValid) {
8532                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8533            }
8534
8535            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8536
8537            if (persistChanged) {
8538                schedulePersistUriGrants();
8539            }
8540        }
8541    }
8542
8543    /**
8544     * @param uri This uri must NOT contain an embedded userId.
8545     * @param userId The userId in which the uri is to be resolved.
8546     */
8547    @Override
8548    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8549        enforceNotIsolatedCaller("releasePersistableUriPermission");
8550
8551        Preconditions.checkFlagsArgument(modeFlags,
8552                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8553
8554        synchronized (this) {
8555            final int callingUid = Binder.getCallingUid();
8556            boolean persistChanged = false;
8557
8558            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8559                    new GrantUri(userId, uri, false));
8560            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8561                    new GrantUri(userId, uri, true));
8562            if (exactPerm == null && prefixPerm == null) {
8563                throw new SecurityException("No permission grants found for UID " + callingUid
8564                        + " and Uri " + uri.toSafeString());
8565            }
8566
8567            if (exactPerm != null) {
8568                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8569                removeUriPermissionIfNeededLocked(exactPerm);
8570            }
8571            if (prefixPerm != null) {
8572                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8573                removeUriPermissionIfNeededLocked(prefixPerm);
8574            }
8575
8576            if (persistChanged) {
8577                schedulePersistUriGrants();
8578            }
8579        }
8580    }
8581
8582    /**
8583     * Prune any older {@link UriPermission} for the given UID until outstanding
8584     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8585     *
8586     * @return if any mutations occured that require persisting.
8587     */
8588    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8589        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8590        if (perms == null) return false;
8591        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8592
8593        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8594        for (UriPermission perm : perms.values()) {
8595            if (perm.persistedModeFlags != 0) {
8596                persisted.add(perm);
8597            }
8598        }
8599
8600        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8601        if (trimCount <= 0) return false;
8602
8603        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8604        for (int i = 0; i < trimCount; i++) {
8605            final UriPermission perm = persisted.get(i);
8606
8607            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8608                    "Trimming grant created at " + perm.persistedCreateTime);
8609
8610            perm.releasePersistableModes(~0);
8611            removeUriPermissionIfNeededLocked(perm);
8612        }
8613
8614        return true;
8615    }
8616
8617    @Override
8618    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8619            String packageName, boolean incoming) {
8620        enforceNotIsolatedCaller("getPersistedUriPermissions");
8621        Preconditions.checkNotNull(packageName, "packageName");
8622
8623        final int callingUid = Binder.getCallingUid();
8624        final IPackageManager pm = AppGlobals.getPackageManager();
8625        try {
8626            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8627                    UserHandle.getUserId(callingUid));
8628            if (packageUid != callingUid) {
8629                throw new SecurityException(
8630                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8631            }
8632        } catch (RemoteException e) {
8633            throw new SecurityException("Failed to verify package name ownership");
8634        }
8635
8636        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8637        synchronized (this) {
8638            if (incoming) {
8639                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8640                        callingUid);
8641                if (perms == null) {
8642                    Slog.w(TAG, "No permission grants found for " + packageName);
8643                } else {
8644                    for (UriPermission perm : perms.values()) {
8645                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8646                            result.add(perm.buildPersistedPublicApiObject());
8647                        }
8648                    }
8649                }
8650            } else {
8651                final int size = mGrantedUriPermissions.size();
8652                for (int i = 0; i < size; i++) {
8653                    final ArrayMap<GrantUri, UriPermission> perms =
8654                            mGrantedUriPermissions.valueAt(i);
8655                    for (UriPermission perm : perms.values()) {
8656                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8657                            result.add(perm.buildPersistedPublicApiObject());
8658                        }
8659                    }
8660                }
8661            }
8662        }
8663        return new ParceledListSlice<android.content.UriPermission>(result);
8664    }
8665
8666    @Override
8667    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8668            String packageName, int userId) {
8669        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8670                "getGrantedUriPermissions");
8671
8672        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8673        synchronized (this) {
8674            final int size = mGrantedUriPermissions.size();
8675            for (int i = 0; i < size; i++) {
8676                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8677                for (UriPermission perm : perms.values()) {
8678                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8679                            && perm.persistedModeFlags != 0) {
8680                        result.add(perm.buildPersistedPublicApiObject());
8681                    }
8682                }
8683            }
8684        }
8685        return new ParceledListSlice<android.content.UriPermission>(result);
8686    }
8687
8688    @Override
8689    public void clearGrantedUriPermissions(String packageName, int userId) {
8690        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8691                "clearGrantedUriPermissions");
8692        removeUriPermissionsForPackageLocked(packageName, userId, true);
8693    }
8694
8695    @Override
8696    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8697        synchronized (this) {
8698            ProcessRecord app =
8699                who != null ? getRecordForAppLocked(who) : null;
8700            if (app == null) return;
8701
8702            Message msg = Message.obtain();
8703            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8704            msg.obj = app;
8705            msg.arg1 = waiting ? 1 : 0;
8706            mUiHandler.sendMessage(msg);
8707        }
8708    }
8709
8710    @Override
8711    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8712        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8713        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8714        outInfo.availMem = Process.getFreeMemory();
8715        outInfo.totalMem = Process.getTotalMemory();
8716        outInfo.threshold = homeAppMem;
8717        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8718        outInfo.hiddenAppThreshold = cachedAppMem;
8719        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8720                ProcessList.SERVICE_ADJ);
8721        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8722                ProcessList.VISIBLE_APP_ADJ);
8723        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8724                ProcessList.FOREGROUND_APP_ADJ);
8725    }
8726
8727    // =========================================================
8728    // TASK MANAGEMENT
8729    // =========================================================
8730
8731    @Override
8732    public List<IAppTask> getAppTasks(String callingPackage) {
8733        int callingUid = Binder.getCallingUid();
8734        long ident = Binder.clearCallingIdentity();
8735
8736        synchronized(this) {
8737            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8738            try {
8739                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8740
8741                final int N = mRecentTasks.size();
8742                for (int i = 0; i < N; i++) {
8743                    TaskRecord tr = mRecentTasks.get(i);
8744                    // Skip tasks that do not match the caller.  We don't need to verify
8745                    // callingPackage, because we are also limiting to callingUid and know
8746                    // that will limit to the correct security sandbox.
8747                    if (tr.effectiveUid != callingUid) {
8748                        continue;
8749                    }
8750                    Intent intent = tr.getBaseIntent();
8751                    if (intent == null ||
8752                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8753                        continue;
8754                    }
8755                    ActivityManager.RecentTaskInfo taskInfo =
8756                            createRecentTaskInfoFromTaskRecord(tr);
8757                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8758                    list.add(taskImpl);
8759                }
8760            } finally {
8761                Binder.restoreCallingIdentity(ident);
8762            }
8763            return list;
8764        }
8765    }
8766
8767    @Override
8768    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8769        final int callingUid = Binder.getCallingUid();
8770        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8771
8772        synchronized(this) {
8773            if (DEBUG_ALL) Slog.v(
8774                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8775
8776            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8777                    callingUid);
8778
8779            // TODO: Improve with MRU list from all ActivityStacks.
8780            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8781        }
8782
8783        return list;
8784    }
8785
8786    /**
8787     * Creates a new RecentTaskInfo from a TaskRecord.
8788     */
8789    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8790        // Update the task description to reflect any changes in the task stack
8791        tr.updateTaskDescription();
8792
8793        // Compose the recent task info
8794        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8795        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8796        rti.persistentId = tr.taskId;
8797        rti.baseIntent = new Intent(tr.getBaseIntent());
8798        rti.origActivity = tr.origActivity;
8799        rti.realActivity = tr.realActivity;
8800        rti.description = tr.lastDescription;
8801        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8802        rti.userId = tr.userId;
8803        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8804        rti.firstActiveTime = tr.firstActiveTime;
8805        rti.lastActiveTime = tr.lastActiveTime;
8806        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8807        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8808        rti.numActivities = 0;
8809        if (tr.mBounds != null) {
8810            rti.bounds = new Rect(tr.mBounds);
8811        }
8812        rti.isDockable = tr.canGoInDockedStack();
8813
8814        ActivityRecord base = null;
8815        ActivityRecord top = null;
8816        ActivityRecord tmp;
8817
8818        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8819            tmp = tr.mActivities.get(i);
8820            if (tmp.finishing) {
8821                continue;
8822            }
8823            base = tmp;
8824            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8825                top = base;
8826            }
8827            rti.numActivities++;
8828        }
8829
8830        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8831        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8832
8833        return rti;
8834    }
8835
8836    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8837        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8838                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8839        if (!allowed) {
8840            if (checkPermission(android.Manifest.permission.GET_TASKS,
8841                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8842                // Temporary compatibility: some existing apps on the system image may
8843                // still be requesting the old permission and not switched to the new
8844                // one; if so, we'll still allow them full access.  This means we need
8845                // to see if they are holding the old permission and are a system app.
8846                try {
8847                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8848                        allowed = true;
8849                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8850                                + " is using old GET_TASKS but privileged; allowing");
8851                    }
8852                } catch (RemoteException e) {
8853                }
8854            }
8855        }
8856        if (!allowed) {
8857            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8858                    + " does not hold REAL_GET_TASKS; limiting output");
8859        }
8860        return allowed;
8861    }
8862
8863    @Override
8864    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8865        final int callingUid = Binder.getCallingUid();
8866        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8867                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8868
8869        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8870        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8871        synchronized (this) {
8872            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8873                    callingUid);
8874            final boolean detailed = checkCallingPermission(
8875                    android.Manifest.permission.GET_DETAILED_TASKS)
8876                    == PackageManager.PERMISSION_GRANTED;
8877
8878            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8879                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8880                return Collections.emptyList();
8881            }
8882            mRecentTasks.loadUserRecentsLocked(userId);
8883
8884            final int recentsCount = mRecentTasks.size();
8885            ArrayList<ActivityManager.RecentTaskInfo> res =
8886                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8887
8888            final Set<Integer> includedUsers;
8889            if (includeProfiles) {
8890                includedUsers = mUserController.getProfileIds(userId);
8891            } else {
8892                includedUsers = new HashSet<>();
8893            }
8894            includedUsers.add(Integer.valueOf(userId));
8895
8896            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8897                TaskRecord tr = mRecentTasks.get(i);
8898                // Only add calling user or related users recent tasks
8899                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8900                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8901                    continue;
8902                }
8903
8904                if (tr.realActivitySuspended) {
8905                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8906                    continue;
8907                }
8908
8909                // Return the entry if desired by the caller.  We always return
8910                // the first entry, because callers always expect this to be the
8911                // foreground app.  We may filter others if the caller has
8912                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8913                // we should exclude the entry.
8914
8915                if (i == 0
8916                        || withExcluded
8917                        || (tr.intent == null)
8918                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8919                                == 0)) {
8920                    if (!allowed) {
8921                        // If the caller doesn't have the GET_TASKS permission, then only
8922                        // allow them to see a small subset of tasks -- their own and home.
8923                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8924                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8925                            continue;
8926                        }
8927                    }
8928                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8929                        if (tr.stack != null && tr.stack.isHomeStack()) {
8930                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8931                                    "Skipping, home stack task: " + tr);
8932                            continue;
8933                        }
8934                    }
8935                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8936                        final ActivityStack stack = tr.stack;
8937                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8938                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8939                                    "Skipping, top task in docked stack: " + tr);
8940                            continue;
8941                        }
8942                    }
8943                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8944                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8945                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8946                                    "Skipping, pinned stack task: " + tr);
8947                            continue;
8948                        }
8949                    }
8950                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8951                        // Don't include auto remove tasks that are finished or finishing.
8952                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8953                                "Skipping, auto-remove without activity: " + tr);
8954                        continue;
8955                    }
8956                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8957                            && !tr.isAvailable) {
8958                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8959                                "Skipping, unavail real act: " + tr);
8960                        continue;
8961                    }
8962
8963                    if (!tr.mUserSetupComplete) {
8964                        // Don't include task launched while user is not done setting-up.
8965                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8966                                "Skipping, user setup not complete: " + tr);
8967                        continue;
8968                    }
8969
8970                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8971                    if (!detailed) {
8972                        rti.baseIntent.replaceExtras((Bundle)null);
8973                    }
8974
8975                    res.add(rti);
8976                    maxNum--;
8977                }
8978            }
8979            return res;
8980        }
8981    }
8982
8983    @Override
8984    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8985        synchronized (this) {
8986            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8987                    "getTaskThumbnail()");
8988            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8989                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8990            if (tr != null) {
8991                return tr.getTaskThumbnailLocked();
8992            }
8993        }
8994        return null;
8995    }
8996
8997    @Override
8998    public int addAppTask(IBinder activityToken, Intent intent,
8999            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9000        final int callingUid = Binder.getCallingUid();
9001        final long callingIdent = Binder.clearCallingIdentity();
9002
9003        try {
9004            synchronized (this) {
9005                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9006                if (r == null) {
9007                    throw new IllegalArgumentException("Activity does not exist; token="
9008                            + activityToken);
9009                }
9010                ComponentName comp = intent.getComponent();
9011                if (comp == null) {
9012                    throw new IllegalArgumentException("Intent " + intent
9013                            + " must specify explicit component");
9014                }
9015                if (thumbnail.getWidth() != mThumbnailWidth
9016                        || thumbnail.getHeight() != mThumbnailHeight) {
9017                    throw new IllegalArgumentException("Bad thumbnail size: got "
9018                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9019                            + mThumbnailWidth + "x" + mThumbnailHeight);
9020                }
9021                if (intent.getSelector() != null) {
9022                    intent.setSelector(null);
9023                }
9024                if (intent.getSourceBounds() != null) {
9025                    intent.setSourceBounds(null);
9026                }
9027                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9028                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9029                        // The caller has added this as an auto-remove task...  that makes no
9030                        // sense, so turn off auto-remove.
9031                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9032                    }
9033                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9034                    // Must be a new task.
9035                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9036                }
9037                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9038                    mLastAddedTaskActivity = null;
9039                }
9040                ActivityInfo ainfo = mLastAddedTaskActivity;
9041                if (ainfo == null) {
9042                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9043                            comp, 0, UserHandle.getUserId(callingUid));
9044                    if (ainfo.applicationInfo.uid != callingUid) {
9045                        throw new SecurityException(
9046                                "Can't add task for another application: target uid="
9047                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9048                    }
9049                }
9050
9051                // Use the full screen as the context for the task thumbnail
9052                final Point displaySize = new Point();
9053                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9054                r.task.stack.getDisplaySize(displaySize);
9055                thumbnailInfo.taskWidth = displaySize.x;
9056                thumbnailInfo.taskHeight = displaySize.y;
9057                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9058
9059                TaskRecord task = new TaskRecord(this,
9060                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9061                        ainfo, intent, description, thumbnailInfo);
9062
9063                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9064                if (trimIdx >= 0) {
9065                    // If this would have caused a trim, then we'll abort because that
9066                    // means it would be added at the end of the list but then just removed.
9067                    return INVALID_TASK_ID;
9068                }
9069
9070                final int N = mRecentTasks.size();
9071                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9072                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9073                    tr.removedFromRecents();
9074                }
9075
9076                task.inRecents = true;
9077                mRecentTasks.add(task);
9078                r.task.stack.addTask(task, false, "addAppTask");
9079
9080                task.setLastThumbnailLocked(thumbnail);
9081                task.freeLastThumbnail();
9082
9083                return task.taskId;
9084            }
9085        } finally {
9086            Binder.restoreCallingIdentity(callingIdent);
9087        }
9088    }
9089
9090    @Override
9091    public Point getAppTaskThumbnailSize() {
9092        synchronized (this) {
9093            return new Point(mThumbnailWidth,  mThumbnailHeight);
9094        }
9095    }
9096
9097    @Override
9098    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9099        synchronized (this) {
9100            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9101            if (r != null) {
9102                r.setTaskDescription(td);
9103                r.task.updateTaskDescription();
9104            }
9105        }
9106    }
9107
9108    @Override
9109    public void setTaskResizeable(int taskId, int resizeableMode) {
9110        synchronized (this) {
9111            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9112                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9113            if (task == null) {
9114                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9115                return;
9116            }
9117            if (task.mResizeMode != resizeableMode) {
9118                task.mResizeMode = resizeableMode;
9119                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9120                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9121                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9122            }
9123        }
9124    }
9125
9126    @Override
9127    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9128        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9129        long ident = Binder.clearCallingIdentity();
9130        try {
9131            synchronized (this) {
9132                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9133                if (task == null) {
9134                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9135                    return;
9136                }
9137                int stackId = task.stack.mStackId;
9138                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9139                // in crop windows resize mode or if the task size is affected by the docked stack
9140                // changing size. No need to update configuration.
9141                if (bounds != null && task.inCropWindowsResizeMode()
9142                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9143                    mWindowManager.scrollTask(task.taskId, bounds);
9144                    return;
9145                }
9146
9147                // Place the task in the right stack if it isn't there already based on
9148                // the requested bounds.
9149                // The stack transition logic is:
9150                // - a null bounds on a freeform task moves that task to fullscreen
9151                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9152                //   that task to freeform
9153                // - otherwise the task is not moved
9154                if (!StackId.isTaskResizeAllowed(stackId)) {
9155                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9156                }
9157                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9158                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9159                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9160                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9161                }
9162                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9163                if (stackId != task.stack.mStackId) {
9164                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9165                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9166                    preserveWindow = false;
9167                }
9168
9169                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9170                        false /* deferResume */);
9171            }
9172        } finally {
9173            Binder.restoreCallingIdentity(ident);
9174        }
9175    }
9176
9177    @Override
9178    public Rect getTaskBounds(int taskId) {
9179        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9180        long ident = Binder.clearCallingIdentity();
9181        Rect rect = new Rect();
9182        try {
9183            synchronized (this) {
9184                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9185                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9186                if (task == null) {
9187                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9188                    return rect;
9189                }
9190                if (task.stack != null) {
9191                    // Return the bounds from window manager since it will be adjusted for various
9192                    // things like the presense of a docked stack for tasks that aren't resizeable.
9193                    mWindowManager.getTaskBounds(task.taskId, rect);
9194                } else {
9195                    // Task isn't in window manager yet since it isn't associated with a stack.
9196                    // Return the persist value from activity manager
9197                    if (task.mBounds != null) {
9198                        rect.set(task.mBounds);
9199                    } else if (task.mLastNonFullscreenBounds != null) {
9200                        rect.set(task.mLastNonFullscreenBounds);
9201                    }
9202                }
9203            }
9204        } finally {
9205            Binder.restoreCallingIdentity(ident);
9206        }
9207        return rect;
9208    }
9209
9210    @Override
9211    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9212        if (userId != UserHandle.getCallingUserId()) {
9213            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9214                    "getTaskDescriptionIcon");
9215        }
9216        final File passedIconFile = new File(filePath);
9217        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9218                passedIconFile.getName());
9219        if (!legitIconFile.getPath().equals(filePath)
9220                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9221            throw new IllegalArgumentException("Bad file path: " + filePath
9222                    + " passed for userId " + userId);
9223        }
9224        return mRecentTasks.getTaskDescriptionIcon(filePath);
9225    }
9226
9227    @Override
9228    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9229            throws RemoteException {
9230        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9231                opts.getCustomInPlaceResId() == 0) {
9232            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9233                    "with valid animation");
9234        }
9235        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9236        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9237                opts.getCustomInPlaceResId());
9238        mWindowManager.executeAppTransition();
9239    }
9240
9241    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9242            boolean removeFromRecents) {
9243        if (removeFromRecents) {
9244            mRecentTasks.remove(tr);
9245            tr.removedFromRecents();
9246        }
9247        ComponentName component = tr.getBaseIntent().getComponent();
9248        if (component == null) {
9249            Slog.w(TAG, "No component for base intent of task: " + tr);
9250            return;
9251        }
9252
9253        // Find any running services associated with this app and stop if needed.
9254        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9255
9256        if (!killProcess) {
9257            return;
9258        }
9259
9260        // Determine if the process(es) for this task should be killed.
9261        final String pkg = component.getPackageName();
9262        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9263        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9264        for (int i = 0; i < pmap.size(); i++) {
9265
9266            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9267            for (int j = 0; j < uids.size(); j++) {
9268                ProcessRecord proc = uids.valueAt(j);
9269                if (proc.userId != tr.userId) {
9270                    // Don't kill process for a different user.
9271                    continue;
9272                }
9273                if (proc == mHomeProcess) {
9274                    // Don't kill the home process along with tasks from the same package.
9275                    continue;
9276                }
9277                if (!proc.pkgList.containsKey(pkg)) {
9278                    // Don't kill process that is not associated with this task.
9279                    continue;
9280                }
9281
9282                for (int k = 0; k < proc.activities.size(); k++) {
9283                    TaskRecord otherTask = proc.activities.get(k).task;
9284                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9285                        // Don't kill process(es) that has an activity in a different task that is
9286                        // also in recents.
9287                        return;
9288                    }
9289                }
9290
9291                if (proc.foregroundServices) {
9292                    // Don't kill process(es) with foreground service.
9293                    return;
9294                }
9295
9296                // Add process to kill list.
9297                procsToKill.add(proc);
9298            }
9299        }
9300
9301        // Kill the running processes.
9302        for (int i = 0; i < procsToKill.size(); i++) {
9303            ProcessRecord pr = procsToKill.get(i);
9304            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9305                    && pr.curReceiver == null) {
9306                pr.kill("remove task", true);
9307            } else {
9308                // We delay killing processes that are not in the background or running a receiver.
9309                pr.waitingToKill = "remove task";
9310            }
9311        }
9312    }
9313
9314    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9315        // Remove all tasks with activities in the specified package from the list of recent tasks
9316        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9317            TaskRecord tr = mRecentTasks.get(i);
9318            if (tr.userId != userId) continue;
9319
9320            ComponentName cn = tr.intent.getComponent();
9321            if (cn != null && cn.getPackageName().equals(packageName)) {
9322                // If the package name matches, remove the task.
9323                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9324            }
9325        }
9326    }
9327
9328    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9329            int userId) {
9330
9331        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9332            TaskRecord tr = mRecentTasks.get(i);
9333            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9334                continue;
9335            }
9336
9337            ComponentName cn = tr.intent.getComponent();
9338            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9339                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9340            if (sameComponent) {
9341                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9342            }
9343        }
9344    }
9345
9346    /**
9347     * Removes the task with the specified task id.
9348     *
9349     * @param taskId Identifier of the task to be removed.
9350     * @param killProcess Kill any process associated with the task if possible.
9351     * @param removeFromRecents Whether to also remove the task from recents.
9352     * @return Returns true if the given task was found and removed.
9353     */
9354    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9355            boolean removeFromRecents) {
9356        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9357                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9358        if (tr != null) {
9359            tr.removeTaskActivitiesLocked();
9360            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9361            if (tr.isPersistable) {
9362                notifyTaskPersisterLocked(null, true);
9363            }
9364            return true;
9365        }
9366        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9367        return false;
9368    }
9369
9370    @Override
9371    public void removeStack(int stackId) {
9372        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9373        if (stackId == HOME_STACK_ID) {
9374            throw new IllegalArgumentException("Removing home stack is not allowed.");
9375        }
9376
9377        synchronized (this) {
9378            final long ident = Binder.clearCallingIdentity();
9379            try {
9380                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9381                if (stack == null) {
9382                    return;
9383                }
9384                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9385                for (int i = tasks.size() - 1; i >= 0; i--) {
9386                    removeTaskByIdLocked(
9387                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9388                }
9389            } finally {
9390                Binder.restoreCallingIdentity(ident);
9391            }
9392        }
9393    }
9394
9395    @Override
9396    public boolean removeTask(int taskId) {
9397        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9398        synchronized (this) {
9399            final long ident = Binder.clearCallingIdentity();
9400            try {
9401                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9402            } finally {
9403                Binder.restoreCallingIdentity(ident);
9404            }
9405        }
9406    }
9407
9408    /**
9409     * TODO: Add mController hook
9410     */
9411    @Override
9412    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9413        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9414
9415        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9416        synchronized(this) {
9417            moveTaskToFrontLocked(taskId, flags, bOptions);
9418        }
9419    }
9420
9421    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9422        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9423
9424        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9425                Binder.getCallingUid(), -1, -1, "Task to front")) {
9426            ActivityOptions.abort(options);
9427            return;
9428        }
9429        final long origId = Binder.clearCallingIdentity();
9430        try {
9431            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9432            if (task == null) {
9433                Slog.d(TAG, "Could not find task for id: "+ taskId);
9434                return;
9435            }
9436            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9437                mStackSupervisor.showLockTaskToast();
9438                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9439                return;
9440            }
9441            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9442            if (prev != null && prev.isRecentsActivity()) {
9443                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9444            }
9445            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9446        } finally {
9447            Binder.restoreCallingIdentity(origId);
9448        }
9449        ActivityOptions.abort(options);
9450    }
9451
9452    /**
9453     * Moves an activity, and all of the other activities within the same task, to the bottom
9454     * of the history stack.  The activity's order within the task is unchanged.
9455     *
9456     * @param token A reference to the activity we wish to move
9457     * @param nonRoot If false then this only works if the activity is the root
9458     *                of a task; if true it will work for any activity in a task.
9459     * @return Returns true if the move completed, false if not.
9460     */
9461    @Override
9462    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9463        enforceNotIsolatedCaller("moveActivityTaskToBack");
9464        synchronized(this) {
9465            final long origId = Binder.clearCallingIdentity();
9466            try {
9467                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9468                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9469                if (task != null) {
9470                    if (mStackSupervisor.isLockedTask(task)) {
9471                        mStackSupervisor.showLockTaskToast();
9472                        return false;
9473                    }
9474                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9475                }
9476            } finally {
9477                Binder.restoreCallingIdentity(origId);
9478            }
9479        }
9480        return false;
9481    }
9482
9483    @Override
9484    public void moveTaskBackwards(int task) {
9485        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9486                "moveTaskBackwards()");
9487
9488        synchronized(this) {
9489            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9490                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9491                return;
9492            }
9493            final long origId = Binder.clearCallingIdentity();
9494            moveTaskBackwardsLocked(task);
9495            Binder.restoreCallingIdentity(origId);
9496        }
9497    }
9498
9499    private final void moveTaskBackwardsLocked(int task) {
9500        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9501    }
9502
9503    @Override
9504    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9505            IActivityContainerCallback callback) throws RemoteException {
9506        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9507        synchronized (this) {
9508            if (parentActivityToken == null) {
9509                throw new IllegalArgumentException("parent token must not be null");
9510            }
9511            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9512            if (r == null) {
9513                return null;
9514            }
9515            if (callback == null) {
9516                throw new IllegalArgumentException("callback must not be null");
9517            }
9518            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9519        }
9520    }
9521
9522    @Override
9523    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9524        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9525        synchronized (this) {
9526            mStackSupervisor.deleteActivityContainer(container);
9527        }
9528    }
9529
9530    @Override
9531    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9532        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9533        synchronized (this) {
9534            final int stackId = mStackSupervisor.getNextStackId();
9535            final ActivityStack stack =
9536                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9537            if (stack == null) {
9538                return null;
9539            }
9540            return stack.mActivityContainer;
9541        }
9542    }
9543
9544    @Override
9545    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9546        synchronized (this) {
9547            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9548            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9549                return stack.mActivityContainer.getDisplayId();
9550            }
9551            return Display.DEFAULT_DISPLAY;
9552        }
9553    }
9554
9555    @Override
9556    public int getActivityStackId(IBinder token) throws RemoteException {
9557        synchronized (this) {
9558            ActivityStack stack = ActivityRecord.getStackLocked(token);
9559            if (stack == null) {
9560                return INVALID_STACK_ID;
9561            }
9562            return stack.mStackId;
9563        }
9564    }
9565
9566    @Override
9567    public void exitFreeformMode(IBinder token) throws RemoteException {
9568        synchronized (this) {
9569            long ident = Binder.clearCallingIdentity();
9570            try {
9571                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9572                if (r == null) {
9573                    throw new IllegalArgumentException(
9574                            "exitFreeformMode: No activity record matching token=" + token);
9575                }
9576                final ActivityStack stack = r.getStackLocked(token);
9577                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9578                    throw new IllegalStateException(
9579                            "exitFreeformMode: You can only go fullscreen from freeform.");
9580                }
9581                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9582                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9583                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9584            } finally {
9585                Binder.restoreCallingIdentity(ident);
9586            }
9587        }
9588    }
9589
9590    @Override
9591    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9592        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9593        if (stackId == HOME_STACK_ID) {
9594            throw new IllegalArgumentException(
9595                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9596        }
9597        synchronized (this) {
9598            long ident = Binder.clearCallingIdentity();
9599            try {
9600                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9601                        + " to stackId=" + stackId + " toTop=" + toTop);
9602                if (stackId == DOCKED_STACK_ID) {
9603                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9604                            null /* initialBounds */);
9605                }
9606                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9607                        "moveTaskToStack", ANIMATE);
9608            } finally {
9609                Binder.restoreCallingIdentity(ident);
9610            }
9611        }
9612    }
9613
9614    @Override
9615    public void swapDockedAndFullscreenStack() throws RemoteException {
9616        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9617        synchronized (this) {
9618            long ident = Binder.clearCallingIdentity();
9619            try {
9620                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9621                        FULLSCREEN_WORKSPACE_STACK_ID);
9622                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9623                        : null;
9624                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9625                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9626                        : null;
9627                if (topTask == null || tasks == null || tasks.size() == 0) {
9628                    Slog.w(TAG,
9629                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9630                    return;
9631                }
9632
9633                // TODO: App transition
9634                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9635
9636                // Defer the resume so resume/pausing while moving stacks is dangerous.
9637                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9638                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9639                        ANIMATE, true /* deferResume */);
9640                final int size = tasks.size();
9641                for (int i = 0; i < size; i++) {
9642                    final int id = tasks.get(i).taskId;
9643                    if (id == topTask.taskId) {
9644                        continue;
9645                    }
9646                    mStackSupervisor.moveTaskToStackLocked(id,
9647                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9648                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9649                }
9650
9651                // Because we deferred the resume, to avoid conflicts with stack switches while
9652                // resuming, we need to do it after all the tasks are moved.
9653                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9654                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9655
9656                mWindowManager.executeAppTransition();
9657            } finally {
9658                Binder.restoreCallingIdentity(ident);
9659            }
9660        }
9661    }
9662
9663    /**
9664     * Moves the input task to the docked stack.
9665     *
9666     * @param taskId Id of task to move.
9667     * @param createMode The mode the docked stack should be created in if it doesn't exist
9668     *                   already. See
9669     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9670     *                   and
9671     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9672     * @param toTop If the task and stack should be moved to the top.
9673     * @param animate Whether we should play an animation for the moving the task
9674     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9675     *                      docked stack. Pass {@code null} to use default bounds.
9676     */
9677    @Override
9678    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9679            Rect initialBounds) {
9680        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9681        synchronized (this) {
9682            long ident = Binder.clearCallingIdentity();
9683            try {
9684                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9685                        + " to createMode=" + createMode + " toTop=" + toTop);
9686                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9687                return mStackSupervisor.moveTaskToStackLocked(
9688                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9689                        "moveTaskToDockedStack", animate);
9690            } finally {
9691                Binder.restoreCallingIdentity(ident);
9692            }
9693        }
9694    }
9695
9696    /**
9697     * Moves the top activity in the input stackId to the pinned stack.
9698     *
9699     * @param stackId Id of stack to move the top activity to pinned stack.
9700     * @param bounds Bounds to use for pinned stack.
9701     *
9702     * @return True if the top activity of the input stack was successfully moved to the pinned
9703     *          stack.
9704     */
9705    @Override
9706    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9707        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9708        synchronized (this) {
9709            if (!mSupportsPictureInPicture) {
9710                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9711                        + "Device doesn't support picture-in-pciture mode");
9712            }
9713
9714            long ident = Binder.clearCallingIdentity();
9715            try {
9716                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9717            } finally {
9718                Binder.restoreCallingIdentity(ident);
9719            }
9720        }
9721    }
9722
9723    @Override
9724    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9725            boolean preserveWindows, boolean animate, int animationDuration) {
9726        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9727        long ident = Binder.clearCallingIdentity();
9728        try {
9729            synchronized (this) {
9730                if (animate) {
9731                    if (stackId == PINNED_STACK_ID) {
9732                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9733                    } else {
9734                        throw new IllegalArgumentException("Stack: " + stackId
9735                                + " doesn't support animated resize.");
9736                    }
9737                } else {
9738                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9739                            null /* tempTaskInsetBounds */, preserveWindows,
9740                            allowResizeInDockedMode);
9741                }
9742            }
9743        } finally {
9744            Binder.restoreCallingIdentity(ident);
9745        }
9746    }
9747
9748    @Override
9749    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9750            Rect tempDockedTaskInsetBounds,
9751            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9752        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9753                "resizeDockedStack()");
9754        long ident = Binder.clearCallingIdentity();
9755        try {
9756            synchronized (this) {
9757                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9758                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9759                        PRESERVE_WINDOWS);
9760            }
9761        } finally {
9762            Binder.restoreCallingIdentity(ident);
9763        }
9764    }
9765
9766    @Override
9767    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9768        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9769                "resizePinnedStack()");
9770        final long ident = Binder.clearCallingIdentity();
9771        try {
9772            synchronized (this) {
9773                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9774            }
9775        } finally {
9776            Binder.restoreCallingIdentity(ident);
9777        }
9778    }
9779
9780    @Override
9781    public void positionTaskInStack(int taskId, int stackId, int position) {
9782        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9783        if (stackId == HOME_STACK_ID) {
9784            throw new IllegalArgumentException(
9785                    "positionTaskInStack: Attempt to change the position of task "
9786                    + taskId + " in/to home stack");
9787        }
9788        synchronized (this) {
9789            long ident = Binder.clearCallingIdentity();
9790            try {
9791                if (DEBUG_STACK) Slog.d(TAG_STACK,
9792                        "positionTaskInStack: positioning task=" + taskId
9793                        + " in stackId=" + stackId + " at position=" + position);
9794                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9795            } finally {
9796                Binder.restoreCallingIdentity(ident);
9797            }
9798        }
9799    }
9800
9801    @Override
9802    public List<StackInfo> getAllStackInfos() {
9803        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9804        long ident = Binder.clearCallingIdentity();
9805        try {
9806            synchronized (this) {
9807                return mStackSupervisor.getAllStackInfosLocked();
9808            }
9809        } finally {
9810            Binder.restoreCallingIdentity(ident);
9811        }
9812    }
9813
9814    @Override
9815    public StackInfo getStackInfo(int stackId) {
9816        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9817        long ident = Binder.clearCallingIdentity();
9818        try {
9819            synchronized (this) {
9820                return mStackSupervisor.getStackInfoLocked(stackId);
9821            }
9822        } finally {
9823            Binder.restoreCallingIdentity(ident);
9824        }
9825    }
9826
9827    @Override
9828    public boolean isInHomeStack(int taskId) {
9829        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9830        long ident = Binder.clearCallingIdentity();
9831        try {
9832            synchronized (this) {
9833                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9834                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9835                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9836            }
9837        } finally {
9838            Binder.restoreCallingIdentity(ident);
9839        }
9840    }
9841
9842    @Override
9843    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9844        synchronized(this) {
9845            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9846        }
9847    }
9848
9849    @Override
9850    public void updateDeviceOwner(String packageName) {
9851        final int callingUid = Binder.getCallingUid();
9852        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9853            throw new SecurityException("updateDeviceOwner called from non-system process");
9854        }
9855        synchronized (this) {
9856            mDeviceOwnerName = packageName;
9857        }
9858    }
9859
9860    @Override
9861    public void updateLockTaskPackages(int userId, String[] packages) {
9862        final int callingUid = Binder.getCallingUid();
9863        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9864            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9865                    "updateLockTaskPackages()");
9866        }
9867        synchronized (this) {
9868            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9869                    Arrays.toString(packages));
9870            mLockTaskPackages.put(userId, packages);
9871            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9872        }
9873    }
9874
9875
9876    void startLockTaskModeLocked(TaskRecord task) {
9877        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9878        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9879            return;
9880        }
9881
9882        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9883        // is initiated by system after the pinning request was shown and locked mode is initiated
9884        // by an authorized app directly
9885        final int callingUid = Binder.getCallingUid();
9886        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9887        long ident = Binder.clearCallingIdentity();
9888        try {
9889            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9890            if (!isSystemInitiated) {
9891                task.mLockTaskUid = callingUid;
9892                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9893                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9894                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9895                    StatusBarManagerInternal statusBarManager =
9896                            LocalServices.getService(StatusBarManagerInternal.class);
9897                    if (statusBarManager != null) {
9898                        statusBarManager.showScreenPinningRequest();
9899                    }
9900                    return;
9901                }
9902
9903                if (stack == null || task != stack.topTask()) {
9904                    throw new IllegalArgumentException("Invalid task, not in foreground");
9905                }
9906            }
9907            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9908                    "Locking fully");
9909            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9910                    ActivityManager.LOCK_TASK_MODE_PINNED :
9911                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9912                    "startLockTask", true);
9913        } finally {
9914            Binder.restoreCallingIdentity(ident);
9915        }
9916    }
9917
9918    @Override
9919    public void startLockTaskMode(int taskId) {
9920        synchronized (this) {
9921            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9922            if (task != null) {
9923                startLockTaskModeLocked(task);
9924            }
9925        }
9926    }
9927
9928    @Override
9929    public void startLockTaskMode(IBinder token) {
9930        synchronized (this) {
9931            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9932            if (r == null) {
9933                return;
9934            }
9935            final TaskRecord task = r.task;
9936            if (task != null) {
9937                startLockTaskModeLocked(task);
9938            }
9939        }
9940    }
9941
9942    @Override
9943    public void startLockTaskModeOnCurrent() throws RemoteException {
9944        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9945        long ident = Binder.clearCallingIdentity();
9946        try {
9947            synchronized (this) {
9948                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9949                if (r != null) {
9950                    startLockTaskModeLocked(r.task);
9951                }
9952            }
9953        } finally {
9954            Binder.restoreCallingIdentity(ident);
9955        }
9956    }
9957
9958    @Override
9959    public void stopLockTaskMode() {
9960        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9961        if (lockTask == null) {
9962            // Our work here is done.
9963            return;
9964        }
9965
9966        final int callingUid = Binder.getCallingUid();
9967        final int lockTaskUid = lockTask.mLockTaskUid;
9968        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9969        // It is possible lockTaskMode was started by the system process because
9970        // android:lockTaskMode is set to a locking value in the application manifest instead of
9971        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9972        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9973        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9974                callingUid != lockTaskUid
9975                && (lockTaskUid != 0
9976                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9977            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9978                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9979        }
9980
9981        long ident = Binder.clearCallingIdentity();
9982        try {
9983            Log.d(TAG, "stopLockTaskMode");
9984            // Stop lock task
9985            synchronized (this) {
9986                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9987                        "stopLockTask", true);
9988            }
9989        } finally {
9990            Binder.restoreCallingIdentity(ident);
9991        }
9992    }
9993
9994    @Override
9995    public void stopLockTaskModeOnCurrent() throws RemoteException {
9996        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9997        long ident = Binder.clearCallingIdentity();
9998        try {
9999            stopLockTaskMode();
10000        } finally {
10001            Binder.restoreCallingIdentity(ident);
10002        }
10003    }
10004
10005    @Override
10006    public boolean isInLockTaskMode() {
10007        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10008    }
10009
10010    @Override
10011    public int getLockTaskModeState() {
10012        synchronized (this) {
10013            return mStackSupervisor.getLockTaskModeState();
10014        }
10015    }
10016
10017    @Override
10018    public void showLockTaskEscapeMessage(IBinder token) {
10019        synchronized (this) {
10020            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10021            if (r == null) {
10022                return;
10023            }
10024            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10025        }
10026    }
10027
10028    // =========================================================
10029    // CONTENT PROVIDERS
10030    // =========================================================
10031
10032    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10033        List<ProviderInfo> providers = null;
10034        try {
10035            providers = AppGlobals.getPackageManager()
10036                    .queryContentProviders(app.processName, app.uid,
10037                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10038                                    | MATCH_DEBUG_TRIAGED_MISSING)
10039                    .getList();
10040        } catch (RemoteException ex) {
10041        }
10042        if (DEBUG_MU) Slog.v(TAG_MU,
10043                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10044        int userId = app.userId;
10045        if (providers != null) {
10046            int N = providers.size();
10047            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10048            for (int i=0; i<N; i++) {
10049                ProviderInfo cpi =
10050                    (ProviderInfo)providers.get(i);
10051                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10052                        cpi.name, cpi.flags);
10053                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10054                    // This is a singleton provider, but a user besides the
10055                    // default user is asking to initialize a process it runs
10056                    // in...  well, no, it doesn't actually run in this process,
10057                    // it runs in the process of the default user.  Get rid of it.
10058                    providers.remove(i);
10059                    N--;
10060                    i--;
10061                    continue;
10062                }
10063
10064                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10065                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10066                if (cpr == null) {
10067                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10068                    mProviderMap.putProviderByClass(comp, cpr);
10069                }
10070                if (DEBUG_MU) Slog.v(TAG_MU,
10071                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10072                app.pubProviders.put(cpi.name, cpr);
10073                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10074                    // Don't add this if it is a platform component that is marked
10075                    // to run in multiple processes, because this is actually
10076                    // part of the framework so doesn't make sense to track as a
10077                    // separate apk in the process.
10078                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10079                            mProcessStats);
10080                }
10081                notifyPackageUse(cpi.applicationInfo.packageName);
10082            }
10083        }
10084        return providers;
10085    }
10086
10087    /**
10088     * Check if {@link ProcessRecord} has a possible chance at accessing the
10089     * given {@link ProviderInfo}. Final permission checking is always done
10090     * in {@link ContentProvider}.
10091     */
10092    private final String checkContentProviderPermissionLocked(
10093            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10094        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10095        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10096        boolean checkedGrants = false;
10097        if (checkUser) {
10098            // Looking for cross-user grants before enforcing the typical cross-users permissions
10099            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10100            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10101                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10102                    return null;
10103                }
10104                checkedGrants = true;
10105            }
10106            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10107                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10108            if (userId != tmpTargetUserId) {
10109                // When we actually went to determine the final targer user ID, this ended
10110                // up different than our initial check for the authority.  This is because
10111                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10112                // SELF.  So we need to re-check the grants again.
10113                checkedGrants = false;
10114            }
10115        }
10116        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10117                cpi.applicationInfo.uid, cpi.exported)
10118                == PackageManager.PERMISSION_GRANTED) {
10119            return null;
10120        }
10121        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10122                cpi.applicationInfo.uid, cpi.exported)
10123                == PackageManager.PERMISSION_GRANTED) {
10124            return null;
10125        }
10126
10127        PathPermission[] pps = cpi.pathPermissions;
10128        if (pps != null) {
10129            int i = pps.length;
10130            while (i > 0) {
10131                i--;
10132                PathPermission pp = pps[i];
10133                String pprperm = pp.getReadPermission();
10134                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10135                        cpi.applicationInfo.uid, cpi.exported)
10136                        == PackageManager.PERMISSION_GRANTED) {
10137                    return null;
10138                }
10139                String ppwperm = pp.getWritePermission();
10140                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10141                        cpi.applicationInfo.uid, cpi.exported)
10142                        == PackageManager.PERMISSION_GRANTED) {
10143                    return null;
10144                }
10145            }
10146        }
10147        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10148            return null;
10149        }
10150
10151        String msg;
10152        if (!cpi.exported) {
10153            msg = "Permission Denial: opening provider " + cpi.name
10154                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10155                    + ", uid=" + callingUid + ") that is not exported from uid "
10156                    + cpi.applicationInfo.uid;
10157        } else {
10158            msg = "Permission Denial: opening provider " + cpi.name
10159                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10160                    + ", uid=" + callingUid + ") requires "
10161                    + cpi.readPermission + " or " + cpi.writePermission;
10162        }
10163        Slog.w(TAG, msg);
10164        return msg;
10165    }
10166
10167    /**
10168     * Returns if the ContentProvider has granted a uri to callingUid
10169     */
10170    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10171        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10172        if (perms != null) {
10173            for (int i=perms.size()-1; i>=0; i--) {
10174                GrantUri grantUri = perms.keyAt(i);
10175                if (grantUri.sourceUserId == userId || !checkUser) {
10176                    if (matchesProvider(grantUri.uri, cpi)) {
10177                        return true;
10178                    }
10179                }
10180            }
10181        }
10182        return false;
10183    }
10184
10185    /**
10186     * Returns true if the uri authority is one of the authorities specified in the provider.
10187     */
10188    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10189        String uriAuth = uri.getAuthority();
10190        String cpiAuth = cpi.authority;
10191        if (cpiAuth.indexOf(';') == -1) {
10192            return cpiAuth.equals(uriAuth);
10193        }
10194        String[] cpiAuths = cpiAuth.split(";");
10195        int length = cpiAuths.length;
10196        for (int i = 0; i < length; i++) {
10197            if (cpiAuths[i].equals(uriAuth)) return true;
10198        }
10199        return false;
10200    }
10201
10202    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10203            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10204        if (r != null) {
10205            for (int i=0; i<r.conProviders.size(); i++) {
10206                ContentProviderConnection conn = r.conProviders.get(i);
10207                if (conn.provider == cpr) {
10208                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10209                            "Adding provider requested by "
10210                            + r.processName + " from process "
10211                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10212                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10213                    if (stable) {
10214                        conn.stableCount++;
10215                        conn.numStableIncs++;
10216                    } else {
10217                        conn.unstableCount++;
10218                        conn.numUnstableIncs++;
10219                    }
10220                    return conn;
10221                }
10222            }
10223            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10224            if (stable) {
10225                conn.stableCount = 1;
10226                conn.numStableIncs = 1;
10227            } else {
10228                conn.unstableCount = 1;
10229                conn.numUnstableIncs = 1;
10230            }
10231            cpr.connections.add(conn);
10232            r.conProviders.add(conn);
10233            startAssociationLocked(r.uid, r.processName, r.curProcState,
10234                    cpr.uid, cpr.name, cpr.info.processName);
10235            return conn;
10236        }
10237        cpr.addExternalProcessHandleLocked(externalProcessToken);
10238        return null;
10239    }
10240
10241    boolean decProviderCountLocked(ContentProviderConnection conn,
10242            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10243        if (conn != null) {
10244            cpr = conn.provider;
10245            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10246                    "Removing provider requested by "
10247                    + conn.client.processName + " from process "
10248                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10249                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10250            if (stable) {
10251                conn.stableCount--;
10252            } else {
10253                conn.unstableCount--;
10254            }
10255            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10256                cpr.connections.remove(conn);
10257                conn.client.conProviders.remove(conn);
10258                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10259                    // The client is more important than last activity -- note the time this
10260                    // is happening, so we keep the old provider process around a bit as last
10261                    // activity to avoid thrashing it.
10262                    if (cpr.proc != null) {
10263                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10264                    }
10265                }
10266                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10267                return true;
10268            }
10269            return false;
10270        }
10271        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10272        return false;
10273    }
10274
10275    private void checkTime(long startTime, String where) {
10276        long now = SystemClock.elapsedRealtime();
10277        if ((now-startTime) > 1000) {
10278            // If we are taking more than a second, log about it.
10279            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10280        }
10281    }
10282
10283    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10284            String name, IBinder token, boolean stable, int userId) {
10285        ContentProviderRecord cpr;
10286        ContentProviderConnection conn = null;
10287        ProviderInfo cpi = null;
10288
10289        synchronized(this) {
10290            long startTime = SystemClock.elapsedRealtime();
10291
10292            ProcessRecord r = null;
10293            if (caller != null) {
10294                r = getRecordForAppLocked(caller);
10295                if (r == null) {
10296                    throw new SecurityException(
10297                            "Unable to find app for caller " + caller
10298                          + " (pid=" + Binder.getCallingPid()
10299                          + ") when getting content provider " + name);
10300                }
10301            }
10302
10303            boolean checkCrossUser = true;
10304
10305            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10306
10307            // First check if this content provider has been published...
10308            cpr = mProviderMap.getProviderByName(name, userId);
10309            // If that didn't work, check if it exists for user 0 and then
10310            // verify that it's a singleton provider before using it.
10311            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10312                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10313                if (cpr != null) {
10314                    cpi = cpr.info;
10315                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10316                            cpi.name, cpi.flags)
10317                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10318                        userId = UserHandle.USER_SYSTEM;
10319                        checkCrossUser = false;
10320                    } else {
10321                        cpr = null;
10322                        cpi = null;
10323                    }
10324                }
10325            }
10326
10327            boolean providerRunning = cpr != null;
10328            if (providerRunning) {
10329                cpi = cpr.info;
10330                String msg;
10331                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10332                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10333                        != null) {
10334                    throw new SecurityException(msg);
10335                }
10336                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10337
10338                if (r != null && cpr.canRunHere(r)) {
10339                    // This provider has been published or is in the process
10340                    // of being published...  but it is also allowed to run
10341                    // in the caller's process, so don't make a connection
10342                    // and just let the caller instantiate its own instance.
10343                    ContentProviderHolder holder = cpr.newHolder(null);
10344                    // don't give caller the provider object, it needs
10345                    // to make its own.
10346                    holder.provider = null;
10347                    return holder;
10348                }
10349
10350                final long origId = Binder.clearCallingIdentity();
10351
10352                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10353
10354                // In this case the provider instance already exists, so we can
10355                // return it right away.
10356                conn = incProviderCountLocked(r, cpr, token, stable);
10357                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10358                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10359                        // If this is a perceptible app accessing the provider,
10360                        // make sure to count it as being accessed and thus
10361                        // back up on the LRU list.  This is good because
10362                        // content providers are often expensive to start.
10363                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10364                        updateLruProcessLocked(cpr.proc, false, null);
10365                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10366                    }
10367                }
10368
10369                if (cpr.proc != null) {
10370                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10371                    boolean success = updateOomAdjLocked(cpr.proc);
10372                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10373                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10374                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10375                    // NOTE: there is still a race here where a signal could be
10376                    // pending on the process even though we managed to update its
10377                    // adj level.  Not sure what to do about this, but at least
10378                    // the race is now smaller.
10379                    if (!success) {
10380                        // Uh oh...  it looks like the provider's process
10381                        // has been killed on us.  We need to wait for a new
10382                        // process to be started, and make sure its death
10383                        // doesn't kill our process.
10384                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10385                                + " is crashing; detaching " + r);
10386                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10387                        checkTime(startTime, "getContentProviderImpl: before appDied");
10388                        appDiedLocked(cpr.proc);
10389                        checkTime(startTime, "getContentProviderImpl: after appDied");
10390                        if (!lastRef) {
10391                            // This wasn't the last ref our process had on
10392                            // the provider...  we have now been killed, bail.
10393                            return null;
10394                        }
10395                        providerRunning = false;
10396                        conn = null;
10397                    }
10398                }
10399
10400                Binder.restoreCallingIdentity(origId);
10401            }
10402
10403            if (!providerRunning) {
10404                try {
10405                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10406                    cpi = AppGlobals.getPackageManager().
10407                        resolveContentProvider(name,
10408                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10409                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10410                } catch (RemoteException ex) {
10411                }
10412                if (cpi == null) {
10413                    return null;
10414                }
10415                // If the provider is a singleton AND
10416                // (it's a call within the same user || the provider is a
10417                // privileged app)
10418                // Then allow connecting to the singleton provider
10419                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10420                        cpi.name, cpi.flags)
10421                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10422                if (singleton) {
10423                    userId = UserHandle.USER_SYSTEM;
10424                }
10425                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10426                checkTime(startTime, "getContentProviderImpl: got app info for user");
10427
10428                String msg;
10429                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10430                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10431                        != null) {
10432                    throw new SecurityException(msg);
10433                }
10434                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10435
10436                if (!mProcessesReady
10437                        && !cpi.processName.equals("system")) {
10438                    // If this content provider does not run in the system
10439                    // process, and the system is not yet ready to run other
10440                    // processes, then fail fast instead of hanging.
10441                    throw new IllegalArgumentException(
10442                            "Attempt to launch content provider before system ready");
10443                }
10444
10445                // Make sure that the user who owns this provider is running.  If not,
10446                // we don't want to allow it to run.
10447                if (!mUserController.isUserRunningLocked(userId, 0)) {
10448                    Slog.w(TAG, "Unable to launch app "
10449                            + cpi.applicationInfo.packageName + "/"
10450                            + cpi.applicationInfo.uid + " for provider "
10451                            + name + ": user " + userId + " is stopped");
10452                    return null;
10453                }
10454
10455                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10456                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10457                cpr = mProviderMap.getProviderByClass(comp, userId);
10458                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10459                final boolean firstClass = cpr == null;
10460                if (firstClass) {
10461                    final long ident = Binder.clearCallingIdentity();
10462
10463                    // If permissions need a review before any of the app components can run,
10464                    // we return no provider and launch a review activity if the calling app
10465                    // is in the foreground.
10466                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10467                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10468                            return null;
10469                        }
10470                    }
10471
10472                    try {
10473                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10474                        ApplicationInfo ai =
10475                            AppGlobals.getPackageManager().
10476                                getApplicationInfo(
10477                                        cpi.applicationInfo.packageName,
10478                                        STOCK_PM_FLAGS, userId);
10479                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10480                        if (ai == null) {
10481                            Slog.w(TAG, "No package info for content provider "
10482                                    + cpi.name);
10483                            return null;
10484                        }
10485                        ai = getAppInfoForUser(ai, userId);
10486                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10487                    } catch (RemoteException ex) {
10488                        // pm is in same process, this will never happen.
10489                    } finally {
10490                        Binder.restoreCallingIdentity(ident);
10491                    }
10492                }
10493
10494                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10495
10496                if (r != null && cpr.canRunHere(r)) {
10497                    // If this is a multiprocess provider, then just return its
10498                    // info and allow the caller to instantiate it.  Only do
10499                    // this if the provider is the same user as the caller's
10500                    // process, or can run as root (so can be in any process).
10501                    return cpr.newHolder(null);
10502                }
10503
10504                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10505                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10506                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10507
10508                // This is single process, and our app is now connecting to it.
10509                // See if we are already in the process of launching this
10510                // provider.
10511                final int N = mLaunchingProviders.size();
10512                int i;
10513                for (i = 0; i < N; i++) {
10514                    if (mLaunchingProviders.get(i) == cpr) {
10515                        break;
10516                    }
10517                }
10518
10519                // If the provider is not already being launched, then get it
10520                // started.
10521                if (i >= N) {
10522                    final long origId = Binder.clearCallingIdentity();
10523
10524                    try {
10525                        // Content provider is now in use, its package can't be stopped.
10526                        try {
10527                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10528                            AppGlobals.getPackageManager().setPackageStoppedState(
10529                                    cpr.appInfo.packageName, false, userId);
10530                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10531                        } catch (RemoteException e) {
10532                        } catch (IllegalArgumentException e) {
10533                            Slog.w(TAG, "Failed trying to unstop package "
10534                                    + cpr.appInfo.packageName + ": " + e);
10535                        }
10536
10537                        // Use existing process if already started
10538                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10539                        ProcessRecord proc = getProcessRecordLocked(
10540                                cpi.processName, cpr.appInfo.uid, false);
10541                        if (proc != null && proc.thread != null) {
10542                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10543                                    "Installing in existing process " + proc);
10544                            if (!proc.pubProviders.containsKey(cpi.name)) {
10545                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10546                                proc.pubProviders.put(cpi.name, cpr);
10547                                try {
10548                                    proc.thread.scheduleInstallProvider(cpi);
10549                                } catch (RemoteException e) {
10550                                }
10551                            }
10552                        } else {
10553                            checkTime(startTime, "getContentProviderImpl: before start process");
10554                            proc = startProcessLocked(cpi.processName,
10555                                    cpr.appInfo, false, 0, "content provider",
10556                                    new ComponentName(cpi.applicationInfo.packageName,
10557                                            cpi.name), false, false, false);
10558                            checkTime(startTime, "getContentProviderImpl: after start process");
10559                            if (proc == null) {
10560                                Slog.w(TAG, "Unable to launch app "
10561                                        + cpi.applicationInfo.packageName + "/"
10562                                        + cpi.applicationInfo.uid + " for provider "
10563                                        + name + ": process is bad");
10564                                return null;
10565                            }
10566                        }
10567                        cpr.launchingApp = proc;
10568                        mLaunchingProviders.add(cpr);
10569                    } finally {
10570                        Binder.restoreCallingIdentity(origId);
10571                    }
10572                }
10573
10574                checkTime(startTime, "getContentProviderImpl: updating data structures");
10575
10576                // Make sure the provider is published (the same provider class
10577                // may be published under multiple names).
10578                if (firstClass) {
10579                    mProviderMap.putProviderByClass(comp, cpr);
10580                }
10581
10582                mProviderMap.putProviderByName(name, cpr);
10583                conn = incProviderCountLocked(r, cpr, token, stable);
10584                if (conn != null) {
10585                    conn.waiting = true;
10586                }
10587            }
10588            checkTime(startTime, "getContentProviderImpl: done!");
10589        }
10590
10591        // Wait for the provider to be published...
10592        synchronized (cpr) {
10593            while (cpr.provider == null) {
10594                if (cpr.launchingApp == null) {
10595                    Slog.w(TAG, "Unable to launch app "
10596                            + cpi.applicationInfo.packageName + "/"
10597                            + cpi.applicationInfo.uid + " for provider "
10598                            + name + ": launching app became null");
10599                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10600                            UserHandle.getUserId(cpi.applicationInfo.uid),
10601                            cpi.applicationInfo.packageName,
10602                            cpi.applicationInfo.uid, name);
10603                    return null;
10604                }
10605                try {
10606                    if (DEBUG_MU) Slog.v(TAG_MU,
10607                            "Waiting to start provider " + cpr
10608                            + " launchingApp=" + cpr.launchingApp);
10609                    if (conn != null) {
10610                        conn.waiting = true;
10611                    }
10612                    cpr.wait();
10613                } catch (InterruptedException ex) {
10614                } finally {
10615                    if (conn != null) {
10616                        conn.waiting = false;
10617                    }
10618                }
10619            }
10620        }
10621        return cpr != null ? cpr.newHolder(conn) : null;
10622    }
10623
10624    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10625            ProcessRecord r, final int userId) {
10626        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10627                cpi.packageName, userId)) {
10628
10629            final boolean callerForeground = r == null || r.setSchedGroup
10630                    != ProcessList.SCHED_GROUP_BACKGROUND;
10631
10632            // Show a permission review UI only for starting from a foreground app
10633            if (!callerForeground) {
10634                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10635                        + cpi.packageName + " requires a permissions review");
10636                return false;
10637            }
10638
10639            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10640            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10641                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10642            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10643
10644            if (DEBUG_PERMISSIONS_REVIEW) {
10645                Slog.i(TAG, "u" + userId + " Launching permission review "
10646                        + "for package " + cpi.packageName);
10647            }
10648
10649            final UserHandle userHandle = new UserHandle(userId);
10650            mHandler.post(new Runnable() {
10651                @Override
10652                public void run() {
10653                    mContext.startActivityAsUser(intent, userHandle);
10654                }
10655            });
10656
10657            return false;
10658        }
10659
10660        return true;
10661    }
10662
10663    PackageManagerInternal getPackageManagerInternalLocked() {
10664        if (mPackageManagerInt == null) {
10665            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10666        }
10667        return mPackageManagerInt;
10668    }
10669
10670    @Override
10671    public final ContentProviderHolder getContentProvider(
10672            IApplicationThread caller, String name, int userId, boolean stable) {
10673        enforceNotIsolatedCaller("getContentProvider");
10674        if (caller == null) {
10675            String msg = "null IApplicationThread when getting content provider "
10676                    + name;
10677            Slog.w(TAG, msg);
10678            throw new SecurityException(msg);
10679        }
10680        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10681        // with cross-user grant.
10682        return getContentProviderImpl(caller, name, null, stable, userId);
10683    }
10684
10685    public ContentProviderHolder getContentProviderExternal(
10686            String name, int userId, IBinder token) {
10687        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10688            "Do not have permission in call getContentProviderExternal()");
10689        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10690                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10691        return getContentProviderExternalUnchecked(name, token, userId);
10692    }
10693
10694    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10695            IBinder token, int userId) {
10696        return getContentProviderImpl(null, name, token, true, userId);
10697    }
10698
10699    /**
10700     * Drop a content provider from a ProcessRecord's bookkeeping
10701     */
10702    public void removeContentProvider(IBinder connection, boolean stable) {
10703        enforceNotIsolatedCaller("removeContentProvider");
10704        long ident = Binder.clearCallingIdentity();
10705        try {
10706            synchronized (this) {
10707                ContentProviderConnection conn;
10708                try {
10709                    conn = (ContentProviderConnection)connection;
10710                } catch (ClassCastException e) {
10711                    String msg ="removeContentProvider: " + connection
10712                            + " not a ContentProviderConnection";
10713                    Slog.w(TAG, msg);
10714                    throw new IllegalArgumentException(msg);
10715                }
10716                if (conn == null) {
10717                    throw new NullPointerException("connection is null");
10718                }
10719                if (decProviderCountLocked(conn, null, null, stable)) {
10720                    updateOomAdjLocked();
10721                }
10722            }
10723        } finally {
10724            Binder.restoreCallingIdentity(ident);
10725        }
10726    }
10727
10728    public void removeContentProviderExternal(String name, IBinder token) {
10729        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10730            "Do not have permission in call removeContentProviderExternal()");
10731        int userId = UserHandle.getCallingUserId();
10732        long ident = Binder.clearCallingIdentity();
10733        try {
10734            removeContentProviderExternalUnchecked(name, token, userId);
10735        } finally {
10736            Binder.restoreCallingIdentity(ident);
10737        }
10738    }
10739
10740    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10741        synchronized (this) {
10742            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10743            if(cpr == null) {
10744                //remove from mProvidersByClass
10745                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10746                return;
10747            }
10748
10749            //update content provider record entry info
10750            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10751            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10752            if (localCpr.hasExternalProcessHandles()) {
10753                if (localCpr.removeExternalProcessHandleLocked(token)) {
10754                    updateOomAdjLocked();
10755                } else {
10756                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10757                            + " with no external reference for token: "
10758                            + token + ".");
10759                }
10760            } else {
10761                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10762                        + " with no external references.");
10763            }
10764        }
10765    }
10766
10767    public final void publishContentProviders(IApplicationThread caller,
10768            List<ContentProviderHolder> providers) {
10769        if (providers == null) {
10770            return;
10771        }
10772
10773        enforceNotIsolatedCaller("publishContentProviders");
10774        synchronized (this) {
10775            final ProcessRecord r = getRecordForAppLocked(caller);
10776            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10777            if (r == null) {
10778                throw new SecurityException(
10779                        "Unable to find app for caller " + caller
10780                      + " (pid=" + Binder.getCallingPid()
10781                      + ") when publishing content providers");
10782            }
10783
10784            final long origId = Binder.clearCallingIdentity();
10785
10786            final int N = providers.size();
10787            for (int i = 0; i < N; i++) {
10788                ContentProviderHolder src = providers.get(i);
10789                if (src == null || src.info == null || src.provider == null) {
10790                    continue;
10791                }
10792                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10793                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10794                if (dst != null) {
10795                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10796                    mProviderMap.putProviderByClass(comp, dst);
10797                    String names[] = dst.info.authority.split(";");
10798                    for (int j = 0; j < names.length; j++) {
10799                        mProviderMap.putProviderByName(names[j], dst);
10800                    }
10801
10802                    int launchingCount = mLaunchingProviders.size();
10803                    int j;
10804                    boolean wasInLaunchingProviders = false;
10805                    for (j = 0; j < launchingCount; j++) {
10806                        if (mLaunchingProviders.get(j) == dst) {
10807                            mLaunchingProviders.remove(j);
10808                            wasInLaunchingProviders = true;
10809                            j--;
10810                            launchingCount--;
10811                        }
10812                    }
10813                    if (wasInLaunchingProviders) {
10814                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10815                    }
10816                    synchronized (dst) {
10817                        dst.provider = src.provider;
10818                        dst.proc = r;
10819                        dst.notifyAll();
10820                    }
10821                    updateOomAdjLocked(r);
10822                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10823                            src.info.authority);
10824                }
10825            }
10826
10827            Binder.restoreCallingIdentity(origId);
10828        }
10829    }
10830
10831    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10832        ContentProviderConnection conn;
10833        try {
10834            conn = (ContentProviderConnection)connection;
10835        } catch (ClassCastException e) {
10836            String msg ="refContentProvider: " + connection
10837                    + " not a ContentProviderConnection";
10838            Slog.w(TAG, msg);
10839            throw new IllegalArgumentException(msg);
10840        }
10841        if (conn == null) {
10842            throw new NullPointerException("connection is null");
10843        }
10844
10845        synchronized (this) {
10846            if (stable > 0) {
10847                conn.numStableIncs += stable;
10848            }
10849            stable = conn.stableCount + stable;
10850            if (stable < 0) {
10851                throw new IllegalStateException("stableCount < 0: " + stable);
10852            }
10853
10854            if (unstable > 0) {
10855                conn.numUnstableIncs += unstable;
10856            }
10857            unstable = conn.unstableCount + unstable;
10858            if (unstable < 0) {
10859                throw new IllegalStateException("unstableCount < 0: " + unstable);
10860            }
10861
10862            if ((stable+unstable) <= 0) {
10863                throw new IllegalStateException("ref counts can't go to zero here: stable="
10864                        + stable + " unstable=" + unstable);
10865            }
10866            conn.stableCount = stable;
10867            conn.unstableCount = unstable;
10868            return !conn.dead;
10869        }
10870    }
10871
10872    public void unstableProviderDied(IBinder connection) {
10873        ContentProviderConnection conn;
10874        try {
10875            conn = (ContentProviderConnection)connection;
10876        } catch (ClassCastException e) {
10877            String msg ="refContentProvider: " + connection
10878                    + " not a ContentProviderConnection";
10879            Slog.w(TAG, msg);
10880            throw new IllegalArgumentException(msg);
10881        }
10882        if (conn == null) {
10883            throw new NullPointerException("connection is null");
10884        }
10885
10886        // Safely retrieve the content provider associated with the connection.
10887        IContentProvider provider;
10888        synchronized (this) {
10889            provider = conn.provider.provider;
10890        }
10891
10892        if (provider == null) {
10893            // Um, yeah, we're way ahead of you.
10894            return;
10895        }
10896
10897        // Make sure the caller is being honest with us.
10898        if (provider.asBinder().pingBinder()) {
10899            // Er, no, still looks good to us.
10900            synchronized (this) {
10901                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10902                        + " says " + conn + " died, but we don't agree");
10903                return;
10904            }
10905        }
10906
10907        // Well look at that!  It's dead!
10908        synchronized (this) {
10909            if (conn.provider.provider != provider) {
10910                // But something changed...  good enough.
10911                return;
10912            }
10913
10914            ProcessRecord proc = conn.provider.proc;
10915            if (proc == null || proc.thread == null) {
10916                // Seems like the process is already cleaned up.
10917                return;
10918            }
10919
10920            // As far as we're concerned, this is just like receiving a
10921            // death notification...  just a bit prematurely.
10922            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10923                    + ") early provider death");
10924            final long ident = Binder.clearCallingIdentity();
10925            try {
10926                appDiedLocked(proc);
10927            } finally {
10928                Binder.restoreCallingIdentity(ident);
10929            }
10930        }
10931    }
10932
10933    @Override
10934    public void appNotRespondingViaProvider(IBinder connection) {
10935        enforceCallingPermission(
10936                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10937
10938        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10939        if (conn == null) {
10940            Slog.w(TAG, "ContentProviderConnection is null");
10941            return;
10942        }
10943
10944        final ProcessRecord host = conn.provider.proc;
10945        if (host == null) {
10946            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10947            return;
10948        }
10949
10950        mHandler.post(new Runnable() {
10951            @Override
10952            public void run() {
10953                mAppErrors.appNotResponding(host, null, null, false,
10954                        "ContentProvider not responding");
10955            }
10956        });
10957    }
10958
10959    public final void installSystemProviders() {
10960        List<ProviderInfo> providers;
10961        synchronized (this) {
10962            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10963            providers = generateApplicationProvidersLocked(app);
10964            if (providers != null) {
10965                for (int i=providers.size()-1; i>=0; i--) {
10966                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10967                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10968                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10969                                + ": not system .apk");
10970                        providers.remove(i);
10971                    }
10972                }
10973            }
10974        }
10975        if (providers != null) {
10976            mSystemThread.installSystemProviders(providers);
10977        }
10978
10979        mCoreSettingsObserver = new CoreSettingsObserver(this);
10980        mFontScaleSettingObserver = new FontScaleSettingObserver();
10981
10982        //mUsageStatsService.monitorPackages();
10983    }
10984
10985    private void startPersistentApps(int matchFlags) {
10986        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
10987
10988        synchronized (this) {
10989            try {
10990                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
10991                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
10992                for (ApplicationInfo app : apps) {
10993                    if (!"android".equals(app.packageName)) {
10994                        addAppLocked(app, false, null /* ABI override */);
10995                    }
10996                }
10997            } catch (RemoteException ex) {
10998            }
10999        }
11000    }
11001
11002    /**
11003     * When a user is unlocked, we need to install encryption-unaware providers
11004     * belonging to any running apps.
11005     */
11006    private void installEncryptionUnawareProviders(int userId) {
11007        if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
11008            // TODO: eventually pivot this back to look at current user state,
11009            // similar to the comment in UserManager.isUserUnlocked(), but for
11010            // now, if we started apps when "unlocked" then unaware providers
11011            // have already been spun up.
11012            return;
11013        }
11014
11015        // We're only interested in providers that are encryption unaware, and
11016        // we don't care about uninstalled apps, since there's no way they're
11017        // running at this point.
11018        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11019
11020        synchronized (this) {
11021            final int NP = mProcessNames.getMap().size();
11022            for (int ip = 0; ip < NP; ip++) {
11023                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11024                final int NA = apps.size();
11025                for (int ia = 0; ia < NA; ia++) {
11026                    final ProcessRecord app = apps.valueAt(ia);
11027                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11028
11029                    final int NG = app.pkgList.size();
11030                    for (int ig = 0; ig < NG; ig++) {
11031                        try {
11032                            final String pkgName = app.pkgList.keyAt(ig);
11033                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11034                                    .getPackageInfo(pkgName, matchFlags, userId);
11035                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11036                                for (ProviderInfo provInfo : pkgInfo.providers) {
11037                                    Log.v(TAG, "Installing " + provInfo);
11038                                    app.thread.scheduleInstallProvider(provInfo);
11039                                }
11040                            }
11041                        } catch (RemoteException ignored) {
11042                        }
11043                    }
11044                }
11045            }
11046        }
11047    }
11048
11049    /**
11050     * Allows apps to retrieve the MIME type of a URI.
11051     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11052     * users, then it does not need permission to access the ContentProvider.
11053     * Either, it needs cross-user uri grants.
11054     *
11055     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11056     *
11057     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11058     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11059     */
11060    public String getProviderMimeType(Uri uri, int userId) {
11061        enforceNotIsolatedCaller("getProviderMimeType");
11062        final String name = uri.getAuthority();
11063        int callingUid = Binder.getCallingUid();
11064        int callingPid = Binder.getCallingPid();
11065        long ident = 0;
11066        boolean clearedIdentity = false;
11067        synchronized (this) {
11068            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11069        }
11070        if (canClearIdentity(callingPid, callingUid, userId)) {
11071            clearedIdentity = true;
11072            ident = Binder.clearCallingIdentity();
11073        }
11074        ContentProviderHolder holder = null;
11075        try {
11076            holder = getContentProviderExternalUnchecked(name, null, userId);
11077            if (holder != null) {
11078                return holder.provider.getType(uri);
11079            }
11080        } catch (RemoteException e) {
11081            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11082            return null;
11083        } finally {
11084            // We need to clear the identity to call removeContentProviderExternalUnchecked
11085            if (!clearedIdentity) {
11086                ident = Binder.clearCallingIdentity();
11087            }
11088            try {
11089                if (holder != null) {
11090                    removeContentProviderExternalUnchecked(name, null, userId);
11091                }
11092            } finally {
11093                Binder.restoreCallingIdentity(ident);
11094            }
11095        }
11096
11097        return null;
11098    }
11099
11100    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11101        if (UserHandle.getUserId(callingUid) == userId) {
11102            return true;
11103        }
11104        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11105                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11106                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11107                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11108                return true;
11109        }
11110        return false;
11111    }
11112
11113    // =========================================================
11114    // GLOBAL MANAGEMENT
11115    // =========================================================
11116
11117    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11118            boolean isolated, int isolatedUid) {
11119        String proc = customProcess != null ? customProcess : info.processName;
11120        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11121        final int userId = UserHandle.getUserId(info.uid);
11122        int uid = info.uid;
11123        if (isolated) {
11124            if (isolatedUid == 0) {
11125                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11126                while (true) {
11127                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11128                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11129                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11130                    }
11131                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11132                    mNextIsolatedProcessUid++;
11133                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11134                        // No process for this uid, use it.
11135                        break;
11136                    }
11137                    stepsLeft--;
11138                    if (stepsLeft <= 0) {
11139                        return null;
11140                    }
11141                }
11142            } else {
11143                // Special case for startIsolatedProcess (internal only), where
11144                // the uid of the isolated process is specified by the caller.
11145                uid = isolatedUid;
11146            }
11147        }
11148        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11149        if (!mBooted && !mBooting
11150                && userId == UserHandle.USER_SYSTEM
11151                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11152            r.persistent = true;
11153        }
11154        addProcessNameLocked(r);
11155        return r;
11156    }
11157
11158    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11159            String abiOverride) {
11160        ProcessRecord app;
11161        if (!isolated) {
11162            app = getProcessRecordLocked(info.processName, info.uid, true);
11163        } else {
11164            app = null;
11165        }
11166
11167        if (app == null) {
11168            app = newProcessRecordLocked(info, null, isolated, 0);
11169            updateLruProcessLocked(app, false, null);
11170            updateOomAdjLocked();
11171        }
11172
11173        // This package really, really can not be stopped.
11174        try {
11175            AppGlobals.getPackageManager().setPackageStoppedState(
11176                    info.packageName, false, UserHandle.getUserId(app.uid));
11177        } catch (RemoteException e) {
11178        } catch (IllegalArgumentException e) {
11179            Slog.w(TAG, "Failed trying to unstop package "
11180                    + info.packageName + ": " + e);
11181        }
11182
11183        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11184            app.persistent = true;
11185            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11186        }
11187        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11188            mPersistentStartingProcesses.add(app);
11189            startProcessLocked(app, "added application", app.processName, abiOverride,
11190                    null /* entryPoint */, null /* entryPointArgs */);
11191        }
11192
11193        return app;
11194    }
11195
11196    public void unhandledBack() {
11197        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11198                "unhandledBack()");
11199
11200        synchronized(this) {
11201            final long origId = Binder.clearCallingIdentity();
11202            try {
11203                getFocusedStack().unhandledBackLocked();
11204            } finally {
11205                Binder.restoreCallingIdentity(origId);
11206            }
11207        }
11208    }
11209
11210    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11211        enforceNotIsolatedCaller("openContentUri");
11212        final int userId = UserHandle.getCallingUserId();
11213        String name = uri.getAuthority();
11214        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11215        ParcelFileDescriptor pfd = null;
11216        if (cph != null) {
11217            // We record the binder invoker's uid in thread-local storage before
11218            // going to the content provider to open the file.  Later, in the code
11219            // that handles all permissions checks, we look for this uid and use
11220            // that rather than the Activity Manager's own uid.  The effect is that
11221            // we do the check against the caller's permissions even though it looks
11222            // to the content provider like the Activity Manager itself is making
11223            // the request.
11224            Binder token = new Binder();
11225            sCallerIdentity.set(new Identity(
11226                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11227            try {
11228                pfd = cph.provider.openFile(null, uri, "r", null, token);
11229            } catch (FileNotFoundException e) {
11230                // do nothing; pfd will be returned null
11231            } finally {
11232                // Ensure that whatever happens, we clean up the identity state
11233                sCallerIdentity.remove();
11234                // Ensure we're done with the provider.
11235                removeContentProviderExternalUnchecked(name, null, userId);
11236            }
11237        } else {
11238            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11239        }
11240        return pfd;
11241    }
11242
11243    // Actually is sleeping or shutting down or whatever else in the future
11244    // is an inactive state.
11245    public boolean isSleepingOrShuttingDown() {
11246        return isSleeping() || mShuttingDown;
11247    }
11248
11249    public boolean isSleeping() {
11250        return mSleeping;
11251    }
11252
11253    void onWakefulnessChanged(int wakefulness) {
11254        synchronized(this) {
11255            mWakefulness = wakefulness;
11256            updateSleepIfNeededLocked();
11257        }
11258    }
11259
11260    void finishRunningVoiceLocked() {
11261        if (mRunningVoice != null) {
11262            mRunningVoice = null;
11263            mVoiceWakeLock.release();
11264            updateSleepIfNeededLocked();
11265        }
11266    }
11267
11268    void startTimeTrackingFocusedActivityLocked() {
11269        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11270            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11271        }
11272    }
11273
11274    void updateSleepIfNeededLocked() {
11275        if (mSleeping && !shouldSleepLocked()) {
11276            mSleeping = false;
11277            startTimeTrackingFocusedActivityLocked();
11278            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11279            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11280            updateOomAdjLocked();
11281        } else if (!mSleeping && shouldSleepLocked()) {
11282            mSleeping = true;
11283            if (mCurAppTimeTracker != null) {
11284                mCurAppTimeTracker.stop();
11285            }
11286            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11287            mStackSupervisor.goingToSleepLocked();
11288            updateOomAdjLocked();
11289
11290            // Initialize the wake times of all processes.
11291            checkExcessivePowerUsageLocked(false);
11292            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11293            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11294            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11295        }
11296    }
11297
11298    private boolean shouldSleepLocked() {
11299        // Resume applications while running a voice interactor.
11300        if (mRunningVoice != null) {
11301            return false;
11302        }
11303
11304        // TODO: Transform the lock screen state into a sleep token instead.
11305        switch (mWakefulness) {
11306            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11307            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11308            case PowerManagerInternal.WAKEFULNESS_DOZING:
11309                // Pause applications whenever the lock screen is shown or any sleep
11310                // tokens have been acquired.
11311                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11312            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11313            default:
11314                // If we're asleep then pause applications unconditionally.
11315                return true;
11316        }
11317    }
11318
11319    /** Pokes the task persister. */
11320    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11321        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11322    }
11323
11324    /** Notifies all listeners when the task stack has changed. */
11325    void notifyTaskStackChangedLocked() {
11326        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11327        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11328        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11329        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11330    }
11331
11332    /** Notifies all listeners when an Activity is pinned. */
11333    void notifyActivityPinnedLocked() {
11334        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11335        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11336    }
11337
11338    /**
11339     * Notifies all listeners when an attempt was made to start an an activity that is already
11340     * running in the pinned stack and the activity was not actually started, but the task is
11341     * either brought to the front or a new Intent is delivered to it.
11342     */
11343    void notifyPinnedActivityRestartAttemptLocked() {
11344        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11345        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11346    }
11347
11348    /** Notifies all listeners when the pinned stack animation ends. */
11349    @Override
11350    public void notifyPinnedStackAnimationEnded() {
11351        synchronized (this) {
11352            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11353            mHandler.obtainMessage(
11354                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11355        }
11356    }
11357
11358    @Override
11359    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11360        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11361    }
11362
11363    @Override
11364    public boolean shutdown(int timeout) {
11365        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11366                != PackageManager.PERMISSION_GRANTED) {
11367            throw new SecurityException("Requires permission "
11368                    + android.Manifest.permission.SHUTDOWN);
11369        }
11370
11371        boolean timedout = false;
11372
11373        synchronized(this) {
11374            mShuttingDown = true;
11375            updateEventDispatchingLocked();
11376            timedout = mStackSupervisor.shutdownLocked(timeout);
11377        }
11378
11379        mAppOpsService.shutdown();
11380        if (mUsageStatsService != null) {
11381            mUsageStatsService.prepareShutdown();
11382        }
11383        mBatteryStatsService.shutdown();
11384        synchronized (this) {
11385            mProcessStats.shutdownLocked();
11386            notifyTaskPersisterLocked(null, true);
11387        }
11388
11389        return timedout;
11390    }
11391
11392    public final void activitySlept(IBinder token) {
11393        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11394
11395        final long origId = Binder.clearCallingIdentity();
11396
11397        synchronized (this) {
11398            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11399            if (r != null) {
11400                mStackSupervisor.activitySleptLocked(r);
11401            }
11402        }
11403
11404        Binder.restoreCallingIdentity(origId);
11405    }
11406
11407    private String lockScreenShownToString() {
11408        switch (mLockScreenShown) {
11409            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11410            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11411            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11412            default: return "Unknown=" + mLockScreenShown;
11413        }
11414    }
11415
11416    void logLockScreen(String msg) {
11417        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11418                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11419                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11420                + " mSleeping=" + mSleeping);
11421    }
11422
11423    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11424        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11425        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11426        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11427            boolean wasRunningVoice = mRunningVoice != null;
11428            mRunningVoice = session;
11429            if (!wasRunningVoice) {
11430                mVoiceWakeLock.acquire();
11431                updateSleepIfNeededLocked();
11432            }
11433        }
11434    }
11435
11436    private void updateEventDispatchingLocked() {
11437        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11438    }
11439
11440    public void setLockScreenShown(boolean shown) {
11441        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11442                != PackageManager.PERMISSION_GRANTED) {
11443            throw new SecurityException("Requires permission "
11444                    + android.Manifest.permission.DEVICE_POWER);
11445        }
11446
11447        synchronized(this) {
11448            long ident = Binder.clearCallingIdentity();
11449            try {
11450                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11451                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11452                updateSleepIfNeededLocked();
11453            } finally {
11454                Binder.restoreCallingIdentity(ident);
11455            }
11456        }
11457    }
11458
11459    @Override
11460    public void notifyLockedProfile(@UserIdInt int userId) {
11461        try {
11462            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11463                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11464            }
11465        } catch (RemoteException ex) {
11466            throw new SecurityException("Fail to check is caller a privileged app", ex);
11467        }
11468
11469        synchronized (this) {
11470            if (mStackSupervisor.isFocusedUserLockedProfile()) {
11471                final long ident = Binder.clearCallingIdentity();
11472                try {
11473                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11474                    // Get the focused task before launching launcher.
11475
11476                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11477
11478                        // If there is no device lock, we will show the profile's credential page.
11479                        // startActivityFromRecentsInner is intercepted and will forward user to it.
11480                        if (mFocusedActivity != null) {
11481                            mStackSupervisor.startActivityFromRecentsInner(
11482                                    mFocusedActivity.task.taskId, null);
11483                        }
11484                    } else {
11485                        // Showing launcher to avoid user entering credential twice.
11486                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11487                    }
11488                } finally {
11489                    Binder.restoreCallingIdentity(ident);
11490                }
11491            }
11492        }
11493    }
11494
11495    @Override
11496    public void stopAppSwitches() {
11497        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11498                != PackageManager.PERMISSION_GRANTED) {
11499            throw new SecurityException("viewquires permission "
11500                    + android.Manifest.permission.STOP_APP_SWITCHES);
11501        }
11502
11503        synchronized(this) {
11504            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11505                    + APP_SWITCH_DELAY_TIME;
11506            mDidAppSwitch = false;
11507            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11508            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11509            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11510        }
11511    }
11512
11513    public void resumeAppSwitches() {
11514        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11515                != PackageManager.PERMISSION_GRANTED) {
11516            throw new SecurityException("Requires permission "
11517                    + android.Manifest.permission.STOP_APP_SWITCHES);
11518        }
11519
11520        synchronized(this) {
11521            // Note that we don't execute any pending app switches... we will
11522            // let those wait until either the timeout, or the next start
11523            // activity request.
11524            mAppSwitchesAllowedTime = 0;
11525        }
11526    }
11527
11528    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11529            int callingPid, int callingUid, String name) {
11530        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11531            return true;
11532        }
11533
11534        int perm = checkComponentPermission(
11535                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11536                sourceUid, -1, true);
11537        if (perm == PackageManager.PERMISSION_GRANTED) {
11538            return true;
11539        }
11540
11541        // If the actual IPC caller is different from the logical source, then
11542        // also see if they are allowed to control app switches.
11543        if (callingUid != -1 && callingUid != sourceUid) {
11544            perm = checkComponentPermission(
11545                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11546                    callingUid, -1, true);
11547            if (perm == PackageManager.PERMISSION_GRANTED) {
11548                return true;
11549            }
11550        }
11551
11552        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11553        return false;
11554    }
11555
11556    public void setDebugApp(String packageName, boolean waitForDebugger,
11557            boolean persistent) {
11558        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11559                "setDebugApp()");
11560
11561        long ident = Binder.clearCallingIdentity();
11562        try {
11563            // Note that this is not really thread safe if there are multiple
11564            // callers into it at the same time, but that's not a situation we
11565            // care about.
11566            if (persistent) {
11567                final ContentResolver resolver = mContext.getContentResolver();
11568                Settings.Global.putString(
11569                    resolver, Settings.Global.DEBUG_APP,
11570                    packageName);
11571                Settings.Global.putInt(
11572                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11573                    waitForDebugger ? 1 : 0);
11574            }
11575
11576            synchronized (this) {
11577                if (!persistent) {
11578                    mOrigDebugApp = mDebugApp;
11579                    mOrigWaitForDebugger = mWaitForDebugger;
11580                }
11581                mDebugApp = packageName;
11582                mWaitForDebugger = waitForDebugger;
11583                mDebugTransient = !persistent;
11584                if (packageName != null) {
11585                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11586                            false, UserHandle.USER_ALL, "set debug app");
11587                }
11588            }
11589        } finally {
11590            Binder.restoreCallingIdentity(ident);
11591        }
11592    }
11593
11594    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11595        synchronized (this) {
11596            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11597            if (!isDebuggable) {
11598                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11599                    throw new SecurityException("Process not debuggable: " + app.packageName);
11600                }
11601            }
11602
11603            mTrackAllocationApp = processName;
11604        }
11605    }
11606
11607    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11608        synchronized (this) {
11609            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11610            if (!isDebuggable) {
11611                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11612                    throw new SecurityException("Process not debuggable: " + app.packageName);
11613                }
11614            }
11615            mProfileApp = processName;
11616            mProfileFile = profilerInfo.profileFile;
11617            if (mProfileFd != null) {
11618                try {
11619                    mProfileFd.close();
11620                } catch (IOException e) {
11621                }
11622                mProfileFd = null;
11623            }
11624            mProfileFd = profilerInfo.profileFd;
11625            mSamplingInterval = profilerInfo.samplingInterval;
11626            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11627            mProfileType = 0;
11628        }
11629    }
11630
11631    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11632        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11633        if (!isDebuggable) {
11634            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11635                throw new SecurityException("Process not debuggable: " + app.packageName);
11636            }
11637        }
11638        mNativeDebuggingApp = processName;
11639    }
11640
11641    @Override
11642    public void setAlwaysFinish(boolean enabled) {
11643        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11644                "setAlwaysFinish()");
11645
11646        long ident = Binder.clearCallingIdentity();
11647        try {
11648            Settings.Global.putInt(
11649                    mContext.getContentResolver(),
11650                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11651
11652            synchronized (this) {
11653                mAlwaysFinishActivities = enabled;
11654            }
11655        } finally {
11656            Binder.restoreCallingIdentity(ident);
11657        }
11658    }
11659
11660    @Override
11661    public void setLenientBackgroundCheck(boolean enabled) {
11662        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11663                "setLenientBackgroundCheck()");
11664
11665        long ident = Binder.clearCallingIdentity();
11666        try {
11667            Settings.Global.putInt(
11668                    mContext.getContentResolver(),
11669                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11670
11671            synchronized (this) {
11672                mLenientBackgroundCheck = enabled;
11673            }
11674        } finally {
11675            Binder.restoreCallingIdentity(ident);
11676        }
11677    }
11678
11679    @Override
11680    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11681        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11682                "setActivityController()");
11683        synchronized (this) {
11684            mController = controller;
11685            mControllerIsAMonkey = imAMonkey;
11686            Watchdog.getInstance().setActivityController(controller);
11687        }
11688    }
11689
11690    @Override
11691    public void setUserIsMonkey(boolean userIsMonkey) {
11692        synchronized (this) {
11693            synchronized (mPidsSelfLocked) {
11694                final int callingPid = Binder.getCallingPid();
11695                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11696                if (precessRecord == null) {
11697                    throw new SecurityException("Unknown process: " + callingPid);
11698                }
11699                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11700                    throw new SecurityException("Only an instrumentation process "
11701                            + "with a UiAutomation can call setUserIsMonkey");
11702                }
11703            }
11704            mUserIsMonkey = userIsMonkey;
11705        }
11706    }
11707
11708    @Override
11709    public boolean isUserAMonkey() {
11710        synchronized (this) {
11711            // If there is a controller also implies the user is a monkey.
11712            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11713        }
11714    }
11715
11716    public void requestBugReport(int bugreportType) {
11717        String service = null;
11718        switch (bugreportType) {
11719            case ActivityManager.BUGREPORT_OPTION_FULL:
11720                service = "bugreport";
11721                break;
11722            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11723                service = "bugreportplus";
11724                break;
11725            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11726                service = "bugreportremote";
11727                break;
11728        }
11729        if (service == null) {
11730            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11731                    + bugreportType);
11732        }
11733        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11734        SystemProperties.set("ctl.start", service);
11735    }
11736
11737    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11738        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11739    }
11740
11741    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11742        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11743            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11744        }
11745        return KEY_DISPATCHING_TIMEOUT;
11746    }
11747
11748    @Override
11749    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11750        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11751                != PackageManager.PERMISSION_GRANTED) {
11752            throw new SecurityException("Requires permission "
11753                    + android.Manifest.permission.FILTER_EVENTS);
11754        }
11755        ProcessRecord proc;
11756        long timeout;
11757        synchronized (this) {
11758            synchronized (mPidsSelfLocked) {
11759                proc = mPidsSelfLocked.get(pid);
11760            }
11761            timeout = getInputDispatchingTimeoutLocked(proc);
11762        }
11763
11764        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11765            return -1;
11766        }
11767
11768        return timeout;
11769    }
11770
11771    /**
11772     * Handle input dispatching timeouts.
11773     * Returns whether input dispatching should be aborted or not.
11774     */
11775    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11776            final ActivityRecord activity, final ActivityRecord parent,
11777            final boolean aboveSystem, String reason) {
11778        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11779                != PackageManager.PERMISSION_GRANTED) {
11780            throw new SecurityException("Requires permission "
11781                    + android.Manifest.permission.FILTER_EVENTS);
11782        }
11783
11784        final String annotation;
11785        if (reason == null) {
11786            annotation = "Input dispatching timed out";
11787        } else {
11788            annotation = "Input dispatching timed out (" + reason + ")";
11789        }
11790
11791        if (proc != null) {
11792            synchronized (this) {
11793                if (proc.debugging) {
11794                    return false;
11795                }
11796
11797                if (mDidDexOpt) {
11798                    // Give more time since we were dexopting.
11799                    mDidDexOpt = false;
11800                    return false;
11801                }
11802
11803                if (proc.instrumentationClass != null) {
11804                    Bundle info = new Bundle();
11805                    info.putString("shortMsg", "keyDispatchingTimedOut");
11806                    info.putString("longMsg", annotation);
11807                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11808                    return true;
11809                }
11810            }
11811            mHandler.post(new Runnable() {
11812                @Override
11813                public void run() {
11814                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11815                }
11816            });
11817        }
11818
11819        return true;
11820    }
11821
11822    @Override
11823    public Bundle getAssistContextExtras(int requestType) {
11824        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11825                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11826        if (pae == null) {
11827            return null;
11828        }
11829        synchronized (pae) {
11830            while (!pae.haveResult) {
11831                try {
11832                    pae.wait();
11833                } catch (InterruptedException e) {
11834                }
11835            }
11836        }
11837        synchronized (this) {
11838            buildAssistBundleLocked(pae, pae.result);
11839            mPendingAssistExtras.remove(pae);
11840            mUiHandler.removeCallbacks(pae);
11841        }
11842        return pae.extras;
11843    }
11844
11845    @Override
11846    public boolean isAssistDataAllowedOnCurrentActivity() {
11847        int userId;
11848        synchronized (this) {
11849            userId = mUserController.getCurrentUserIdLocked();
11850            ActivityRecord activity = getFocusedStack().topActivity();
11851            if (activity == null) {
11852                return false;
11853            }
11854            userId = activity.userId;
11855        }
11856        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11857                Context.DEVICE_POLICY_SERVICE);
11858        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11859    }
11860
11861    @Override
11862    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11863        long ident = Binder.clearCallingIdentity();
11864        try {
11865            synchronized (this) {
11866                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11867                ActivityRecord top = getFocusedStack().topActivity();
11868                if (top != caller) {
11869                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11870                            + " is not current top " + top);
11871                    return false;
11872                }
11873                if (!top.nowVisible) {
11874                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11875                            + " is not visible");
11876                    return false;
11877                }
11878            }
11879            AssistUtils utils = new AssistUtils(mContext);
11880            return utils.showSessionForActiveService(args,
11881                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11882        } finally {
11883            Binder.restoreCallingIdentity(ident);
11884        }
11885    }
11886
11887    @Override
11888    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11889            IBinder activityToken) {
11890        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11891                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11892    }
11893
11894    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11895            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11896            long timeout) {
11897        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11898                "enqueueAssistContext()");
11899        synchronized (this) {
11900            ActivityRecord activity = getFocusedStack().topActivity();
11901            if (activity == null) {
11902                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11903                return null;
11904            }
11905            if (activity.app == null || activity.app.thread == null) {
11906                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11907                return null;
11908            }
11909            if (activityToken != null) {
11910                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11911                if (activity != caller) {
11912                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11913                            + " is not current top " + activity);
11914                    return null;
11915                }
11916            }
11917            PendingAssistExtras pae;
11918            Bundle extras = new Bundle();
11919            if (args != null) {
11920                extras.putAll(args);
11921            }
11922            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11923            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11924            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11925            try {
11926                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11927                        requestType);
11928                mPendingAssistExtras.add(pae);
11929                mUiHandler.postDelayed(pae, timeout);
11930            } catch (RemoteException e) {
11931                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11932                return null;
11933            }
11934            return pae;
11935        }
11936    }
11937
11938    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11939        IResultReceiver receiver;
11940        synchronized (this) {
11941            mPendingAssistExtras.remove(pae);
11942            receiver = pae.receiver;
11943        }
11944        if (receiver != null) {
11945            // Caller wants result sent back to them.
11946            try {
11947                pae.receiver.send(0, null);
11948            } catch (RemoteException e) {
11949            }
11950        }
11951    }
11952
11953    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11954        if (result != null) {
11955            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11956        }
11957        if (pae.hint != null) {
11958            pae.extras.putBoolean(pae.hint, true);
11959        }
11960    }
11961
11962    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11963            AssistContent content, Uri referrer) {
11964        PendingAssistExtras pae = (PendingAssistExtras)token;
11965        synchronized (pae) {
11966            pae.result = extras;
11967            pae.structure = structure;
11968            pae.content = content;
11969            if (referrer != null) {
11970                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11971            }
11972            pae.haveResult = true;
11973            pae.notifyAll();
11974            if (pae.intent == null && pae.receiver == null) {
11975                // Caller is just waiting for the result.
11976                return;
11977            }
11978        }
11979
11980        // We are now ready to launch the assist activity.
11981        IResultReceiver sendReceiver = null;
11982        Bundle sendBundle = null;
11983        synchronized (this) {
11984            buildAssistBundleLocked(pae, extras);
11985            boolean exists = mPendingAssistExtras.remove(pae);
11986            mUiHandler.removeCallbacks(pae);
11987            if (!exists) {
11988                // Timed out.
11989                return;
11990            }
11991            if ((sendReceiver=pae.receiver) != null) {
11992                // Caller wants result sent back to them.
11993                sendBundle = new Bundle();
11994                sendBundle.putBundle("data", pae.extras);
11995                sendBundle.putParcelable("structure", pae.structure);
11996                sendBundle.putParcelable("content", pae.content);
11997            }
11998        }
11999        if (sendReceiver != null) {
12000            try {
12001                sendReceiver.send(0, sendBundle);
12002            } catch (RemoteException e) {
12003            }
12004            return;
12005        }
12006
12007        long ident = Binder.clearCallingIdentity();
12008        try {
12009            pae.intent.replaceExtras(pae.extras);
12010            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12011                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12012                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12013            closeSystemDialogs("assist");
12014            try {
12015                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12016            } catch (ActivityNotFoundException e) {
12017                Slog.w(TAG, "No activity to handle assist action.", e);
12018            }
12019        } finally {
12020            Binder.restoreCallingIdentity(ident);
12021        }
12022    }
12023
12024    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12025            Bundle args) {
12026        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
12027                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12028    }
12029
12030    public void registerProcessObserver(IProcessObserver observer) {
12031        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12032                "registerProcessObserver()");
12033        synchronized (this) {
12034            mProcessObservers.register(observer);
12035        }
12036    }
12037
12038    @Override
12039    public void unregisterProcessObserver(IProcessObserver observer) {
12040        synchronized (this) {
12041            mProcessObservers.unregister(observer);
12042        }
12043    }
12044
12045    @Override
12046    public void registerUidObserver(IUidObserver observer, int which) {
12047        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12048                "registerUidObserver()");
12049        synchronized (this) {
12050            mUidObservers.register(observer, which);
12051        }
12052    }
12053
12054    @Override
12055    public void unregisterUidObserver(IUidObserver observer) {
12056        synchronized (this) {
12057            mUidObservers.unregister(observer);
12058        }
12059    }
12060
12061    @Override
12062    public boolean convertFromTranslucent(IBinder token) {
12063        final long origId = Binder.clearCallingIdentity();
12064        try {
12065            synchronized (this) {
12066                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12067                if (r == null) {
12068                    return false;
12069                }
12070                final boolean translucentChanged = r.changeWindowTranslucency(true);
12071                if (translucentChanged) {
12072                    r.task.stack.releaseBackgroundResources(r);
12073                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12074                }
12075                mWindowManager.setAppFullscreen(token, true);
12076                return translucentChanged;
12077            }
12078        } finally {
12079            Binder.restoreCallingIdentity(origId);
12080        }
12081    }
12082
12083    @Override
12084    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12085        final long origId = Binder.clearCallingIdentity();
12086        try {
12087            synchronized (this) {
12088                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12089                if (r == null) {
12090                    return false;
12091                }
12092                int index = r.task.mActivities.lastIndexOf(r);
12093                if (index > 0) {
12094                    ActivityRecord under = r.task.mActivities.get(index - 1);
12095                    under.returningOptions = options;
12096                }
12097                final boolean translucentChanged = r.changeWindowTranslucency(false);
12098                if (translucentChanged) {
12099                    r.task.stack.convertActivityToTranslucent(r);
12100                }
12101                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12102                mWindowManager.setAppFullscreen(token, false);
12103                return translucentChanged;
12104            }
12105        } finally {
12106            Binder.restoreCallingIdentity(origId);
12107        }
12108    }
12109
12110    @Override
12111    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12112        final long origId = Binder.clearCallingIdentity();
12113        try {
12114            synchronized (this) {
12115                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12116                if (r != null) {
12117                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12118                }
12119            }
12120            return false;
12121        } finally {
12122            Binder.restoreCallingIdentity(origId);
12123        }
12124    }
12125
12126    @Override
12127    public boolean isBackgroundVisibleBehind(IBinder token) {
12128        final long origId = Binder.clearCallingIdentity();
12129        try {
12130            synchronized (this) {
12131                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12132                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12133                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12134                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12135                return visible;
12136            }
12137        } finally {
12138            Binder.restoreCallingIdentity(origId);
12139        }
12140    }
12141
12142    @Override
12143    public ActivityOptions getActivityOptions(IBinder token) {
12144        final long origId = Binder.clearCallingIdentity();
12145        try {
12146            synchronized (this) {
12147                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12148                if (r != null) {
12149                    final ActivityOptions activityOptions = r.pendingOptions;
12150                    r.pendingOptions = null;
12151                    return activityOptions;
12152                }
12153                return null;
12154            }
12155        } finally {
12156            Binder.restoreCallingIdentity(origId);
12157        }
12158    }
12159
12160    @Override
12161    public void setImmersive(IBinder token, boolean immersive) {
12162        synchronized(this) {
12163            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12164            if (r == null) {
12165                throw new IllegalArgumentException();
12166            }
12167            r.immersive = immersive;
12168
12169            // update associated state if we're frontmost
12170            if (r == mFocusedActivity) {
12171                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12172                applyUpdateLockStateLocked(r);
12173            }
12174        }
12175    }
12176
12177    @Override
12178    public boolean isImmersive(IBinder token) {
12179        synchronized (this) {
12180            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12181            if (r == null) {
12182                throw new IllegalArgumentException();
12183            }
12184            return r.immersive;
12185        }
12186    }
12187
12188    @Override
12189    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12190        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12191            throw new UnsupportedOperationException("VR mode not supported on this device!");
12192        }
12193
12194        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12195
12196        ActivityRecord r;
12197        synchronized (this) {
12198            r = ActivityRecord.isInStackLocked(token);
12199        }
12200
12201        if (r == null) {
12202            throw new IllegalArgumentException();
12203        }
12204
12205        int err;
12206        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12207                VrManagerInternal.NO_ERROR) {
12208            return err;
12209        }
12210
12211        synchronized(this) {
12212            r.requestedVrComponent = (enabled) ? packageName : null;
12213
12214            // Update associated state if this activity is currently focused
12215            if (r == mFocusedActivity) {
12216                applyUpdateVrModeLocked(r);
12217            }
12218            return 0;
12219        }
12220    }
12221
12222    @Override
12223    public boolean isVrModePackageEnabled(ComponentName packageName) {
12224        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12225            throw new UnsupportedOperationException("VR mode not supported on this device!");
12226        }
12227
12228        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12229
12230        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12231                VrManagerInternal.NO_ERROR;
12232    }
12233
12234    public boolean isTopActivityImmersive() {
12235        enforceNotIsolatedCaller("startActivity");
12236        synchronized (this) {
12237            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12238            return (r != null) ? r.immersive : false;
12239        }
12240    }
12241
12242    @Override
12243    public boolean isTopOfTask(IBinder token) {
12244        synchronized (this) {
12245            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12246            if (r == null) {
12247                throw new IllegalArgumentException();
12248            }
12249            return r.task.getTopActivity() == r;
12250        }
12251    }
12252
12253    public final void enterSafeMode() {
12254        synchronized(this) {
12255            // It only makes sense to do this before the system is ready
12256            // and started launching other packages.
12257            if (!mSystemReady) {
12258                try {
12259                    AppGlobals.getPackageManager().enterSafeMode();
12260                } catch (RemoteException e) {
12261                }
12262            }
12263
12264            mSafeMode = true;
12265        }
12266    }
12267
12268    public final void showSafeModeOverlay() {
12269        View v = LayoutInflater.from(mContext).inflate(
12270                com.android.internal.R.layout.safe_mode, null);
12271        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12272        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12273        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12274        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12275        lp.gravity = Gravity.BOTTOM | Gravity.START;
12276        lp.format = v.getBackground().getOpacity();
12277        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12278                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12279        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12280        ((WindowManager)mContext.getSystemService(
12281                Context.WINDOW_SERVICE)).addView(v, lp);
12282    }
12283
12284    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12285        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12286            return;
12287        }
12288        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12289        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12290        synchronized (stats) {
12291            if (mBatteryStatsService.isOnBattery()) {
12292                mBatteryStatsService.enforceCallingPermission();
12293                int MY_UID = Binder.getCallingUid();
12294                final int uid;
12295                if (sender == null) {
12296                    uid = sourceUid;
12297                } else {
12298                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12299                }
12300                BatteryStatsImpl.Uid.Pkg pkg =
12301                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12302                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12303                pkg.noteWakeupAlarmLocked(tag);
12304            }
12305        }
12306    }
12307
12308    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12309        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12310            return;
12311        }
12312        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12313        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12314        synchronized (stats) {
12315            mBatteryStatsService.enforceCallingPermission();
12316            int MY_UID = Binder.getCallingUid();
12317            final int uid;
12318            if (sender == null) {
12319                uid = sourceUid;
12320            } else {
12321                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12322            }
12323            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12324        }
12325    }
12326
12327    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12328        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12329            return;
12330        }
12331        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12332        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12333        synchronized (stats) {
12334            mBatteryStatsService.enforceCallingPermission();
12335            int MY_UID = Binder.getCallingUid();
12336            final int uid;
12337            if (sender == null) {
12338                uid = sourceUid;
12339            } else {
12340                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12341            }
12342            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12343        }
12344    }
12345
12346    public boolean killPids(int[] pids, String pReason, boolean secure) {
12347        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12348            throw new SecurityException("killPids only available to the system");
12349        }
12350        String reason = (pReason == null) ? "Unknown" : pReason;
12351        // XXX Note: don't acquire main activity lock here, because the window
12352        // manager calls in with its locks held.
12353
12354        boolean killed = false;
12355        synchronized (mPidsSelfLocked) {
12356            int worstType = 0;
12357            for (int i=0; i<pids.length; i++) {
12358                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12359                if (proc != null) {
12360                    int type = proc.setAdj;
12361                    if (type > worstType) {
12362                        worstType = type;
12363                    }
12364                }
12365            }
12366
12367            // If the worst oom_adj is somewhere in the cached proc LRU range,
12368            // then constrain it so we will kill all cached procs.
12369            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12370                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12371                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12372            }
12373
12374            // If this is not a secure call, don't let it kill processes that
12375            // are important.
12376            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12377                worstType = ProcessList.SERVICE_ADJ;
12378            }
12379
12380            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12381            for (int i=0; i<pids.length; i++) {
12382                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12383                if (proc == null) {
12384                    continue;
12385                }
12386                int adj = proc.setAdj;
12387                if (adj >= worstType && !proc.killedByAm) {
12388                    proc.kill(reason, true);
12389                    killed = true;
12390                }
12391            }
12392        }
12393        return killed;
12394    }
12395
12396    @Override
12397    public void killUid(int appId, int userId, String reason) {
12398        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12399        synchronized (this) {
12400            final long identity = Binder.clearCallingIdentity();
12401            try {
12402                killPackageProcessesLocked(null, appId, userId,
12403                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12404                        reason != null ? reason : "kill uid");
12405            } finally {
12406                Binder.restoreCallingIdentity(identity);
12407            }
12408        }
12409    }
12410
12411    @Override
12412    public boolean killProcessesBelowForeground(String reason) {
12413        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12414            throw new SecurityException("killProcessesBelowForeground() only available to system");
12415        }
12416
12417        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12418    }
12419
12420    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12421        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12422            throw new SecurityException("killProcessesBelowAdj() only available to system");
12423        }
12424
12425        boolean killed = false;
12426        synchronized (mPidsSelfLocked) {
12427            final int size = mPidsSelfLocked.size();
12428            for (int i = 0; i < size; i++) {
12429                final int pid = mPidsSelfLocked.keyAt(i);
12430                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12431                if (proc == null) continue;
12432
12433                final int adj = proc.setAdj;
12434                if (adj > belowAdj && !proc.killedByAm) {
12435                    proc.kill(reason, true);
12436                    killed = true;
12437                }
12438            }
12439        }
12440        return killed;
12441    }
12442
12443    @Override
12444    public void hang(final IBinder who, boolean allowRestart) {
12445        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12446                != PackageManager.PERMISSION_GRANTED) {
12447            throw new SecurityException("Requires permission "
12448                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12449        }
12450
12451        final IBinder.DeathRecipient death = new DeathRecipient() {
12452            @Override
12453            public void binderDied() {
12454                synchronized (this) {
12455                    notifyAll();
12456                }
12457            }
12458        };
12459
12460        try {
12461            who.linkToDeath(death, 0);
12462        } catch (RemoteException e) {
12463            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12464            return;
12465        }
12466
12467        synchronized (this) {
12468            Watchdog.getInstance().setAllowRestart(allowRestart);
12469            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12470            synchronized (death) {
12471                while (who.isBinderAlive()) {
12472                    try {
12473                        death.wait();
12474                    } catch (InterruptedException e) {
12475                    }
12476                }
12477            }
12478            Watchdog.getInstance().setAllowRestart(true);
12479        }
12480    }
12481
12482    @Override
12483    public void restart() {
12484        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12485                != PackageManager.PERMISSION_GRANTED) {
12486            throw new SecurityException("Requires permission "
12487                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12488        }
12489
12490        Log.i(TAG, "Sending shutdown broadcast...");
12491
12492        BroadcastReceiver br = new BroadcastReceiver() {
12493            @Override public void onReceive(Context context, Intent intent) {
12494                // Now the broadcast is done, finish up the low-level shutdown.
12495                Log.i(TAG, "Shutting down activity manager...");
12496                shutdown(10000);
12497                Log.i(TAG, "Shutdown complete, restarting!");
12498                Process.killProcess(Process.myPid());
12499                System.exit(10);
12500            }
12501        };
12502
12503        // First send the high-level shut down broadcast.
12504        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12505        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12506        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12507        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12508        mContext.sendOrderedBroadcastAsUser(intent,
12509                UserHandle.ALL, null, br, mHandler, 0, null, null);
12510        */
12511        br.onReceive(mContext, intent);
12512    }
12513
12514    private long getLowRamTimeSinceIdle(long now) {
12515        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12516    }
12517
12518    @Override
12519    public void performIdleMaintenance() {
12520        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12521                != PackageManager.PERMISSION_GRANTED) {
12522            throw new SecurityException("Requires permission "
12523                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12524        }
12525
12526        synchronized (this) {
12527            final long now = SystemClock.uptimeMillis();
12528            final long timeSinceLastIdle = now - mLastIdleTime;
12529            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12530            mLastIdleTime = now;
12531            mLowRamTimeSinceLastIdle = 0;
12532            if (mLowRamStartTime != 0) {
12533                mLowRamStartTime = now;
12534            }
12535
12536            StringBuilder sb = new StringBuilder(128);
12537            sb.append("Idle maintenance over ");
12538            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12539            sb.append(" low RAM for ");
12540            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12541            Slog.i(TAG, sb.toString());
12542
12543            // If at least 1/3 of our time since the last idle period has been spent
12544            // with RAM low, then we want to kill processes.
12545            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12546
12547            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12548                ProcessRecord proc = mLruProcesses.get(i);
12549                if (proc.notCachedSinceIdle) {
12550                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12551                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12552                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12553                        if (doKilling && proc.initialIdlePss != 0
12554                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12555                            sb = new StringBuilder(128);
12556                            sb.append("Kill");
12557                            sb.append(proc.processName);
12558                            sb.append(" in idle maint: pss=");
12559                            sb.append(proc.lastPss);
12560                            sb.append(", swapPss=");
12561                            sb.append(proc.lastSwapPss);
12562                            sb.append(", initialPss=");
12563                            sb.append(proc.initialIdlePss);
12564                            sb.append(", period=");
12565                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12566                            sb.append(", lowRamPeriod=");
12567                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12568                            Slog.wtfQuiet(TAG, sb.toString());
12569                            proc.kill("idle maint (pss " + proc.lastPss
12570                                    + " from " + proc.initialIdlePss + ")", true);
12571                        }
12572                    }
12573                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12574                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12575                    proc.notCachedSinceIdle = true;
12576                    proc.initialIdlePss = 0;
12577                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12578                            mTestPssMode, isSleeping(), now);
12579                }
12580            }
12581
12582            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12583            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12584        }
12585    }
12586
12587    private void retrieveSettings() {
12588        final ContentResolver resolver = mContext.getContentResolver();
12589        final boolean freeformWindowManagement =
12590                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12591                        || Settings.Global.getInt(
12592                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12593        final boolean supportsPictureInPicture =
12594                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12595
12596        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12597        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12598        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12599        final boolean alwaysFinishActivities =
12600                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12601        final boolean lenientBackgroundCheck =
12602                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12603        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12604        final boolean forceResizable = Settings.Global.getInt(
12605                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12606        // Transfer any global setting for forcing RTL layout, into a System Property
12607        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12608
12609        final Configuration configuration = new Configuration();
12610        Settings.System.getConfiguration(resolver, configuration);
12611        if (forceRtl) {
12612            // This will take care of setting the correct layout direction flags
12613            configuration.setLayoutDirection(configuration.locale);
12614        }
12615
12616        synchronized (this) {
12617            mDebugApp = mOrigDebugApp = debugApp;
12618            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12619            mAlwaysFinishActivities = alwaysFinishActivities;
12620            mLenientBackgroundCheck = lenientBackgroundCheck;
12621            mForceResizableActivities = forceResizable;
12622            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12623            if (supportsMultiWindow || forceResizable) {
12624                mSupportsMultiWindow = true;
12625                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12626                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12627            } else {
12628                mSupportsMultiWindow = false;
12629                mSupportsFreeformWindowManagement = false;
12630                mSupportsPictureInPicture = false;
12631            }
12632            // This happens before any activities are started, so we can
12633            // change mConfiguration in-place.
12634            updateConfigurationLocked(configuration, null, true);
12635            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12636                    "Initial config: " + mConfiguration);
12637
12638            // Load resources only after the current configuration has been set.
12639            final Resources res = mContext.getResources();
12640            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12641            mThumbnailWidth = res.getDimensionPixelSize(
12642                    com.android.internal.R.dimen.thumbnail_width);
12643            mThumbnailHeight = res.getDimensionPixelSize(
12644                    com.android.internal.R.dimen.thumbnail_height);
12645            mFullscreenThumbnailScale = res.getFraction(
12646                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12647            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12648                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12649            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12650                    com.android.internal.R.string.config_appsNotReportingCrashes));
12651        }
12652    }
12653
12654    public boolean testIsSystemReady() {
12655        // no need to synchronize(this) just to read & return the value
12656        return mSystemReady;
12657    }
12658
12659    public void systemReady(final Runnable goingCallback) {
12660        synchronized(this) {
12661            if (mSystemReady) {
12662                // If we're done calling all the receivers, run the next "boot phase" passed in
12663                // by the SystemServer
12664                if (goingCallback != null) {
12665                    goingCallback.run();
12666                }
12667                return;
12668            }
12669
12670            mLocalDeviceIdleController
12671                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12672
12673            // Make sure we have the current profile info, since it is needed for security checks.
12674            mUserController.onSystemReady();
12675            mRecentTasks.onSystemReadyLocked();
12676            mAppOpsService.systemReady();
12677            mSystemReady = true;
12678        }
12679
12680        ArrayList<ProcessRecord> procsToKill = null;
12681        synchronized(mPidsSelfLocked) {
12682            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12683                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12684                if (!isAllowedWhileBooting(proc.info)){
12685                    if (procsToKill == null) {
12686                        procsToKill = new ArrayList<ProcessRecord>();
12687                    }
12688                    procsToKill.add(proc);
12689                }
12690            }
12691        }
12692
12693        synchronized(this) {
12694            if (procsToKill != null) {
12695                for (int i=procsToKill.size()-1; i>=0; i--) {
12696                    ProcessRecord proc = procsToKill.get(i);
12697                    Slog.i(TAG, "Removing system update proc: " + proc);
12698                    removeProcessLocked(proc, true, false, "system update done");
12699                }
12700            }
12701
12702            // Now that we have cleaned up any update processes, we
12703            // are ready to start launching real processes and know that
12704            // we won't trample on them any more.
12705            mProcessesReady = true;
12706        }
12707
12708        Slog.i(TAG, "System now ready");
12709        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12710            SystemClock.uptimeMillis());
12711
12712        synchronized(this) {
12713            // Make sure we have no pre-ready processes sitting around.
12714
12715            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12716                ResolveInfo ri = mContext.getPackageManager()
12717                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12718                                STOCK_PM_FLAGS);
12719                CharSequence errorMsg = null;
12720                if (ri != null) {
12721                    ActivityInfo ai = ri.activityInfo;
12722                    ApplicationInfo app = ai.applicationInfo;
12723                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12724                        mTopAction = Intent.ACTION_FACTORY_TEST;
12725                        mTopData = null;
12726                        mTopComponent = new ComponentName(app.packageName,
12727                                ai.name);
12728                    } else {
12729                        errorMsg = mContext.getResources().getText(
12730                                com.android.internal.R.string.factorytest_not_system);
12731                    }
12732                } else {
12733                    errorMsg = mContext.getResources().getText(
12734                            com.android.internal.R.string.factorytest_no_action);
12735                }
12736                if (errorMsg != null) {
12737                    mTopAction = null;
12738                    mTopData = null;
12739                    mTopComponent = null;
12740                    Message msg = Message.obtain();
12741                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12742                    msg.getData().putCharSequence("msg", errorMsg);
12743                    mUiHandler.sendMessage(msg);
12744                }
12745            }
12746        }
12747
12748        retrieveSettings();
12749        final int currentUserId;
12750        synchronized (this) {
12751            currentUserId = mUserController.getCurrentUserIdLocked();
12752            readGrantedUriPermissionsLocked();
12753        }
12754
12755        if (goingCallback != null) goingCallback.run();
12756
12757        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12758                Integer.toString(currentUserId), currentUserId);
12759        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12760                Integer.toString(currentUserId), currentUserId);
12761        mSystemServiceManager.startUser(currentUserId);
12762
12763        synchronized (this) {
12764            // Only start up encryption-aware persistent apps; once user is
12765            // unlocked we'll come back around and start unaware apps
12766            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12767
12768            // Start up initial activity.
12769            mBooting = true;
12770            // Enable home activity for system user, so that the system can always boot
12771            if (UserManager.isSplitSystemUser()) {
12772                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12773                try {
12774                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12775                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12776                            UserHandle.USER_SYSTEM);
12777                } catch (RemoteException e) {
12778                    throw e.rethrowAsRuntimeException();
12779                }
12780            }
12781            startHomeActivityLocked(currentUserId, "systemReady");
12782
12783            try {
12784                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12785                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12786                            + " data partition or your device will be unstable.");
12787                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12788                }
12789            } catch (RemoteException e) {
12790            }
12791
12792            if (!Build.isBuildConsistent()) {
12793                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12794                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12795            }
12796
12797            long ident = Binder.clearCallingIdentity();
12798            try {
12799                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12800                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12801                        | Intent.FLAG_RECEIVER_FOREGROUND);
12802                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12803                broadcastIntentLocked(null, null, intent,
12804                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12805                        null, false, false, MY_PID, Process.SYSTEM_UID,
12806                        currentUserId);
12807                intent = new Intent(Intent.ACTION_USER_STARTING);
12808                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12809                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12810                broadcastIntentLocked(null, null, intent,
12811                        null, new IIntentReceiver.Stub() {
12812                            @Override
12813                            public void performReceive(Intent intent, int resultCode, String data,
12814                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12815                                    throws RemoteException {
12816                            }
12817                        }, 0, null, null,
12818                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12819                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12820            } catch (Throwable t) {
12821                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12822            } finally {
12823                Binder.restoreCallingIdentity(ident);
12824            }
12825            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12826            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12827        }
12828    }
12829
12830    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12831        synchronized (this) {
12832            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12833        }
12834    }
12835
12836    void skipCurrentReceiverLocked(ProcessRecord app) {
12837        for (BroadcastQueue queue : mBroadcastQueues) {
12838            queue.skipCurrentReceiverLocked(app);
12839        }
12840    }
12841
12842    /**
12843     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12844     * The application process will exit immediately after this call returns.
12845     * @param app object of the crashing app, null for the system server
12846     * @param crashInfo describing the exception
12847     */
12848    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12849        ProcessRecord r = findAppProcess(app, "Crash");
12850        final String processName = app == null ? "system_server"
12851                : (r == null ? "unknown" : r.processName);
12852
12853        handleApplicationCrashInner("crash", r, processName, crashInfo);
12854    }
12855
12856    /* Native crash reporting uses this inner version because it needs to be somewhat
12857     * decoupled from the AM-managed cleanup lifecycle
12858     */
12859    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12860            ApplicationErrorReport.CrashInfo crashInfo) {
12861        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12862                UserHandle.getUserId(Binder.getCallingUid()), processName,
12863                r == null ? -1 : r.info.flags,
12864                crashInfo.exceptionClassName,
12865                crashInfo.exceptionMessage,
12866                crashInfo.throwFileName,
12867                crashInfo.throwLineNumber);
12868
12869        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12870
12871        mAppErrors.crashApplication(r, crashInfo);
12872    }
12873
12874    public void handleApplicationStrictModeViolation(
12875            IBinder app,
12876            int violationMask,
12877            StrictMode.ViolationInfo info) {
12878        ProcessRecord r = findAppProcess(app, "StrictMode");
12879        if (r == null) {
12880            return;
12881        }
12882
12883        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12884            Integer stackFingerprint = info.hashCode();
12885            boolean logIt = true;
12886            synchronized (mAlreadyLoggedViolatedStacks) {
12887                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12888                    logIt = false;
12889                    // TODO: sub-sample into EventLog for these, with
12890                    // the info.durationMillis?  Then we'd get
12891                    // the relative pain numbers, without logging all
12892                    // the stack traces repeatedly.  We'd want to do
12893                    // likewise in the client code, which also does
12894                    // dup suppression, before the Binder call.
12895                } else {
12896                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12897                        mAlreadyLoggedViolatedStacks.clear();
12898                    }
12899                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12900                }
12901            }
12902            if (logIt) {
12903                logStrictModeViolationToDropBox(r, info);
12904            }
12905        }
12906
12907        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12908            AppErrorResult result = new AppErrorResult();
12909            synchronized (this) {
12910                final long origId = Binder.clearCallingIdentity();
12911
12912                Message msg = Message.obtain();
12913                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12914                HashMap<String, Object> data = new HashMap<String, Object>();
12915                data.put("result", result);
12916                data.put("app", r);
12917                data.put("violationMask", violationMask);
12918                data.put("info", info);
12919                msg.obj = data;
12920                mUiHandler.sendMessage(msg);
12921
12922                Binder.restoreCallingIdentity(origId);
12923            }
12924            int res = result.get();
12925            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12926        }
12927    }
12928
12929    // Depending on the policy in effect, there could be a bunch of
12930    // these in quick succession so we try to batch these together to
12931    // minimize disk writes, number of dropbox entries, and maximize
12932    // compression, by having more fewer, larger records.
12933    private void logStrictModeViolationToDropBox(
12934            ProcessRecord process,
12935            StrictMode.ViolationInfo info) {
12936        if (info == null) {
12937            return;
12938        }
12939        final boolean isSystemApp = process == null ||
12940                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12941                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12942        final String processName = process == null ? "unknown" : process.processName;
12943        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12944        final DropBoxManager dbox = (DropBoxManager)
12945                mContext.getSystemService(Context.DROPBOX_SERVICE);
12946
12947        // Exit early if the dropbox isn't configured to accept this report type.
12948        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12949
12950        boolean bufferWasEmpty;
12951        boolean needsFlush;
12952        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12953        synchronized (sb) {
12954            bufferWasEmpty = sb.length() == 0;
12955            appendDropBoxProcessHeaders(process, processName, sb);
12956            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12957            sb.append("System-App: ").append(isSystemApp).append("\n");
12958            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12959            if (info.violationNumThisLoop != 0) {
12960                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12961            }
12962            if (info.numAnimationsRunning != 0) {
12963                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12964            }
12965            if (info.broadcastIntentAction != null) {
12966                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12967            }
12968            if (info.durationMillis != -1) {
12969                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12970            }
12971            if (info.numInstances != -1) {
12972                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12973            }
12974            if (info.tags != null) {
12975                for (String tag : info.tags) {
12976                    sb.append("Span-Tag: ").append(tag).append("\n");
12977                }
12978            }
12979            sb.append("\n");
12980            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12981                sb.append(info.crashInfo.stackTrace);
12982                sb.append("\n");
12983            }
12984            if (info.message != null) {
12985                sb.append(info.message);
12986                sb.append("\n");
12987            }
12988
12989            // Only buffer up to ~64k.  Various logging bits truncate
12990            // things at 128k.
12991            needsFlush = (sb.length() > 64 * 1024);
12992        }
12993
12994        // Flush immediately if the buffer's grown too large, or this
12995        // is a non-system app.  Non-system apps are isolated with a
12996        // different tag & policy and not batched.
12997        //
12998        // Batching is useful during internal testing with
12999        // StrictMode settings turned up high.  Without batching,
13000        // thousands of separate files could be created on boot.
13001        if (!isSystemApp || needsFlush) {
13002            new Thread("Error dump: " + dropboxTag) {
13003                @Override
13004                public void run() {
13005                    String report;
13006                    synchronized (sb) {
13007                        report = sb.toString();
13008                        sb.delete(0, sb.length());
13009                        sb.trimToSize();
13010                    }
13011                    if (report.length() != 0) {
13012                        dbox.addText(dropboxTag, report);
13013                    }
13014                }
13015            }.start();
13016            return;
13017        }
13018
13019        // System app batching:
13020        if (!bufferWasEmpty) {
13021            // An existing dropbox-writing thread is outstanding, so
13022            // we don't need to start it up.  The existing thread will
13023            // catch the buffer appends we just did.
13024            return;
13025        }
13026
13027        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13028        // (After this point, we shouldn't access AMS internal data structures.)
13029        new Thread("Error dump: " + dropboxTag) {
13030            @Override
13031            public void run() {
13032                // 5 second sleep to let stacks arrive and be batched together
13033                try {
13034                    Thread.sleep(5000);  // 5 seconds
13035                } catch (InterruptedException e) {}
13036
13037                String errorReport;
13038                synchronized (mStrictModeBuffer) {
13039                    errorReport = mStrictModeBuffer.toString();
13040                    if (errorReport.length() == 0) {
13041                        return;
13042                    }
13043                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13044                    mStrictModeBuffer.trimToSize();
13045                }
13046                dbox.addText(dropboxTag, errorReport);
13047            }
13048        }.start();
13049    }
13050
13051    /**
13052     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13053     * @param app object of the crashing app, null for the system server
13054     * @param tag reported by the caller
13055     * @param system whether this wtf is coming from the system
13056     * @param crashInfo describing the context of the error
13057     * @return true if the process should exit immediately (WTF is fatal)
13058     */
13059    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13060            final ApplicationErrorReport.CrashInfo crashInfo) {
13061        final int callingUid = Binder.getCallingUid();
13062        final int callingPid = Binder.getCallingPid();
13063
13064        if (system) {
13065            // If this is coming from the system, we could very well have low-level
13066            // system locks held, so we want to do this all asynchronously.  And we
13067            // never want this to become fatal, so there is that too.
13068            mHandler.post(new Runnable() {
13069                @Override public void run() {
13070                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13071                }
13072            });
13073            return false;
13074        }
13075
13076        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13077                crashInfo);
13078
13079        if (r != null && r.pid != Process.myPid() &&
13080                Settings.Global.getInt(mContext.getContentResolver(),
13081                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13082            mAppErrors.crashApplication(r, crashInfo);
13083            return true;
13084        } else {
13085            return false;
13086        }
13087    }
13088
13089    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13090            final ApplicationErrorReport.CrashInfo crashInfo) {
13091        final ProcessRecord r = findAppProcess(app, "WTF");
13092        final String processName = app == null ? "system_server"
13093                : (r == null ? "unknown" : r.processName);
13094
13095        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13096                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13097
13098        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13099
13100        return r;
13101    }
13102
13103    /**
13104     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13105     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13106     */
13107    private ProcessRecord findAppProcess(IBinder app, String reason) {
13108        if (app == null) {
13109            return null;
13110        }
13111
13112        synchronized (this) {
13113            final int NP = mProcessNames.getMap().size();
13114            for (int ip=0; ip<NP; ip++) {
13115                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13116                final int NA = apps.size();
13117                for (int ia=0; ia<NA; ia++) {
13118                    ProcessRecord p = apps.valueAt(ia);
13119                    if (p.thread != null && p.thread.asBinder() == app) {
13120                        return p;
13121                    }
13122                }
13123            }
13124
13125            Slog.w(TAG, "Can't find mystery application for " + reason
13126                    + " from pid=" + Binder.getCallingPid()
13127                    + " uid=" + Binder.getCallingUid() + ": " + app);
13128            return null;
13129        }
13130    }
13131
13132    /**
13133     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13134     * to append various headers to the dropbox log text.
13135     */
13136    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13137            StringBuilder sb) {
13138        // Watchdog thread ends up invoking this function (with
13139        // a null ProcessRecord) to add the stack file to dropbox.
13140        // Do not acquire a lock on this (am) in such cases, as it
13141        // could cause a potential deadlock, if and when watchdog
13142        // is invoked due to unavailability of lock on am and it
13143        // would prevent watchdog from killing system_server.
13144        if (process == null) {
13145            sb.append("Process: ").append(processName).append("\n");
13146            return;
13147        }
13148        // Note: ProcessRecord 'process' is guarded by the service
13149        // instance.  (notably process.pkgList, which could otherwise change
13150        // concurrently during execution of this method)
13151        synchronized (this) {
13152            sb.append("Process: ").append(processName).append("\n");
13153            int flags = process.info.flags;
13154            IPackageManager pm = AppGlobals.getPackageManager();
13155            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13156            for (int ip=0; ip<process.pkgList.size(); ip++) {
13157                String pkg = process.pkgList.keyAt(ip);
13158                sb.append("Package: ").append(pkg);
13159                try {
13160                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13161                    if (pi != null) {
13162                        sb.append(" v").append(pi.versionCode);
13163                        if (pi.versionName != null) {
13164                            sb.append(" (").append(pi.versionName).append(")");
13165                        }
13166                    }
13167                } catch (RemoteException e) {
13168                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13169                }
13170                sb.append("\n");
13171            }
13172        }
13173    }
13174
13175    private static String processClass(ProcessRecord process) {
13176        if (process == null || process.pid == MY_PID) {
13177            return "system_server";
13178        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13179            return "system_app";
13180        } else {
13181            return "data_app";
13182        }
13183    }
13184
13185    private volatile long mWtfClusterStart;
13186    private volatile int mWtfClusterCount;
13187
13188    /**
13189     * Write a description of an error (crash, WTF, ANR) to the drop box.
13190     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13191     * @param process which caused the error, null means the system server
13192     * @param activity which triggered the error, null if unknown
13193     * @param parent activity related to the error, null if unknown
13194     * @param subject line related to the error, null if absent
13195     * @param report in long form describing the error, null if absent
13196     * @param logFile to include in the report, null if none
13197     * @param crashInfo giving an application stack trace, null if absent
13198     */
13199    public void addErrorToDropBox(String eventType,
13200            ProcessRecord process, String processName, ActivityRecord activity,
13201            ActivityRecord parent, String subject,
13202            final String report, final File logFile,
13203            final ApplicationErrorReport.CrashInfo crashInfo) {
13204        // NOTE -- this must never acquire the ActivityManagerService lock,
13205        // otherwise the watchdog may be prevented from resetting the system.
13206
13207        final String dropboxTag = processClass(process) + "_" + eventType;
13208        final DropBoxManager dbox = (DropBoxManager)
13209                mContext.getSystemService(Context.DROPBOX_SERVICE);
13210
13211        // Exit early if the dropbox isn't configured to accept this report type.
13212        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13213
13214        // Rate-limit how often we're willing to do the heavy lifting below to
13215        // collect and record logs; currently 5 logs per 10 second period.
13216        final long now = SystemClock.elapsedRealtime();
13217        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13218            mWtfClusterStart = now;
13219            mWtfClusterCount = 1;
13220        } else {
13221            if (mWtfClusterCount++ >= 5) return;
13222        }
13223
13224        final StringBuilder sb = new StringBuilder(1024);
13225        appendDropBoxProcessHeaders(process, processName, sb);
13226        if (process != null) {
13227            sb.append("Foreground: ")
13228                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13229                    .append("\n");
13230        }
13231        if (activity != null) {
13232            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13233        }
13234        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13235            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13236        }
13237        if (parent != null && parent != activity) {
13238            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13239        }
13240        if (subject != null) {
13241            sb.append("Subject: ").append(subject).append("\n");
13242        }
13243        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13244        if (Debug.isDebuggerConnected()) {
13245            sb.append("Debugger: Connected\n");
13246        }
13247        sb.append("\n");
13248
13249        // Do the rest in a worker thread to avoid blocking the caller on I/O
13250        // (After this point, we shouldn't access AMS internal data structures.)
13251        Thread worker = new Thread("Error dump: " + dropboxTag) {
13252            @Override
13253            public void run() {
13254                if (report != null) {
13255                    sb.append(report);
13256                }
13257                if (logFile != null) {
13258                    try {
13259                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13260                                    "\n\n[[TRUNCATED]]"));
13261                    } catch (IOException e) {
13262                        Slog.e(TAG, "Error reading " + logFile, e);
13263                    }
13264                }
13265                if (crashInfo != null && crashInfo.stackTrace != null) {
13266                    sb.append(crashInfo.stackTrace);
13267                }
13268
13269                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13270                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13271                if (lines > 0) {
13272                    sb.append("\n");
13273
13274                    // Merge several logcat streams, and take the last N lines
13275                    InputStreamReader input = null;
13276                    try {
13277                        java.lang.Process logcat = new ProcessBuilder(
13278                                "/system/bin/timeout", "-k", "15s", "10s",
13279                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13280                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13281                                        .redirectErrorStream(true).start();
13282
13283                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13284                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13285                        input = new InputStreamReader(logcat.getInputStream());
13286
13287                        int num;
13288                        char[] buf = new char[8192];
13289                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13290                    } catch (IOException e) {
13291                        Slog.e(TAG, "Error running logcat", e);
13292                    } finally {
13293                        if (input != null) try { input.close(); } catch (IOException e) {}
13294                    }
13295                }
13296
13297                dbox.addText(dropboxTag, sb.toString());
13298            }
13299        };
13300
13301        if (process == null) {
13302            // If process is null, we are being called from some internal code
13303            // and may be about to die -- run this synchronously.
13304            worker.run();
13305        } else {
13306            worker.start();
13307        }
13308    }
13309
13310    @Override
13311    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13312        enforceNotIsolatedCaller("getProcessesInErrorState");
13313        // assume our apps are happy - lazy create the list
13314        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13315
13316        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13317                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13318        int userId = UserHandle.getUserId(Binder.getCallingUid());
13319
13320        synchronized (this) {
13321
13322            // iterate across all processes
13323            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13324                ProcessRecord app = mLruProcesses.get(i);
13325                if (!allUsers && app.userId != userId) {
13326                    continue;
13327                }
13328                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13329                    // This one's in trouble, so we'll generate a report for it
13330                    // crashes are higher priority (in case there's a crash *and* an anr)
13331                    ActivityManager.ProcessErrorStateInfo report = null;
13332                    if (app.crashing) {
13333                        report = app.crashingReport;
13334                    } else if (app.notResponding) {
13335                        report = app.notRespondingReport;
13336                    }
13337
13338                    if (report != null) {
13339                        if (errList == null) {
13340                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13341                        }
13342                        errList.add(report);
13343                    } else {
13344                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13345                                " crashing = " + app.crashing +
13346                                " notResponding = " + app.notResponding);
13347                    }
13348                }
13349            }
13350        }
13351
13352        return errList;
13353    }
13354
13355    static int procStateToImportance(int procState, int memAdj,
13356            ActivityManager.RunningAppProcessInfo currApp) {
13357        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13358        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13359            currApp.lru = memAdj;
13360        } else {
13361            currApp.lru = 0;
13362        }
13363        return imp;
13364    }
13365
13366    private void fillInProcMemInfo(ProcessRecord app,
13367            ActivityManager.RunningAppProcessInfo outInfo) {
13368        outInfo.pid = app.pid;
13369        outInfo.uid = app.info.uid;
13370        if (mHeavyWeightProcess == app) {
13371            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13372        }
13373        if (app.persistent) {
13374            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13375        }
13376        if (app.activities.size() > 0) {
13377            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13378        }
13379        outInfo.lastTrimLevel = app.trimMemoryLevel;
13380        int adj = app.curAdj;
13381        int procState = app.curProcState;
13382        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13383        outInfo.importanceReasonCode = app.adjTypeCode;
13384        outInfo.processState = app.curProcState;
13385    }
13386
13387    @Override
13388    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13389        enforceNotIsolatedCaller("getRunningAppProcesses");
13390
13391        final int callingUid = Binder.getCallingUid();
13392
13393        // Lazy instantiation of list
13394        List<ActivityManager.RunningAppProcessInfo> runList = null;
13395        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13396                callingUid) == PackageManager.PERMISSION_GRANTED;
13397        final int userId = UserHandle.getUserId(callingUid);
13398        final boolean allUids = isGetTasksAllowed(
13399                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13400
13401        synchronized (this) {
13402            // Iterate across all processes
13403            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13404                ProcessRecord app = mLruProcesses.get(i);
13405                if ((!allUsers && app.userId != userId)
13406                        || (!allUids && app.uid != callingUid)) {
13407                    continue;
13408                }
13409                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13410                    // Generate process state info for running application
13411                    ActivityManager.RunningAppProcessInfo currApp =
13412                        new ActivityManager.RunningAppProcessInfo(app.processName,
13413                                app.pid, app.getPackageList());
13414                    fillInProcMemInfo(app, currApp);
13415                    if (app.adjSource instanceof ProcessRecord) {
13416                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13417                        currApp.importanceReasonImportance =
13418                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13419                                        app.adjSourceProcState);
13420                    } else if (app.adjSource instanceof ActivityRecord) {
13421                        ActivityRecord r = (ActivityRecord)app.adjSource;
13422                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13423                    }
13424                    if (app.adjTarget instanceof ComponentName) {
13425                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13426                    }
13427                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13428                    //        + " lru=" + currApp.lru);
13429                    if (runList == null) {
13430                        runList = new ArrayList<>();
13431                    }
13432                    runList.add(currApp);
13433                }
13434            }
13435        }
13436        return runList;
13437    }
13438
13439    @Override
13440    public List<ApplicationInfo> getRunningExternalApplications() {
13441        enforceNotIsolatedCaller("getRunningExternalApplications");
13442        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13443        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13444        if (runningApps != null && runningApps.size() > 0) {
13445            Set<String> extList = new HashSet<String>();
13446            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13447                if (app.pkgList != null) {
13448                    for (String pkg : app.pkgList) {
13449                        extList.add(pkg);
13450                    }
13451                }
13452            }
13453            IPackageManager pm = AppGlobals.getPackageManager();
13454            for (String pkg : extList) {
13455                try {
13456                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13457                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13458                        retList.add(info);
13459                    }
13460                } catch (RemoteException e) {
13461                }
13462            }
13463        }
13464        return retList;
13465    }
13466
13467    @Override
13468    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13469        enforceNotIsolatedCaller("getMyMemoryState");
13470        synchronized (this) {
13471            ProcessRecord proc;
13472            synchronized (mPidsSelfLocked) {
13473                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13474            }
13475            fillInProcMemInfo(proc, outInfo);
13476        }
13477    }
13478
13479    @Override
13480    public int getMemoryTrimLevel() {
13481        enforceNotIsolatedCaller("getMyMemoryState");
13482        synchronized (this) {
13483            return mLastMemoryLevel;
13484        }
13485    }
13486
13487    @Override
13488    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13489            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13490        (new ActivityManagerShellCommand(this, false)).exec(
13491                this, in, out, err, args, resultReceiver);
13492    }
13493
13494    @Override
13495    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13496        if (checkCallingPermission(android.Manifest.permission.DUMP)
13497                != PackageManager.PERMISSION_GRANTED) {
13498            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13499                    + Binder.getCallingPid()
13500                    + ", uid=" + Binder.getCallingUid()
13501                    + " without permission "
13502                    + android.Manifest.permission.DUMP);
13503            return;
13504        }
13505
13506        boolean dumpAll = false;
13507        boolean dumpClient = false;
13508        String dumpPackage = null;
13509
13510        int opti = 0;
13511        while (opti < args.length) {
13512            String opt = args[opti];
13513            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13514                break;
13515            }
13516            opti++;
13517            if ("-a".equals(opt)) {
13518                dumpAll = true;
13519            } else if ("-c".equals(opt)) {
13520                dumpClient = true;
13521            } else if ("-p".equals(opt)) {
13522                if (opti < args.length) {
13523                    dumpPackage = args[opti];
13524                    opti++;
13525                } else {
13526                    pw.println("Error: -p option requires package argument");
13527                    return;
13528                }
13529                dumpClient = true;
13530            } else if ("-h".equals(opt)) {
13531                ActivityManagerShellCommand.dumpHelp(pw, true);
13532                return;
13533            } else {
13534                pw.println("Unknown argument: " + opt + "; use -h for help");
13535            }
13536        }
13537
13538        long origId = Binder.clearCallingIdentity();
13539        boolean more = false;
13540        // Is the caller requesting to dump a particular piece of data?
13541        if (opti < args.length) {
13542            String cmd = args[opti];
13543            opti++;
13544            if ("activities".equals(cmd) || "a".equals(cmd)) {
13545                synchronized (this) {
13546                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13547                }
13548            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13549                synchronized (this) {
13550                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13551                }
13552            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13553                String[] newArgs;
13554                String name;
13555                if (opti >= args.length) {
13556                    name = null;
13557                    newArgs = EMPTY_STRING_ARRAY;
13558                } else {
13559                    dumpPackage = args[opti];
13560                    opti++;
13561                    newArgs = new String[args.length - opti];
13562                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13563                            args.length - opti);
13564                }
13565                synchronized (this) {
13566                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13567                }
13568            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13569                String[] newArgs;
13570                String name;
13571                if (opti >= args.length) {
13572                    name = null;
13573                    newArgs = EMPTY_STRING_ARRAY;
13574                } else {
13575                    dumpPackage = args[opti];
13576                    opti++;
13577                    newArgs = new String[args.length - opti];
13578                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13579                            args.length - opti);
13580                }
13581                synchronized (this) {
13582                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13583                }
13584            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13585                String[] newArgs;
13586                String name;
13587                if (opti >= args.length) {
13588                    name = null;
13589                    newArgs = EMPTY_STRING_ARRAY;
13590                } else {
13591                    dumpPackage = args[opti];
13592                    opti++;
13593                    newArgs = new String[args.length - opti];
13594                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13595                            args.length - opti);
13596                }
13597                synchronized (this) {
13598                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13599                }
13600            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13601                synchronized (this) {
13602                    dumpOomLocked(fd, pw, args, opti, true);
13603                }
13604            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13605                synchronized (this) {
13606                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13607                }
13608            } else if ("provider".equals(cmd)) {
13609                String[] newArgs;
13610                String name;
13611                if (opti >= args.length) {
13612                    name = null;
13613                    newArgs = EMPTY_STRING_ARRAY;
13614                } else {
13615                    name = args[opti];
13616                    opti++;
13617                    newArgs = new String[args.length - opti];
13618                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13619                }
13620                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13621                    pw.println("No providers match: " + name);
13622                    pw.println("Use -h for help.");
13623                }
13624            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13625                synchronized (this) {
13626                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13627                }
13628            } else if ("service".equals(cmd)) {
13629                String[] newArgs;
13630                String name;
13631                if (opti >= args.length) {
13632                    name = null;
13633                    newArgs = EMPTY_STRING_ARRAY;
13634                } else {
13635                    name = args[opti];
13636                    opti++;
13637                    newArgs = new String[args.length - opti];
13638                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13639                            args.length - opti);
13640                }
13641                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13642                    pw.println("No services match: " + name);
13643                    pw.println("Use -h for help.");
13644                }
13645            } else if ("package".equals(cmd)) {
13646                String[] newArgs;
13647                if (opti >= args.length) {
13648                    pw.println("package: no package name specified");
13649                    pw.println("Use -h for help.");
13650                } else {
13651                    dumpPackage = args[opti];
13652                    opti++;
13653                    newArgs = new String[args.length - opti];
13654                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13655                            args.length - opti);
13656                    args = newArgs;
13657                    opti = 0;
13658                    more = true;
13659                }
13660            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13661                synchronized (this) {
13662                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13663                }
13664            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13665                synchronized (this) {
13666                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13667                }
13668            } else if ("locks".equals(cmd)) {
13669                LockGuard.dump(fd, pw, args);
13670            } else {
13671                // Dumping a single activity?
13672                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13673                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13674                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13675                    if (res < 0) {
13676                        pw.println("Bad activity command, or no activities match: " + cmd);
13677                        pw.println("Use -h for help.");
13678                    }
13679                }
13680            }
13681            if (!more) {
13682                Binder.restoreCallingIdentity(origId);
13683                return;
13684            }
13685        }
13686
13687        // No piece of data specified, dump everything.
13688        synchronized (this) {
13689            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13690            pw.println();
13691            if (dumpAll) {
13692                pw.println("-------------------------------------------------------------------------------");
13693            }
13694            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13695            pw.println();
13696            if (dumpAll) {
13697                pw.println("-------------------------------------------------------------------------------");
13698            }
13699            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13700            pw.println();
13701            if (dumpAll) {
13702                pw.println("-------------------------------------------------------------------------------");
13703            }
13704            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13705            pw.println();
13706            if (dumpAll) {
13707                pw.println("-------------------------------------------------------------------------------");
13708            }
13709            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13710            pw.println();
13711            if (dumpAll) {
13712                pw.println("-------------------------------------------------------------------------------");
13713            }
13714            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13715            pw.println();
13716            if (dumpAll) {
13717                pw.println("-------------------------------------------------------------------------------");
13718            }
13719            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13720            if (mAssociations.size() > 0) {
13721                pw.println();
13722                if (dumpAll) {
13723                    pw.println("-------------------------------------------------------------------------------");
13724                }
13725                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13726            }
13727            pw.println();
13728            if (dumpAll) {
13729                pw.println("-------------------------------------------------------------------------------");
13730            }
13731            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13732        }
13733        Binder.restoreCallingIdentity(origId);
13734    }
13735
13736    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13737            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13738        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13739
13740        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13741                dumpPackage);
13742        boolean needSep = printedAnything;
13743
13744        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13745                dumpPackage, needSep, "  mFocusedActivity: ");
13746        if (printed) {
13747            printedAnything = true;
13748            needSep = false;
13749        }
13750
13751        if (dumpPackage == null) {
13752            if (needSep) {
13753                pw.println();
13754            }
13755            needSep = true;
13756            printedAnything = true;
13757            mStackSupervisor.dump(pw, "  ");
13758        }
13759
13760        if (!printedAnything) {
13761            pw.println("  (nothing)");
13762        }
13763    }
13764
13765    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13766            int opti, boolean dumpAll, String dumpPackage) {
13767        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13768
13769        boolean printedAnything = false;
13770
13771        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13772            boolean printedHeader = false;
13773
13774            final int N = mRecentTasks.size();
13775            for (int i=0; i<N; i++) {
13776                TaskRecord tr = mRecentTasks.get(i);
13777                if (dumpPackage != null) {
13778                    if (tr.realActivity == null ||
13779                            !dumpPackage.equals(tr.realActivity)) {
13780                        continue;
13781                    }
13782                }
13783                if (!printedHeader) {
13784                    pw.println("  Recent tasks:");
13785                    printedHeader = true;
13786                    printedAnything = true;
13787                }
13788                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13789                        pw.println(tr);
13790                if (dumpAll) {
13791                    mRecentTasks.get(i).dump(pw, "    ");
13792                }
13793            }
13794        }
13795
13796        if (!printedAnything) {
13797            pw.println("  (nothing)");
13798        }
13799    }
13800
13801    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13802            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13803        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13804
13805        int dumpUid = 0;
13806        if (dumpPackage != null) {
13807            IPackageManager pm = AppGlobals.getPackageManager();
13808            try {
13809                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13810            } catch (RemoteException e) {
13811            }
13812        }
13813
13814        boolean printedAnything = false;
13815
13816        final long now = SystemClock.uptimeMillis();
13817
13818        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13819            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13820                    = mAssociations.valueAt(i1);
13821            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13822                SparseArray<ArrayMap<String, Association>> sourceUids
13823                        = targetComponents.valueAt(i2);
13824                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13825                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13826                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13827                        Association ass = sourceProcesses.valueAt(i4);
13828                        if (dumpPackage != null) {
13829                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13830                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13831                                continue;
13832                            }
13833                        }
13834                        printedAnything = true;
13835                        pw.print("  ");
13836                        pw.print(ass.mTargetProcess);
13837                        pw.print("/");
13838                        UserHandle.formatUid(pw, ass.mTargetUid);
13839                        pw.print(" <- ");
13840                        pw.print(ass.mSourceProcess);
13841                        pw.print("/");
13842                        UserHandle.formatUid(pw, ass.mSourceUid);
13843                        pw.println();
13844                        pw.print("    via ");
13845                        pw.print(ass.mTargetComponent.flattenToShortString());
13846                        pw.println();
13847                        pw.print("    ");
13848                        long dur = ass.mTime;
13849                        if (ass.mNesting > 0) {
13850                            dur += now - ass.mStartTime;
13851                        }
13852                        TimeUtils.formatDuration(dur, pw);
13853                        pw.print(" (");
13854                        pw.print(ass.mCount);
13855                        pw.print(" times)");
13856                        pw.print("  ");
13857                        for (int i=0; i<ass.mStateTimes.length; i++) {
13858                            long amt = ass.mStateTimes[i];
13859                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13860                                amt += now - ass.mLastStateUptime;
13861                            }
13862                            if (amt != 0) {
13863                                pw.print(" ");
13864                                pw.print(ProcessList.makeProcStateString(
13865                                            i + ActivityManager.MIN_PROCESS_STATE));
13866                                pw.print("=");
13867                                TimeUtils.formatDuration(amt, pw);
13868                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13869                                    pw.print("*");
13870                                }
13871                            }
13872                        }
13873                        pw.println();
13874                        if (ass.mNesting > 0) {
13875                            pw.print("    Currently active: ");
13876                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13877                            pw.println();
13878                        }
13879                    }
13880                }
13881            }
13882
13883        }
13884
13885        if (!printedAnything) {
13886            pw.println("  (nothing)");
13887        }
13888    }
13889
13890    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13891            String header, boolean needSep) {
13892        boolean printed = false;
13893        int whichAppId = -1;
13894        if (dumpPackage != null) {
13895            try {
13896                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13897                        dumpPackage, 0);
13898                whichAppId = UserHandle.getAppId(info.uid);
13899            } catch (NameNotFoundException e) {
13900                e.printStackTrace();
13901            }
13902        }
13903        for (int i=0; i<uids.size(); i++) {
13904            UidRecord uidRec = uids.valueAt(i);
13905            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13906                continue;
13907            }
13908            if (!printed) {
13909                printed = true;
13910                if (needSep) {
13911                    pw.println();
13912                }
13913                pw.print("  ");
13914                pw.println(header);
13915                needSep = true;
13916            }
13917            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13918            pw.print(": "); pw.println(uidRec);
13919        }
13920        return printed;
13921    }
13922
13923    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13924            int opti, boolean dumpAll, String dumpPackage) {
13925        boolean needSep = false;
13926        boolean printedAnything = false;
13927        int numPers = 0;
13928
13929        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13930
13931        if (dumpAll) {
13932            final int NP = mProcessNames.getMap().size();
13933            for (int ip=0; ip<NP; ip++) {
13934                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13935                final int NA = procs.size();
13936                for (int ia=0; ia<NA; ia++) {
13937                    ProcessRecord r = procs.valueAt(ia);
13938                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13939                        continue;
13940                    }
13941                    if (!needSep) {
13942                        pw.println("  All known processes:");
13943                        needSep = true;
13944                        printedAnything = true;
13945                    }
13946                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13947                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13948                        pw.print(" "); pw.println(r);
13949                    r.dump(pw, "    ");
13950                    if (r.persistent) {
13951                        numPers++;
13952                    }
13953                }
13954            }
13955        }
13956
13957        if (mIsolatedProcesses.size() > 0) {
13958            boolean printed = false;
13959            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13960                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13961                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13962                    continue;
13963                }
13964                if (!printed) {
13965                    if (needSep) {
13966                        pw.println();
13967                    }
13968                    pw.println("  Isolated process list (sorted by uid):");
13969                    printedAnything = true;
13970                    printed = true;
13971                    needSep = true;
13972                }
13973                pw.println(String.format("%sIsolated #%2d: %s",
13974                        "    ", i, r.toString()));
13975            }
13976        }
13977
13978        if (mActiveUids.size() > 0) {
13979            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13980                printedAnything = needSep = true;
13981            }
13982        }
13983        if (mValidateUids.size() > 0) {
13984            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13985                printedAnything = needSep = true;
13986            }
13987        }
13988
13989        if (mLruProcesses.size() > 0) {
13990            if (needSep) {
13991                pw.println();
13992            }
13993            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13994                    pw.print(" total, non-act at ");
13995                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13996                    pw.print(", non-svc at ");
13997                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13998                    pw.println("):");
13999            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14000            needSep = true;
14001            printedAnything = true;
14002        }
14003
14004        if (dumpAll || dumpPackage != null) {
14005            synchronized (mPidsSelfLocked) {
14006                boolean printed = false;
14007                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14008                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14009                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14010                        continue;
14011                    }
14012                    if (!printed) {
14013                        if (needSep) pw.println();
14014                        needSep = true;
14015                        pw.println("  PID mappings:");
14016                        printed = true;
14017                        printedAnything = true;
14018                    }
14019                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14020                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14021                }
14022            }
14023        }
14024
14025        if (mForegroundProcesses.size() > 0) {
14026            synchronized (mPidsSelfLocked) {
14027                boolean printed = false;
14028                for (int i=0; i<mForegroundProcesses.size(); i++) {
14029                    ProcessRecord r = mPidsSelfLocked.get(
14030                            mForegroundProcesses.valueAt(i).pid);
14031                    if (dumpPackage != null && (r == null
14032                            || !r.pkgList.containsKey(dumpPackage))) {
14033                        continue;
14034                    }
14035                    if (!printed) {
14036                        if (needSep) pw.println();
14037                        needSep = true;
14038                        pw.println("  Foreground Processes:");
14039                        printed = true;
14040                        printedAnything = true;
14041                    }
14042                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14043                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14044                }
14045            }
14046        }
14047
14048        if (mPersistentStartingProcesses.size() > 0) {
14049            if (needSep) pw.println();
14050            needSep = true;
14051            printedAnything = true;
14052            pw.println("  Persisent processes that are starting:");
14053            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14054                    "Starting Norm", "Restarting PERS", dumpPackage);
14055        }
14056
14057        if (mRemovedProcesses.size() > 0) {
14058            if (needSep) pw.println();
14059            needSep = true;
14060            printedAnything = true;
14061            pw.println("  Processes that are being removed:");
14062            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14063                    "Removed Norm", "Removed PERS", dumpPackage);
14064        }
14065
14066        if (mProcessesOnHold.size() > 0) {
14067            if (needSep) pw.println();
14068            needSep = true;
14069            printedAnything = true;
14070            pw.println("  Processes that are on old until the system is ready:");
14071            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14072                    "OnHold Norm", "OnHold PERS", dumpPackage);
14073        }
14074
14075        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14076
14077        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14078        if (needSep) {
14079            printedAnything = true;
14080        }
14081
14082        if (dumpPackage == null) {
14083            pw.println();
14084            needSep = false;
14085            mUserController.dump(pw, dumpAll);
14086        }
14087        if (mHomeProcess != null && (dumpPackage == null
14088                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14089            if (needSep) {
14090                pw.println();
14091                needSep = false;
14092            }
14093            pw.println("  mHomeProcess: " + mHomeProcess);
14094        }
14095        if (mPreviousProcess != null && (dumpPackage == null
14096                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14097            if (needSep) {
14098                pw.println();
14099                needSep = false;
14100            }
14101            pw.println("  mPreviousProcess: " + mPreviousProcess);
14102        }
14103        if (dumpAll) {
14104            StringBuilder sb = new StringBuilder(128);
14105            sb.append("  mPreviousProcessVisibleTime: ");
14106            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14107            pw.println(sb);
14108        }
14109        if (mHeavyWeightProcess != null && (dumpPackage == null
14110                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14111            if (needSep) {
14112                pw.println();
14113                needSep = false;
14114            }
14115            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14116        }
14117        if (dumpPackage == null) {
14118            pw.println("  mConfiguration: " + mConfiguration);
14119        }
14120        if (dumpAll) {
14121            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14122            if (mCompatModePackages.getPackages().size() > 0) {
14123                boolean printed = false;
14124                for (Map.Entry<String, Integer> entry
14125                        : mCompatModePackages.getPackages().entrySet()) {
14126                    String pkg = entry.getKey();
14127                    int mode = entry.getValue();
14128                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14129                        continue;
14130                    }
14131                    if (!printed) {
14132                        pw.println("  mScreenCompatPackages:");
14133                        printed = true;
14134                    }
14135                    pw.print("    "); pw.print(pkg); pw.print(": ");
14136                            pw.print(mode); pw.println();
14137                }
14138            }
14139        }
14140        if (dumpPackage == null) {
14141            pw.println("  mWakefulness="
14142                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14143            pw.println("  mSleepTokens=" + mSleepTokens);
14144            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14145                    + lockScreenShownToString());
14146            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14147            if (mRunningVoice != null) {
14148                pw.println("  mRunningVoice=" + mRunningVoice);
14149                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14150            }
14151        }
14152        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14153                || mOrigWaitForDebugger) {
14154            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14155                    || dumpPackage.equals(mOrigDebugApp)) {
14156                if (needSep) {
14157                    pw.println();
14158                    needSep = false;
14159                }
14160                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14161                        + " mDebugTransient=" + mDebugTransient
14162                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14163            }
14164        }
14165        if (mCurAppTimeTracker != null) {
14166            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14167        }
14168        if (mMemWatchProcesses.getMap().size() > 0) {
14169            pw.println("  Mem watch processes:");
14170            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14171                    = mMemWatchProcesses.getMap();
14172            for (int i=0; i<procs.size(); i++) {
14173                final String proc = procs.keyAt(i);
14174                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14175                for (int j=0; j<uids.size(); j++) {
14176                    if (needSep) {
14177                        pw.println();
14178                        needSep = false;
14179                    }
14180                    StringBuilder sb = new StringBuilder();
14181                    sb.append("    ").append(proc).append('/');
14182                    UserHandle.formatUid(sb, uids.keyAt(j));
14183                    Pair<Long, String> val = uids.valueAt(j);
14184                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14185                    if (val.second != null) {
14186                        sb.append(", report to ").append(val.second);
14187                    }
14188                    pw.println(sb.toString());
14189                }
14190            }
14191            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14192            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14193            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14194                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14195        }
14196        if (mTrackAllocationApp != null) {
14197            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14198                if (needSep) {
14199                    pw.println();
14200                    needSep = false;
14201                }
14202                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14203            }
14204        }
14205        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14206                || mProfileFd != null) {
14207            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14208                if (needSep) {
14209                    pw.println();
14210                    needSep = false;
14211                }
14212                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14213                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14214                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14215                        + mAutoStopProfiler);
14216                pw.println("  mProfileType=" + mProfileType);
14217            }
14218        }
14219        if (mNativeDebuggingApp != null) {
14220            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14221                if (needSep) {
14222                    pw.println();
14223                    needSep = false;
14224                }
14225                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14226            }
14227        }
14228        if (dumpPackage == null) {
14229            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14230                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14231                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14232            }
14233            if (mController != null) {
14234                pw.println("  mController=" + mController
14235                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14236            }
14237            if (dumpAll) {
14238                pw.println("  Total persistent processes: " + numPers);
14239                pw.println("  mProcessesReady=" + mProcessesReady
14240                        + " mSystemReady=" + mSystemReady
14241                        + " mBooted=" + mBooted
14242                        + " mFactoryTest=" + mFactoryTest);
14243                pw.println("  mBooting=" + mBooting
14244                        + " mCallFinishBooting=" + mCallFinishBooting
14245                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14246                pw.print("  mLastPowerCheckRealtime=");
14247                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14248                        pw.println("");
14249                pw.print("  mLastPowerCheckUptime=");
14250                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14251                        pw.println("");
14252                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14253                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14254                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14255                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14256                        + " (" + mLruProcesses.size() + " total)"
14257                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14258                        + " mNumServiceProcs=" + mNumServiceProcs
14259                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14260                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14261                        + " mLastMemoryLevel" + mLastMemoryLevel
14262                        + " mLastNumProcesses" + mLastNumProcesses);
14263                long now = SystemClock.uptimeMillis();
14264                pw.print("  mLastIdleTime=");
14265                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14266                        pw.print(" mLowRamSinceLastIdle=");
14267                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14268                        pw.println();
14269            }
14270        }
14271
14272        if (!printedAnything) {
14273            pw.println("  (nothing)");
14274        }
14275    }
14276
14277    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14278            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14279        if (mProcessesToGc.size() > 0) {
14280            boolean printed = false;
14281            long now = SystemClock.uptimeMillis();
14282            for (int i=0; i<mProcessesToGc.size(); i++) {
14283                ProcessRecord proc = mProcessesToGc.get(i);
14284                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14285                    continue;
14286                }
14287                if (!printed) {
14288                    if (needSep) pw.println();
14289                    needSep = true;
14290                    pw.println("  Processes that are waiting to GC:");
14291                    printed = true;
14292                }
14293                pw.print("    Process "); pw.println(proc);
14294                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14295                        pw.print(", last gced=");
14296                        pw.print(now-proc.lastRequestedGc);
14297                        pw.print(" ms ago, last lowMem=");
14298                        pw.print(now-proc.lastLowMemory);
14299                        pw.println(" ms ago");
14300
14301            }
14302        }
14303        return needSep;
14304    }
14305
14306    void printOomLevel(PrintWriter pw, String name, int adj) {
14307        pw.print("    ");
14308        if (adj >= 0) {
14309            pw.print(' ');
14310            if (adj < 10) pw.print(' ');
14311        } else {
14312            if (adj > -10) pw.print(' ');
14313        }
14314        pw.print(adj);
14315        pw.print(": ");
14316        pw.print(name);
14317        pw.print(" (");
14318        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14319        pw.println(")");
14320    }
14321
14322    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14323            int opti, boolean dumpAll) {
14324        boolean needSep = false;
14325
14326        if (mLruProcesses.size() > 0) {
14327            if (needSep) pw.println();
14328            needSep = true;
14329            pw.println("  OOM levels:");
14330            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14331            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14332            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14333            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14334            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14335            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14336            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14337            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14338            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14339            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14340            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14341            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14342            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14343            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14344
14345            if (needSep) pw.println();
14346            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14347                    pw.print(" total, non-act at ");
14348                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14349                    pw.print(", non-svc at ");
14350                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14351                    pw.println("):");
14352            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14353            needSep = true;
14354        }
14355
14356        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14357
14358        pw.println();
14359        pw.println("  mHomeProcess: " + mHomeProcess);
14360        pw.println("  mPreviousProcess: " + mPreviousProcess);
14361        if (mHeavyWeightProcess != null) {
14362            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14363        }
14364
14365        return true;
14366    }
14367
14368    /**
14369     * There are three ways to call this:
14370     *  - no provider specified: dump all the providers
14371     *  - a flattened component name that matched an existing provider was specified as the
14372     *    first arg: dump that one provider
14373     *  - the first arg isn't the flattened component name of an existing provider:
14374     *    dump all providers whose component contains the first arg as a substring
14375     */
14376    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14377            int opti, boolean dumpAll) {
14378        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14379    }
14380
14381    static class ItemMatcher {
14382        ArrayList<ComponentName> components;
14383        ArrayList<String> strings;
14384        ArrayList<Integer> objects;
14385        boolean all;
14386
14387        ItemMatcher() {
14388            all = true;
14389        }
14390
14391        void build(String name) {
14392            ComponentName componentName = ComponentName.unflattenFromString(name);
14393            if (componentName != null) {
14394                if (components == null) {
14395                    components = new ArrayList<ComponentName>();
14396                }
14397                components.add(componentName);
14398                all = false;
14399            } else {
14400                int objectId = 0;
14401                // Not a '/' separated full component name; maybe an object ID?
14402                try {
14403                    objectId = Integer.parseInt(name, 16);
14404                    if (objects == null) {
14405                        objects = new ArrayList<Integer>();
14406                    }
14407                    objects.add(objectId);
14408                    all = false;
14409                } catch (RuntimeException e) {
14410                    // Not an integer; just do string match.
14411                    if (strings == null) {
14412                        strings = new ArrayList<String>();
14413                    }
14414                    strings.add(name);
14415                    all = false;
14416                }
14417            }
14418        }
14419
14420        int build(String[] args, int opti) {
14421            for (; opti<args.length; opti++) {
14422                String name = args[opti];
14423                if ("--".equals(name)) {
14424                    return opti+1;
14425                }
14426                build(name);
14427            }
14428            return opti;
14429        }
14430
14431        boolean match(Object object, ComponentName comp) {
14432            if (all) {
14433                return true;
14434            }
14435            if (components != null) {
14436                for (int i=0; i<components.size(); i++) {
14437                    if (components.get(i).equals(comp)) {
14438                        return true;
14439                    }
14440                }
14441            }
14442            if (objects != null) {
14443                for (int i=0; i<objects.size(); i++) {
14444                    if (System.identityHashCode(object) == objects.get(i)) {
14445                        return true;
14446                    }
14447                }
14448            }
14449            if (strings != null) {
14450                String flat = comp.flattenToString();
14451                for (int i=0; i<strings.size(); i++) {
14452                    if (flat.contains(strings.get(i))) {
14453                        return true;
14454                    }
14455                }
14456            }
14457            return false;
14458        }
14459    }
14460
14461    /**
14462     * There are three things that cmd can be:
14463     *  - a flattened component name that matches an existing activity
14464     *  - the cmd arg isn't the flattened component name of an existing activity:
14465     *    dump all activity whose component contains the cmd as a substring
14466     *  - A hex number of the ActivityRecord object instance.
14467     */
14468    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14469            int opti, boolean dumpAll) {
14470        ArrayList<ActivityRecord> activities;
14471
14472        synchronized (this) {
14473            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14474        }
14475
14476        if (activities.size() <= 0) {
14477            return false;
14478        }
14479
14480        String[] newArgs = new String[args.length - opti];
14481        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14482
14483        TaskRecord lastTask = null;
14484        boolean needSep = false;
14485        for (int i=activities.size()-1; i>=0; i--) {
14486            ActivityRecord r = activities.get(i);
14487            if (needSep) {
14488                pw.println();
14489            }
14490            needSep = true;
14491            synchronized (this) {
14492                if (lastTask != r.task) {
14493                    lastTask = r.task;
14494                    pw.print("TASK "); pw.print(lastTask.affinity);
14495                            pw.print(" id="); pw.println(lastTask.taskId);
14496                    if (dumpAll) {
14497                        lastTask.dump(pw, "  ");
14498                    }
14499                }
14500            }
14501            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14502        }
14503        return true;
14504    }
14505
14506    /**
14507     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14508     * there is a thread associated with the activity.
14509     */
14510    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14511            final ActivityRecord r, String[] args, boolean dumpAll) {
14512        String innerPrefix = prefix + "  ";
14513        synchronized (this) {
14514            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14515                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14516                    pw.print(" pid=");
14517                    if (r.app != null) pw.println(r.app.pid);
14518                    else pw.println("(not running)");
14519            if (dumpAll) {
14520                r.dump(pw, innerPrefix);
14521            }
14522        }
14523        if (r.app != null && r.app.thread != null) {
14524            // flush anything that is already in the PrintWriter since the thread is going
14525            // to write to the file descriptor directly
14526            pw.flush();
14527            try {
14528                TransferPipe tp = new TransferPipe();
14529                try {
14530                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14531                            r.appToken, innerPrefix, args);
14532                    tp.go(fd);
14533                } finally {
14534                    tp.kill();
14535                }
14536            } catch (IOException e) {
14537                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14538            } catch (RemoteException e) {
14539                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14540            }
14541        }
14542    }
14543
14544    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14545            int opti, boolean dumpAll, String dumpPackage) {
14546        boolean needSep = false;
14547        boolean onlyHistory = false;
14548        boolean printedAnything = false;
14549
14550        if ("history".equals(dumpPackage)) {
14551            if (opti < args.length && "-s".equals(args[opti])) {
14552                dumpAll = false;
14553            }
14554            onlyHistory = true;
14555            dumpPackage = null;
14556        }
14557
14558        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14559        if (!onlyHistory && dumpAll) {
14560            if (mRegisteredReceivers.size() > 0) {
14561                boolean printed = false;
14562                Iterator it = mRegisteredReceivers.values().iterator();
14563                while (it.hasNext()) {
14564                    ReceiverList r = (ReceiverList)it.next();
14565                    if (dumpPackage != null && (r.app == null ||
14566                            !dumpPackage.equals(r.app.info.packageName))) {
14567                        continue;
14568                    }
14569                    if (!printed) {
14570                        pw.println("  Registered Receivers:");
14571                        needSep = true;
14572                        printed = true;
14573                        printedAnything = true;
14574                    }
14575                    pw.print("  * "); pw.println(r);
14576                    r.dump(pw, "    ");
14577                }
14578            }
14579
14580            if (mReceiverResolver.dump(pw, needSep ?
14581                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14582                    "    ", dumpPackage, false, false)) {
14583                needSep = true;
14584                printedAnything = true;
14585            }
14586        }
14587
14588        for (BroadcastQueue q : mBroadcastQueues) {
14589            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14590            printedAnything |= needSep;
14591        }
14592
14593        needSep = true;
14594
14595        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14596            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14597                if (needSep) {
14598                    pw.println();
14599                }
14600                needSep = true;
14601                printedAnything = true;
14602                pw.print("  Sticky broadcasts for user ");
14603                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14604                StringBuilder sb = new StringBuilder(128);
14605                for (Map.Entry<String, ArrayList<Intent>> ent
14606                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14607                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14608                    if (dumpAll) {
14609                        pw.println(":");
14610                        ArrayList<Intent> intents = ent.getValue();
14611                        final int N = intents.size();
14612                        for (int i=0; i<N; i++) {
14613                            sb.setLength(0);
14614                            sb.append("    Intent: ");
14615                            intents.get(i).toShortString(sb, false, true, false, false);
14616                            pw.println(sb.toString());
14617                            Bundle bundle = intents.get(i).getExtras();
14618                            if (bundle != null) {
14619                                pw.print("      ");
14620                                pw.println(bundle.toString());
14621                            }
14622                        }
14623                    } else {
14624                        pw.println("");
14625                    }
14626                }
14627            }
14628        }
14629
14630        if (!onlyHistory && dumpAll) {
14631            pw.println();
14632            for (BroadcastQueue queue : mBroadcastQueues) {
14633                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14634                        + queue.mBroadcastsScheduled);
14635            }
14636            pw.println("  mHandler:");
14637            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14638            needSep = true;
14639            printedAnything = true;
14640        }
14641
14642        if (!printedAnything) {
14643            pw.println("  (nothing)");
14644        }
14645    }
14646
14647    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14648            int opti, boolean dumpAll, String dumpPackage) {
14649        boolean needSep;
14650        boolean printedAnything = false;
14651
14652        ItemMatcher matcher = new ItemMatcher();
14653        matcher.build(args, opti);
14654
14655        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14656
14657        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14658        printedAnything |= needSep;
14659
14660        if (mLaunchingProviders.size() > 0) {
14661            boolean printed = false;
14662            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14663                ContentProviderRecord r = mLaunchingProviders.get(i);
14664                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14665                    continue;
14666                }
14667                if (!printed) {
14668                    if (needSep) pw.println();
14669                    needSep = true;
14670                    pw.println("  Launching content providers:");
14671                    printed = true;
14672                    printedAnything = true;
14673                }
14674                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14675                        pw.println(r);
14676            }
14677        }
14678
14679        if (!printedAnything) {
14680            pw.println("  (nothing)");
14681        }
14682    }
14683
14684    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14685            int opti, boolean dumpAll, String dumpPackage) {
14686        boolean needSep = false;
14687        boolean printedAnything = false;
14688
14689        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14690
14691        if (mGrantedUriPermissions.size() > 0) {
14692            boolean printed = false;
14693            int dumpUid = -2;
14694            if (dumpPackage != null) {
14695                try {
14696                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14697                            MATCH_UNINSTALLED_PACKAGES, 0);
14698                } catch (NameNotFoundException e) {
14699                    dumpUid = -1;
14700                }
14701            }
14702            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14703                int uid = mGrantedUriPermissions.keyAt(i);
14704                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14705                    continue;
14706                }
14707                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14708                if (!printed) {
14709                    if (needSep) pw.println();
14710                    needSep = true;
14711                    pw.println("  Granted Uri Permissions:");
14712                    printed = true;
14713                    printedAnything = true;
14714                }
14715                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14716                for (UriPermission perm : perms.values()) {
14717                    pw.print("    "); pw.println(perm);
14718                    if (dumpAll) {
14719                        perm.dump(pw, "      ");
14720                    }
14721                }
14722            }
14723        }
14724
14725        if (!printedAnything) {
14726            pw.println("  (nothing)");
14727        }
14728    }
14729
14730    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14731            int opti, boolean dumpAll, String dumpPackage) {
14732        boolean printed = false;
14733
14734        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14735
14736        if (mIntentSenderRecords.size() > 0) {
14737            Iterator<WeakReference<PendingIntentRecord>> it
14738                    = mIntentSenderRecords.values().iterator();
14739            while (it.hasNext()) {
14740                WeakReference<PendingIntentRecord> ref = it.next();
14741                PendingIntentRecord rec = ref != null ? ref.get(): null;
14742                if (dumpPackage != null && (rec == null
14743                        || !dumpPackage.equals(rec.key.packageName))) {
14744                    continue;
14745                }
14746                printed = true;
14747                if (rec != null) {
14748                    pw.print("  * "); pw.println(rec);
14749                    if (dumpAll) {
14750                        rec.dump(pw, "    ");
14751                    }
14752                } else {
14753                    pw.print("  * "); pw.println(ref);
14754                }
14755            }
14756        }
14757
14758        if (!printed) {
14759            pw.println("  (nothing)");
14760        }
14761    }
14762
14763    private static final int dumpProcessList(PrintWriter pw,
14764            ActivityManagerService service, List list,
14765            String prefix, String normalLabel, String persistentLabel,
14766            String dumpPackage) {
14767        int numPers = 0;
14768        final int N = list.size()-1;
14769        for (int i=N; i>=0; i--) {
14770            ProcessRecord r = (ProcessRecord)list.get(i);
14771            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14772                continue;
14773            }
14774            pw.println(String.format("%s%s #%2d: %s",
14775                    prefix, (r.persistent ? persistentLabel : normalLabel),
14776                    i, r.toString()));
14777            if (r.persistent) {
14778                numPers++;
14779            }
14780        }
14781        return numPers;
14782    }
14783
14784    private static final boolean dumpProcessOomList(PrintWriter pw,
14785            ActivityManagerService service, List<ProcessRecord> origList,
14786            String prefix, String normalLabel, String persistentLabel,
14787            boolean inclDetails, String dumpPackage) {
14788
14789        ArrayList<Pair<ProcessRecord, Integer>> list
14790                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14791        for (int i=0; i<origList.size(); i++) {
14792            ProcessRecord r = origList.get(i);
14793            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14794                continue;
14795            }
14796            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14797        }
14798
14799        if (list.size() <= 0) {
14800            return false;
14801        }
14802
14803        Comparator<Pair<ProcessRecord, Integer>> comparator
14804                = new Comparator<Pair<ProcessRecord, Integer>>() {
14805            @Override
14806            public int compare(Pair<ProcessRecord, Integer> object1,
14807                    Pair<ProcessRecord, Integer> object2) {
14808                if (object1.first.setAdj != object2.first.setAdj) {
14809                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14810                }
14811                if (object1.first.setProcState != object2.first.setProcState) {
14812                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14813                }
14814                if (object1.second.intValue() != object2.second.intValue()) {
14815                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14816                }
14817                return 0;
14818            }
14819        };
14820
14821        Collections.sort(list, comparator);
14822
14823        final long curRealtime = SystemClock.elapsedRealtime();
14824        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14825        final long curUptime = SystemClock.uptimeMillis();
14826        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14827
14828        for (int i=list.size()-1; i>=0; i--) {
14829            ProcessRecord r = list.get(i).first;
14830            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14831            char schedGroup;
14832            switch (r.setSchedGroup) {
14833                case ProcessList.SCHED_GROUP_BACKGROUND:
14834                    schedGroup = 'B';
14835                    break;
14836                case ProcessList.SCHED_GROUP_DEFAULT:
14837                    schedGroup = 'F';
14838                    break;
14839                case ProcessList.SCHED_GROUP_TOP_APP:
14840                    schedGroup = 'T';
14841                    break;
14842                default:
14843                    schedGroup = '?';
14844                    break;
14845            }
14846            char foreground;
14847            if (r.foregroundActivities) {
14848                foreground = 'A';
14849            } else if (r.foregroundServices) {
14850                foreground = 'S';
14851            } else {
14852                foreground = ' ';
14853            }
14854            String procState = ProcessList.makeProcStateString(r.curProcState);
14855            pw.print(prefix);
14856            pw.print(r.persistent ? persistentLabel : normalLabel);
14857            pw.print(" #");
14858            int num = (origList.size()-1)-list.get(i).second;
14859            if (num < 10) pw.print(' ');
14860            pw.print(num);
14861            pw.print(": ");
14862            pw.print(oomAdj);
14863            pw.print(' ');
14864            pw.print(schedGroup);
14865            pw.print('/');
14866            pw.print(foreground);
14867            pw.print('/');
14868            pw.print(procState);
14869            pw.print(" trm:");
14870            if (r.trimMemoryLevel < 10) pw.print(' ');
14871            pw.print(r.trimMemoryLevel);
14872            pw.print(' ');
14873            pw.print(r.toShortString());
14874            pw.print(" (");
14875            pw.print(r.adjType);
14876            pw.println(')');
14877            if (r.adjSource != null || r.adjTarget != null) {
14878                pw.print(prefix);
14879                pw.print("    ");
14880                if (r.adjTarget instanceof ComponentName) {
14881                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14882                } else if (r.adjTarget != null) {
14883                    pw.print(r.adjTarget.toString());
14884                } else {
14885                    pw.print("{null}");
14886                }
14887                pw.print("<=");
14888                if (r.adjSource instanceof ProcessRecord) {
14889                    pw.print("Proc{");
14890                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14891                    pw.println("}");
14892                } else if (r.adjSource != null) {
14893                    pw.println(r.adjSource.toString());
14894                } else {
14895                    pw.println("{null}");
14896                }
14897            }
14898            if (inclDetails) {
14899                pw.print(prefix);
14900                pw.print("    ");
14901                pw.print("oom: max="); pw.print(r.maxAdj);
14902                pw.print(" curRaw="); pw.print(r.curRawAdj);
14903                pw.print(" setRaw="); pw.print(r.setRawAdj);
14904                pw.print(" cur="); pw.print(r.curAdj);
14905                pw.print(" set="); pw.println(r.setAdj);
14906                pw.print(prefix);
14907                pw.print("    ");
14908                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14909                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14910                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14911                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14912                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14913                pw.println();
14914                pw.print(prefix);
14915                pw.print("    ");
14916                pw.print("cached="); pw.print(r.cached);
14917                pw.print(" empty="); pw.print(r.empty);
14918                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14919
14920                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14921                    if (r.lastWakeTime != 0) {
14922                        long wtime;
14923                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14924                        synchronized (stats) {
14925                            wtime = stats.getProcessWakeTime(r.info.uid,
14926                                    r.pid, curRealtime);
14927                        }
14928                        long timeUsed = wtime - r.lastWakeTime;
14929                        pw.print(prefix);
14930                        pw.print("    ");
14931                        pw.print("keep awake over ");
14932                        TimeUtils.formatDuration(realtimeSince, pw);
14933                        pw.print(" used ");
14934                        TimeUtils.formatDuration(timeUsed, pw);
14935                        pw.print(" (");
14936                        pw.print((timeUsed*100)/realtimeSince);
14937                        pw.println("%)");
14938                    }
14939                    if (r.lastCpuTime != 0) {
14940                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14941                        pw.print(prefix);
14942                        pw.print("    ");
14943                        pw.print("run cpu over ");
14944                        TimeUtils.formatDuration(uptimeSince, pw);
14945                        pw.print(" used ");
14946                        TimeUtils.formatDuration(timeUsed, pw);
14947                        pw.print(" (");
14948                        pw.print((timeUsed*100)/uptimeSince);
14949                        pw.println("%)");
14950                    }
14951                }
14952            }
14953        }
14954        return true;
14955    }
14956
14957    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14958            String[] args) {
14959        ArrayList<ProcessRecord> procs;
14960        synchronized (this) {
14961            if (args != null && args.length > start
14962                    && args[start].charAt(0) != '-') {
14963                procs = new ArrayList<ProcessRecord>();
14964                int pid = -1;
14965                try {
14966                    pid = Integer.parseInt(args[start]);
14967                } catch (NumberFormatException e) {
14968                }
14969                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14970                    ProcessRecord proc = mLruProcesses.get(i);
14971                    if (proc.pid == pid) {
14972                        procs.add(proc);
14973                    } else if (allPkgs && proc.pkgList != null
14974                            && proc.pkgList.containsKey(args[start])) {
14975                        procs.add(proc);
14976                    } else if (proc.processName.equals(args[start])) {
14977                        procs.add(proc);
14978                    }
14979                }
14980                if (procs.size() <= 0) {
14981                    return null;
14982                }
14983            } else {
14984                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14985            }
14986        }
14987        return procs;
14988    }
14989
14990    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14991            PrintWriter pw, String[] args) {
14992        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14993        if (procs == null) {
14994            pw.println("No process found for: " + args[0]);
14995            return;
14996        }
14997
14998        long uptime = SystemClock.uptimeMillis();
14999        long realtime = SystemClock.elapsedRealtime();
15000        pw.println("Applications Graphics Acceleration Info:");
15001        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15002
15003        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15004            ProcessRecord r = procs.get(i);
15005            if (r.thread != null) {
15006                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15007                pw.flush();
15008                try {
15009                    TransferPipe tp = new TransferPipe();
15010                    try {
15011                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15012                        tp.go(fd);
15013                    } finally {
15014                        tp.kill();
15015                    }
15016                } catch (IOException e) {
15017                    pw.println("Failure while dumping the app: " + r);
15018                    pw.flush();
15019                } catch (RemoteException e) {
15020                    pw.println("Got a RemoteException while dumping the app " + r);
15021                    pw.flush();
15022                }
15023            }
15024        }
15025    }
15026
15027    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15028        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15029        if (procs == null) {
15030            pw.println("No process found for: " + args[0]);
15031            return;
15032        }
15033
15034        pw.println("Applications Database Info:");
15035
15036        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15037            ProcessRecord r = procs.get(i);
15038            if (r.thread != null) {
15039                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15040                pw.flush();
15041                try {
15042                    TransferPipe tp = new TransferPipe();
15043                    try {
15044                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15045                        tp.go(fd);
15046                    } finally {
15047                        tp.kill();
15048                    }
15049                } catch (IOException e) {
15050                    pw.println("Failure while dumping the app: " + r);
15051                    pw.flush();
15052                } catch (RemoteException e) {
15053                    pw.println("Got a RemoteException while dumping the app " + r);
15054                    pw.flush();
15055                }
15056            }
15057        }
15058    }
15059
15060    final static class MemItem {
15061        final boolean isProc;
15062        final String label;
15063        final String shortLabel;
15064        final long pss;
15065        final long swapPss;
15066        final int id;
15067        final boolean hasActivities;
15068        ArrayList<MemItem> subitems;
15069
15070        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15071                boolean _hasActivities) {
15072            isProc = true;
15073            label = _label;
15074            shortLabel = _shortLabel;
15075            pss = _pss;
15076            swapPss = _swapPss;
15077            id = _id;
15078            hasActivities = _hasActivities;
15079        }
15080
15081        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15082            isProc = false;
15083            label = _label;
15084            shortLabel = _shortLabel;
15085            pss = _pss;
15086            swapPss = _swapPss;
15087            id = _id;
15088            hasActivities = false;
15089        }
15090    }
15091
15092    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15093            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15094        if (sort && !isCompact) {
15095            Collections.sort(items, new Comparator<MemItem>() {
15096                @Override
15097                public int compare(MemItem lhs, MemItem rhs) {
15098                    if (lhs.pss < rhs.pss) {
15099                        return 1;
15100                    } else if (lhs.pss > rhs.pss) {
15101                        return -1;
15102                    }
15103                    return 0;
15104                }
15105            });
15106        }
15107
15108        for (int i=0; i<items.size(); i++) {
15109            MemItem mi = items.get(i);
15110            if (!isCompact) {
15111                if (dumpSwapPss) {
15112                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15113                            mi.label, stringifyKBSize(mi.swapPss));
15114                } else {
15115                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15116                }
15117            } else if (mi.isProc) {
15118                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15119                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15120                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15121                pw.println(mi.hasActivities ? ",a" : ",e");
15122            } else {
15123                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15124                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15125            }
15126            if (mi.subitems != null) {
15127                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15128                        true, isCompact, dumpSwapPss);
15129            }
15130        }
15131    }
15132
15133    // These are in KB.
15134    static final long[] DUMP_MEM_BUCKETS = new long[] {
15135        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15136        120*1024, 160*1024, 200*1024,
15137        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15138        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15139    };
15140
15141    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15142            boolean stackLike) {
15143        int start = label.lastIndexOf('.');
15144        if (start >= 0) start++;
15145        else start = 0;
15146        int end = label.length();
15147        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15148            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15149                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15150                out.append(bucket);
15151                out.append(stackLike ? "MB." : "MB ");
15152                out.append(label, start, end);
15153                return;
15154            }
15155        }
15156        out.append(memKB/1024);
15157        out.append(stackLike ? "MB." : "MB ");
15158        out.append(label, start, end);
15159    }
15160
15161    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15162            ProcessList.NATIVE_ADJ,
15163            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15164            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15165            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15166            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15167            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15168            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15169    };
15170    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15171            "Native",
15172            "System", "Persistent", "Persistent Service", "Foreground",
15173            "Visible", "Perceptible",
15174            "Heavy Weight", "Backup",
15175            "A Services", "Home",
15176            "Previous", "B Services", "Cached"
15177    };
15178    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15179            "native",
15180            "sys", "pers", "persvc", "fore",
15181            "vis", "percept",
15182            "heavy", "backup",
15183            "servicea", "home",
15184            "prev", "serviceb", "cached"
15185    };
15186
15187    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15188            long realtime, boolean isCheckinRequest, boolean isCompact) {
15189        if (isCompact) {
15190            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15191        }
15192        if (isCheckinRequest || isCompact) {
15193            // short checkin version
15194            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15195        } else {
15196            pw.println("Applications Memory Usage (in Kilobytes):");
15197            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15198        }
15199    }
15200
15201    private static final int KSM_SHARED = 0;
15202    private static final int KSM_SHARING = 1;
15203    private static final int KSM_UNSHARED = 2;
15204    private static final int KSM_VOLATILE = 3;
15205
15206    private final long[] getKsmInfo() {
15207        long[] longOut = new long[4];
15208        final int[] SINGLE_LONG_FORMAT = new int[] {
15209            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15210        };
15211        long[] longTmp = new long[1];
15212        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15213                SINGLE_LONG_FORMAT, null, longTmp, null);
15214        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15215        longTmp[0] = 0;
15216        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15217                SINGLE_LONG_FORMAT, null, longTmp, null);
15218        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15219        longTmp[0] = 0;
15220        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15221                SINGLE_LONG_FORMAT, null, longTmp, null);
15222        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15223        longTmp[0] = 0;
15224        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15225                SINGLE_LONG_FORMAT, null, longTmp, null);
15226        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15227        return longOut;
15228    }
15229
15230    private static String stringifySize(long size, int order) {
15231        Locale locale = Locale.US;
15232        switch (order) {
15233            case 1:
15234                return String.format(locale, "%,13d", size);
15235            case 1024:
15236                return String.format(locale, "%,9dK", size / 1024);
15237            case 1024 * 1024:
15238                return String.format(locale, "%,5dM", size / 1024 / 1024);
15239            case 1024 * 1024 * 1024:
15240                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15241            default:
15242                throw new IllegalArgumentException("Invalid size order");
15243        }
15244    }
15245
15246    private static String stringifyKBSize(long size) {
15247        return stringifySize(size * 1024, 1024);
15248    }
15249
15250    // Update this version number in case you change the 'compact' format
15251    private static final int MEMINFO_COMPACT_VERSION = 1;
15252
15253    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15254            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15255        boolean dumpDetails = false;
15256        boolean dumpFullDetails = false;
15257        boolean dumpDalvik = false;
15258        boolean dumpSummaryOnly = false;
15259        boolean dumpUnreachable = false;
15260        boolean oomOnly = false;
15261        boolean isCompact = false;
15262        boolean localOnly = false;
15263        boolean packages = false;
15264        boolean isCheckinRequest = false;
15265        boolean dumpSwapPss = false;
15266
15267        int opti = 0;
15268        while (opti < args.length) {
15269            String opt = args[opti];
15270            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15271                break;
15272            }
15273            opti++;
15274            if ("-a".equals(opt)) {
15275                dumpDetails = true;
15276                dumpFullDetails = true;
15277                dumpDalvik = true;
15278                dumpSwapPss = true;
15279            } else if ("-d".equals(opt)) {
15280                dumpDalvik = true;
15281            } else if ("-c".equals(opt)) {
15282                isCompact = true;
15283            } else if ("-s".equals(opt)) {
15284                dumpDetails = true;
15285                dumpSummaryOnly = true;
15286            } else if ("-S".equals(opt)) {
15287                dumpSwapPss = true;
15288            } else if ("--unreachable".equals(opt)) {
15289                dumpUnreachable = true;
15290            } else if ("--oom".equals(opt)) {
15291                oomOnly = true;
15292            } else if ("--local".equals(opt)) {
15293                localOnly = true;
15294            } else if ("--package".equals(opt)) {
15295                packages = true;
15296            } else if ("--checkin".equals(opt)) {
15297                isCheckinRequest = true;
15298
15299            } else if ("-h".equals(opt)) {
15300                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15301                pw.println("  -a: include all available information for each process.");
15302                pw.println("  -d: include dalvik details.");
15303                pw.println("  -c: dump in a compact machine-parseable representation.");
15304                pw.println("  -s: dump only summary of application memory usage.");
15305                pw.println("  -S: dump also SwapPss.");
15306                pw.println("  --oom: only show processes organized by oom adj.");
15307                pw.println("  --local: only collect details locally, don't call process.");
15308                pw.println("  --package: interpret process arg as package, dumping all");
15309                pw.println("             processes that have loaded that package.");
15310                pw.println("  --checkin: dump data for a checkin");
15311                pw.println("If [process] is specified it can be the name or ");
15312                pw.println("pid of a specific process to dump.");
15313                return;
15314            } else {
15315                pw.println("Unknown argument: " + opt + "; use -h for help");
15316            }
15317        }
15318
15319        long uptime = SystemClock.uptimeMillis();
15320        long realtime = SystemClock.elapsedRealtime();
15321        final long[] tmpLong = new long[1];
15322
15323        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15324        if (procs == null) {
15325            // No Java processes.  Maybe they want to print a native process.
15326            if (args != null && args.length > opti
15327                    && args[opti].charAt(0) != '-') {
15328                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15329                        = new ArrayList<ProcessCpuTracker.Stats>();
15330                updateCpuStatsNow();
15331                int findPid = -1;
15332                try {
15333                    findPid = Integer.parseInt(args[opti]);
15334                } catch (NumberFormatException e) {
15335                }
15336                synchronized (mProcessCpuTracker) {
15337                    final int N = mProcessCpuTracker.countStats();
15338                    for (int i=0; i<N; i++) {
15339                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15340                        if (st.pid == findPid || (st.baseName != null
15341                                && st.baseName.equals(args[opti]))) {
15342                            nativeProcs.add(st);
15343                        }
15344                    }
15345                }
15346                if (nativeProcs.size() > 0) {
15347                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15348                            isCompact);
15349                    Debug.MemoryInfo mi = null;
15350                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15351                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15352                        final int pid = r.pid;
15353                        if (!isCheckinRequest && dumpDetails) {
15354                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15355                        }
15356                        if (mi == null) {
15357                            mi = new Debug.MemoryInfo();
15358                        }
15359                        if (dumpDetails || (!brief && !oomOnly)) {
15360                            Debug.getMemoryInfo(pid, mi);
15361                        } else {
15362                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15363                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15364                        }
15365                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15366                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15367                        if (isCheckinRequest) {
15368                            pw.println();
15369                        }
15370                    }
15371                    return;
15372                }
15373            }
15374            pw.println("No process found for: " + args[opti]);
15375            return;
15376        }
15377
15378        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15379            dumpDetails = true;
15380        }
15381
15382        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15383
15384        String[] innerArgs = new String[args.length-opti];
15385        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15386
15387        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15388        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15389        long nativePss = 0;
15390        long nativeSwapPss = 0;
15391        long dalvikPss = 0;
15392        long dalvikSwapPss = 0;
15393        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15394                EmptyArray.LONG;
15395        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15396                EmptyArray.LONG;
15397        long otherPss = 0;
15398        long otherSwapPss = 0;
15399        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15400        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15401
15402        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15403        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15404        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15405                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15406
15407        long totalPss = 0;
15408        long totalSwapPss = 0;
15409        long cachedPss = 0;
15410        long cachedSwapPss = 0;
15411        boolean hasSwapPss = false;
15412
15413        Debug.MemoryInfo mi = null;
15414        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15415            final ProcessRecord r = procs.get(i);
15416            final IApplicationThread thread;
15417            final int pid;
15418            final int oomAdj;
15419            final boolean hasActivities;
15420            synchronized (this) {
15421                thread = r.thread;
15422                pid = r.pid;
15423                oomAdj = r.getSetAdjWithServices();
15424                hasActivities = r.activities.size() > 0;
15425            }
15426            if (thread != null) {
15427                if (!isCheckinRequest && dumpDetails) {
15428                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15429                }
15430                if (mi == null) {
15431                    mi = new Debug.MemoryInfo();
15432                }
15433                if (dumpDetails || (!brief && !oomOnly)) {
15434                    Debug.getMemoryInfo(pid, mi);
15435                    hasSwapPss = mi.hasSwappedOutPss;
15436                } else {
15437                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15438                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15439                }
15440                if (dumpDetails) {
15441                    if (localOnly) {
15442                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15443                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15444                        if (isCheckinRequest) {
15445                            pw.println();
15446                        }
15447                    } else {
15448                        try {
15449                            pw.flush();
15450                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15451                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15452                        } catch (RemoteException e) {
15453                            if (!isCheckinRequest) {
15454                                pw.println("Got RemoteException!");
15455                                pw.flush();
15456                            }
15457                        }
15458                    }
15459                }
15460
15461                final long myTotalPss = mi.getTotalPss();
15462                final long myTotalUss = mi.getTotalUss();
15463                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15464
15465                synchronized (this) {
15466                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15467                        // Record this for posterity if the process has been stable.
15468                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15469                    }
15470                }
15471
15472                if (!isCheckinRequest && mi != null) {
15473                    totalPss += myTotalPss;
15474                    totalSwapPss += myTotalSwapPss;
15475                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15476                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15477                            myTotalSwapPss, pid, hasActivities);
15478                    procMems.add(pssItem);
15479                    procMemsMap.put(pid, pssItem);
15480
15481                    nativePss += mi.nativePss;
15482                    nativeSwapPss += mi.nativeSwappedOutPss;
15483                    dalvikPss += mi.dalvikPss;
15484                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15485                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15486                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15487                        dalvikSubitemSwapPss[j] +=
15488                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15489                    }
15490                    otherPss += mi.otherPss;
15491                    otherSwapPss += mi.otherSwappedOutPss;
15492                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15493                        long mem = mi.getOtherPss(j);
15494                        miscPss[j] += mem;
15495                        otherPss -= mem;
15496                        mem = mi.getOtherSwappedOutPss(j);
15497                        miscSwapPss[j] += mem;
15498                        otherSwapPss -= mem;
15499                    }
15500
15501                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15502                        cachedPss += myTotalPss;
15503                        cachedSwapPss += myTotalSwapPss;
15504                    }
15505
15506                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15507                        if (oomIndex == (oomPss.length - 1)
15508                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15509                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15510                            oomPss[oomIndex] += myTotalPss;
15511                            oomSwapPss[oomIndex] += myTotalSwapPss;
15512                            if (oomProcs[oomIndex] == null) {
15513                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15514                            }
15515                            oomProcs[oomIndex].add(pssItem);
15516                            break;
15517                        }
15518                    }
15519                }
15520            }
15521        }
15522
15523        long nativeProcTotalPss = 0;
15524
15525        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15526            // If we are showing aggregations, also look for native processes to
15527            // include so that our aggregations are more accurate.
15528            updateCpuStatsNow();
15529            mi = null;
15530            synchronized (mProcessCpuTracker) {
15531                final int N = mProcessCpuTracker.countStats();
15532                for (int i=0; i<N; i++) {
15533                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15534                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15535                        if (mi == null) {
15536                            mi = new Debug.MemoryInfo();
15537                        }
15538                        if (!brief && !oomOnly) {
15539                            Debug.getMemoryInfo(st.pid, mi);
15540                        } else {
15541                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15542                            mi.nativePrivateDirty = (int)tmpLong[0];
15543                        }
15544
15545                        final long myTotalPss = mi.getTotalPss();
15546                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15547                        totalPss += myTotalPss;
15548                        nativeProcTotalPss += myTotalPss;
15549
15550                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15551                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15552                        procMems.add(pssItem);
15553
15554                        nativePss += mi.nativePss;
15555                        nativeSwapPss += mi.nativeSwappedOutPss;
15556                        dalvikPss += mi.dalvikPss;
15557                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15558                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15559                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15560                            dalvikSubitemSwapPss[j] +=
15561                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15562                        }
15563                        otherPss += mi.otherPss;
15564                        otherSwapPss += mi.otherSwappedOutPss;
15565                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15566                            long mem = mi.getOtherPss(j);
15567                            miscPss[j] += mem;
15568                            otherPss -= mem;
15569                            mem = mi.getOtherSwappedOutPss(j);
15570                            miscSwapPss[j] += mem;
15571                            otherSwapPss -= mem;
15572                        }
15573                        oomPss[0] += myTotalPss;
15574                        oomSwapPss[0] += myTotalSwapPss;
15575                        if (oomProcs[0] == null) {
15576                            oomProcs[0] = new ArrayList<MemItem>();
15577                        }
15578                        oomProcs[0].add(pssItem);
15579                    }
15580                }
15581            }
15582
15583            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15584
15585            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15586            final MemItem dalvikItem =
15587                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15588            if (dalvikSubitemPss.length > 0) {
15589                dalvikItem.subitems = new ArrayList<MemItem>();
15590                for (int j=0; j<dalvikSubitemPss.length; j++) {
15591                    final String name = Debug.MemoryInfo.getOtherLabel(
15592                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15593                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15594                                    dalvikSubitemSwapPss[j], j));
15595                }
15596            }
15597            catMems.add(dalvikItem);
15598            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15599            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15600                String label = Debug.MemoryInfo.getOtherLabel(j);
15601                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15602            }
15603
15604            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15605            for (int j=0; j<oomPss.length; j++) {
15606                if (oomPss[j] != 0) {
15607                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15608                            : DUMP_MEM_OOM_LABEL[j];
15609                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15610                            DUMP_MEM_OOM_ADJ[j]);
15611                    item.subitems = oomProcs[j];
15612                    oomMems.add(item);
15613                }
15614            }
15615
15616            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15617            if (!brief && !oomOnly && !isCompact) {
15618                pw.println();
15619                pw.println("Total PSS by process:");
15620                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15621                pw.println();
15622            }
15623            if (!isCompact) {
15624                pw.println("Total PSS by OOM adjustment:");
15625            }
15626            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15627            if (!brief && !oomOnly) {
15628                PrintWriter out = categoryPw != null ? categoryPw : pw;
15629                if (!isCompact) {
15630                    out.println();
15631                    out.println("Total PSS by category:");
15632                }
15633                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15634            }
15635            if (!isCompact) {
15636                pw.println();
15637            }
15638            MemInfoReader memInfo = new MemInfoReader();
15639            memInfo.readMemInfo();
15640            if (nativeProcTotalPss > 0) {
15641                synchronized (this) {
15642                    final long cachedKb = memInfo.getCachedSizeKb();
15643                    final long freeKb = memInfo.getFreeSizeKb();
15644                    final long zramKb = memInfo.getZramTotalSizeKb();
15645                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15646                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15647                            kernelKb*1024, nativeProcTotalPss*1024);
15648                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15649                            nativeProcTotalPss);
15650                }
15651            }
15652            if (!brief) {
15653                if (!isCompact) {
15654                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15655                    pw.print(" (status ");
15656                    switch (mLastMemoryLevel) {
15657                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15658                            pw.println("normal)");
15659                            break;
15660                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15661                            pw.println("moderate)");
15662                            break;
15663                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15664                            pw.println("low)");
15665                            break;
15666                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15667                            pw.println("critical)");
15668                            break;
15669                        default:
15670                            pw.print(mLastMemoryLevel);
15671                            pw.println(")");
15672                            break;
15673                    }
15674                    pw.print(" Free RAM: ");
15675                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15676                            + memInfo.getFreeSizeKb()));
15677                    pw.print(" (");
15678                    pw.print(stringifyKBSize(cachedPss));
15679                    pw.print(" cached pss + ");
15680                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15681                    pw.print(" cached kernel + ");
15682                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15683                    pw.println(" free)");
15684                } else {
15685                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15686                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15687                            + memInfo.getFreeSizeKb()); pw.print(",");
15688                    pw.println(totalPss - cachedPss);
15689                }
15690            }
15691            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15692                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15693                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15694            if (!isCompact) {
15695                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15696                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15697                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15698                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15699                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15700            } else {
15701                pw.print("lostram,"); pw.println(lostRAM);
15702            }
15703            if (!brief) {
15704                if (memInfo.getZramTotalSizeKb() != 0) {
15705                    if (!isCompact) {
15706                        pw.print("     ZRAM: ");
15707                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15708                                pw.print(" physical used for ");
15709                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15710                                        - memInfo.getSwapFreeSizeKb()));
15711                                pw.print(" in swap (");
15712                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15713                                pw.println(" total swap)");
15714                    } else {
15715                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15716                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15717                                pw.println(memInfo.getSwapFreeSizeKb());
15718                    }
15719                }
15720                final long[] ksm = getKsmInfo();
15721                if (!isCompact) {
15722                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15723                            || ksm[KSM_VOLATILE] != 0) {
15724                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15725                                pw.print(" saved from shared ");
15726                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15727                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15728                                pw.print(" unshared; ");
15729                                pw.print(stringifyKBSize(
15730                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15731                    }
15732                    pw.print("   Tuning: ");
15733                    pw.print(ActivityManager.staticGetMemoryClass());
15734                    pw.print(" (large ");
15735                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15736                    pw.print("), oom ");
15737                    pw.print(stringifySize(
15738                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15739                    pw.print(", restore limit ");
15740                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15741                    if (ActivityManager.isLowRamDeviceStatic()) {
15742                        pw.print(" (low-ram)");
15743                    }
15744                    if (ActivityManager.isHighEndGfx()) {
15745                        pw.print(" (high-end-gfx)");
15746                    }
15747                    pw.println();
15748                } else {
15749                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15750                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15751                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15752                    pw.print("tuning,");
15753                    pw.print(ActivityManager.staticGetMemoryClass());
15754                    pw.print(',');
15755                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15756                    pw.print(',');
15757                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15758                    if (ActivityManager.isLowRamDeviceStatic()) {
15759                        pw.print(",low-ram");
15760                    }
15761                    if (ActivityManager.isHighEndGfx()) {
15762                        pw.print(",high-end-gfx");
15763                    }
15764                    pw.println();
15765                }
15766            }
15767        }
15768    }
15769
15770    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15771            long memtrack, String name) {
15772        sb.append("  ");
15773        sb.append(ProcessList.makeOomAdjString(oomAdj));
15774        sb.append(' ');
15775        sb.append(ProcessList.makeProcStateString(procState));
15776        sb.append(' ');
15777        ProcessList.appendRamKb(sb, pss);
15778        sb.append(": ");
15779        sb.append(name);
15780        if (memtrack > 0) {
15781            sb.append(" (");
15782            sb.append(stringifyKBSize(memtrack));
15783            sb.append(" memtrack)");
15784        }
15785    }
15786
15787    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15788        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15789        sb.append(" (pid ");
15790        sb.append(mi.pid);
15791        sb.append(") ");
15792        sb.append(mi.adjType);
15793        sb.append('\n');
15794        if (mi.adjReason != null) {
15795            sb.append("                      ");
15796            sb.append(mi.adjReason);
15797            sb.append('\n');
15798        }
15799    }
15800
15801    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15802        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15803        for (int i=0, N=memInfos.size(); i<N; i++) {
15804            ProcessMemInfo mi = memInfos.get(i);
15805            infoMap.put(mi.pid, mi);
15806        }
15807        updateCpuStatsNow();
15808        long[] memtrackTmp = new long[1];
15809        synchronized (mProcessCpuTracker) {
15810            final int N = mProcessCpuTracker.countStats();
15811            for (int i=0; i<N; i++) {
15812                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15813                if (st.vsize > 0) {
15814                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15815                    if (pss > 0) {
15816                        if (infoMap.indexOfKey(st.pid) < 0) {
15817                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15818                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15819                            mi.pss = pss;
15820                            mi.memtrack = memtrackTmp[0];
15821                            memInfos.add(mi);
15822                        }
15823                    }
15824                }
15825            }
15826        }
15827
15828        long totalPss = 0;
15829        long totalMemtrack = 0;
15830        for (int i=0, N=memInfos.size(); i<N; i++) {
15831            ProcessMemInfo mi = memInfos.get(i);
15832            if (mi.pss == 0) {
15833                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15834                mi.memtrack = memtrackTmp[0];
15835            }
15836            totalPss += mi.pss;
15837            totalMemtrack += mi.memtrack;
15838        }
15839        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15840            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15841                if (lhs.oomAdj != rhs.oomAdj) {
15842                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15843                }
15844                if (lhs.pss != rhs.pss) {
15845                    return lhs.pss < rhs.pss ? 1 : -1;
15846                }
15847                return 0;
15848            }
15849        });
15850
15851        StringBuilder tag = new StringBuilder(128);
15852        StringBuilder stack = new StringBuilder(128);
15853        tag.append("Low on memory -- ");
15854        appendMemBucket(tag, totalPss, "total", false);
15855        appendMemBucket(stack, totalPss, "total", true);
15856
15857        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15858        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15859        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15860
15861        boolean firstLine = true;
15862        int lastOomAdj = Integer.MIN_VALUE;
15863        long extraNativeRam = 0;
15864        long extraNativeMemtrack = 0;
15865        long cachedPss = 0;
15866        for (int i=0, N=memInfos.size(); i<N; i++) {
15867            ProcessMemInfo mi = memInfos.get(i);
15868
15869            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15870                cachedPss += mi.pss;
15871            }
15872
15873            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15874                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15875                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15876                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15877                if (lastOomAdj != mi.oomAdj) {
15878                    lastOomAdj = mi.oomAdj;
15879                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15880                        tag.append(" / ");
15881                    }
15882                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15883                        if (firstLine) {
15884                            stack.append(":");
15885                            firstLine = false;
15886                        }
15887                        stack.append("\n\t at ");
15888                    } else {
15889                        stack.append("$");
15890                    }
15891                } else {
15892                    tag.append(" ");
15893                    stack.append("$");
15894                }
15895                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15896                    appendMemBucket(tag, mi.pss, mi.name, false);
15897                }
15898                appendMemBucket(stack, mi.pss, mi.name, true);
15899                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15900                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15901                    stack.append("(");
15902                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15903                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15904                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15905                            stack.append(":");
15906                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15907                        }
15908                    }
15909                    stack.append(")");
15910                }
15911            }
15912
15913            appendMemInfo(fullNativeBuilder, mi);
15914            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15915                // The short form only has native processes that are >= 512K.
15916                if (mi.pss >= 512) {
15917                    appendMemInfo(shortNativeBuilder, mi);
15918                } else {
15919                    extraNativeRam += mi.pss;
15920                    extraNativeMemtrack += mi.memtrack;
15921                }
15922            } else {
15923                // Short form has all other details, but if we have collected RAM
15924                // from smaller native processes let's dump a summary of that.
15925                if (extraNativeRam > 0) {
15926                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15927                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15928                    shortNativeBuilder.append('\n');
15929                    extraNativeRam = 0;
15930                }
15931                appendMemInfo(fullJavaBuilder, mi);
15932            }
15933        }
15934
15935        fullJavaBuilder.append("           ");
15936        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15937        fullJavaBuilder.append(": TOTAL");
15938        if (totalMemtrack > 0) {
15939            fullJavaBuilder.append(" (");
15940            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15941            fullJavaBuilder.append(" memtrack)");
15942        } else {
15943        }
15944        fullJavaBuilder.append("\n");
15945
15946        MemInfoReader memInfo = new MemInfoReader();
15947        memInfo.readMemInfo();
15948        final long[] infos = memInfo.getRawInfo();
15949
15950        StringBuilder memInfoBuilder = new StringBuilder(1024);
15951        Debug.getMemInfo(infos);
15952        memInfoBuilder.append("  MemInfo: ");
15953        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15954        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15955        memInfoBuilder.append(stringifyKBSize(
15956                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15957        memInfoBuilder.append(stringifyKBSize(
15958                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15959        memInfoBuilder.append(stringifyKBSize(
15960                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15961        memInfoBuilder.append("           ");
15962        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15963        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15964        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15965        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15966        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15967            memInfoBuilder.append("  ZRAM: ");
15968            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15969            memInfoBuilder.append(" RAM, ");
15970            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15971            memInfoBuilder.append(" swap total, ");
15972            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15973            memInfoBuilder.append(" swap free\n");
15974        }
15975        final long[] ksm = getKsmInfo();
15976        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15977                || ksm[KSM_VOLATILE] != 0) {
15978            memInfoBuilder.append("  KSM: ");
15979            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15980            memInfoBuilder.append(" saved from shared ");
15981            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15982            memInfoBuilder.append("\n       ");
15983            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15984            memInfoBuilder.append(" unshared; ");
15985            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15986            memInfoBuilder.append(" volatile\n");
15987        }
15988        memInfoBuilder.append("  Free RAM: ");
15989        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15990                + memInfo.getFreeSizeKb()));
15991        memInfoBuilder.append("\n");
15992        memInfoBuilder.append("  Used RAM: ");
15993        memInfoBuilder.append(stringifyKBSize(
15994                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15995        memInfoBuilder.append("\n");
15996        memInfoBuilder.append("  Lost RAM: ");
15997        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15998                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15999                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16000        memInfoBuilder.append("\n");
16001        Slog.i(TAG, "Low on memory:");
16002        Slog.i(TAG, shortNativeBuilder.toString());
16003        Slog.i(TAG, fullJavaBuilder.toString());
16004        Slog.i(TAG, memInfoBuilder.toString());
16005
16006        StringBuilder dropBuilder = new StringBuilder(1024);
16007        /*
16008        StringWriter oomSw = new StringWriter();
16009        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16010        StringWriter catSw = new StringWriter();
16011        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16012        String[] emptyArgs = new String[] { };
16013        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16014        oomPw.flush();
16015        String oomString = oomSw.toString();
16016        */
16017        dropBuilder.append("Low on memory:");
16018        dropBuilder.append(stack);
16019        dropBuilder.append('\n');
16020        dropBuilder.append(fullNativeBuilder);
16021        dropBuilder.append(fullJavaBuilder);
16022        dropBuilder.append('\n');
16023        dropBuilder.append(memInfoBuilder);
16024        dropBuilder.append('\n');
16025        /*
16026        dropBuilder.append(oomString);
16027        dropBuilder.append('\n');
16028        */
16029        StringWriter catSw = new StringWriter();
16030        synchronized (ActivityManagerService.this) {
16031            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16032            String[] emptyArgs = new String[] { };
16033            catPw.println();
16034            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16035            catPw.println();
16036            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16037                    false, false, null);
16038            catPw.println();
16039            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16040            catPw.flush();
16041        }
16042        dropBuilder.append(catSw.toString());
16043        addErrorToDropBox("lowmem", null, "system_server", null,
16044                null, tag.toString(), dropBuilder.toString(), null, null);
16045        //Slog.i(TAG, "Sent to dropbox:");
16046        //Slog.i(TAG, dropBuilder.toString());
16047        synchronized (ActivityManagerService.this) {
16048            long now = SystemClock.uptimeMillis();
16049            if (mLastMemUsageReportTime < now) {
16050                mLastMemUsageReportTime = now;
16051            }
16052        }
16053    }
16054
16055    /**
16056     * Searches array of arguments for the specified string
16057     * @param args array of argument strings
16058     * @param value value to search for
16059     * @return true if the value is contained in the array
16060     */
16061    private static boolean scanArgs(String[] args, String value) {
16062        if (args != null) {
16063            for (String arg : args) {
16064                if (value.equals(arg)) {
16065                    return true;
16066                }
16067            }
16068        }
16069        return false;
16070    }
16071
16072    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16073            ContentProviderRecord cpr, boolean always) {
16074        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16075
16076        if (!inLaunching || always) {
16077            synchronized (cpr) {
16078                cpr.launchingApp = null;
16079                cpr.notifyAll();
16080            }
16081            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16082            String names[] = cpr.info.authority.split(";");
16083            for (int j = 0; j < names.length; j++) {
16084                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16085            }
16086        }
16087
16088        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16089            ContentProviderConnection conn = cpr.connections.get(i);
16090            if (conn.waiting) {
16091                // If this connection is waiting for the provider, then we don't
16092                // need to mess with its process unless we are always removing
16093                // or for some reason the provider is not currently launching.
16094                if (inLaunching && !always) {
16095                    continue;
16096                }
16097            }
16098            ProcessRecord capp = conn.client;
16099            conn.dead = true;
16100            if (conn.stableCount > 0) {
16101                if (!capp.persistent && capp.thread != null
16102                        && capp.pid != 0
16103                        && capp.pid != MY_PID) {
16104                    capp.kill("depends on provider "
16105                            + cpr.name.flattenToShortString()
16106                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16107                }
16108            } else if (capp.thread != null && conn.provider.provider != null) {
16109                try {
16110                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16111                } catch (RemoteException e) {
16112                }
16113                // In the protocol here, we don't expect the client to correctly
16114                // clean up this connection, we'll just remove it.
16115                cpr.connections.remove(i);
16116                if (conn.client.conProviders.remove(conn)) {
16117                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16118                }
16119            }
16120        }
16121
16122        if (inLaunching && always) {
16123            mLaunchingProviders.remove(cpr);
16124        }
16125        return inLaunching;
16126    }
16127
16128    /**
16129     * Main code for cleaning up a process when it has gone away.  This is
16130     * called both as a result of the process dying, or directly when stopping
16131     * a process when running in single process mode.
16132     *
16133     * @return Returns true if the given process has been restarted, so the
16134     * app that was passed in must remain on the process lists.
16135     */
16136    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16137            boolean restarting, boolean allowRestart, int index) {
16138        if (index >= 0) {
16139            removeLruProcessLocked(app);
16140            ProcessList.remove(app.pid);
16141        }
16142
16143        mProcessesToGc.remove(app);
16144        mPendingPssProcesses.remove(app);
16145
16146        // Dismiss any open dialogs.
16147        if (app.crashDialog != null && !app.forceCrashReport) {
16148            app.crashDialog.dismiss();
16149            app.crashDialog = null;
16150        }
16151        if (app.anrDialog != null) {
16152            app.anrDialog.dismiss();
16153            app.anrDialog = null;
16154        }
16155        if (app.waitDialog != null) {
16156            app.waitDialog.dismiss();
16157            app.waitDialog = null;
16158        }
16159
16160        app.crashing = false;
16161        app.notResponding = false;
16162
16163        app.resetPackageList(mProcessStats);
16164        app.unlinkDeathRecipient();
16165        app.makeInactive(mProcessStats);
16166        app.waitingToKill = null;
16167        app.forcingToForeground = null;
16168        updateProcessForegroundLocked(app, false, false);
16169        app.foregroundActivities = false;
16170        app.hasShownUi = false;
16171        app.treatLikeActivity = false;
16172        app.hasAboveClient = false;
16173        app.hasClientActivities = false;
16174
16175        mServices.killServicesLocked(app, allowRestart);
16176
16177        boolean restart = false;
16178
16179        // Remove published content providers.
16180        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16181            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16182            final boolean always = app.bad || !allowRestart;
16183            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16184            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16185                // We left the provider in the launching list, need to
16186                // restart it.
16187                restart = true;
16188            }
16189
16190            cpr.provider = null;
16191            cpr.proc = null;
16192        }
16193        app.pubProviders.clear();
16194
16195        // Take care of any launching providers waiting for this process.
16196        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16197            restart = true;
16198        }
16199
16200        // Unregister from connected content providers.
16201        if (!app.conProviders.isEmpty()) {
16202            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16203                ContentProviderConnection conn = app.conProviders.get(i);
16204                conn.provider.connections.remove(conn);
16205                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16206                        conn.provider.name);
16207            }
16208            app.conProviders.clear();
16209        }
16210
16211        // At this point there may be remaining entries in mLaunchingProviders
16212        // where we were the only one waiting, so they are no longer of use.
16213        // Look for these and clean up if found.
16214        // XXX Commented out for now.  Trying to figure out a way to reproduce
16215        // the actual situation to identify what is actually going on.
16216        if (false) {
16217            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16218                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16219                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16220                    synchronized (cpr) {
16221                        cpr.launchingApp = null;
16222                        cpr.notifyAll();
16223                    }
16224                }
16225            }
16226        }
16227
16228        skipCurrentReceiverLocked(app);
16229
16230        // Unregister any receivers.
16231        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16232            removeReceiverLocked(app.receivers.valueAt(i));
16233        }
16234        app.receivers.clear();
16235
16236        // If the app is undergoing backup, tell the backup manager about it
16237        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16238            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16239                    + mBackupTarget.appInfo + " died during backup");
16240            try {
16241                IBackupManager bm = IBackupManager.Stub.asInterface(
16242                        ServiceManager.getService(Context.BACKUP_SERVICE));
16243                bm.agentDisconnected(app.info.packageName);
16244            } catch (RemoteException e) {
16245                // can't happen; backup manager is local
16246            }
16247        }
16248
16249        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16250            ProcessChangeItem item = mPendingProcessChanges.get(i);
16251            if (item.pid == app.pid) {
16252                mPendingProcessChanges.remove(i);
16253                mAvailProcessChanges.add(item);
16254            }
16255        }
16256        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16257                null).sendToTarget();
16258
16259        // If the caller is restarting this app, then leave it in its
16260        // current lists and let the caller take care of it.
16261        if (restarting) {
16262            return false;
16263        }
16264
16265        if (!app.persistent || app.isolated) {
16266            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16267                    "Removing non-persistent process during cleanup: " + app);
16268            removeProcessNameLocked(app.processName, app.uid);
16269            if (mHeavyWeightProcess == app) {
16270                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16271                        mHeavyWeightProcess.userId, 0));
16272                mHeavyWeightProcess = null;
16273            }
16274        } else if (!app.removed) {
16275            // This app is persistent, so we need to keep its record around.
16276            // If it is not already on the pending app list, add it there
16277            // and start a new process for it.
16278            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16279                mPersistentStartingProcesses.add(app);
16280                restart = true;
16281            }
16282        }
16283        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16284                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16285        mProcessesOnHold.remove(app);
16286
16287        if (app == mHomeProcess) {
16288            mHomeProcess = null;
16289        }
16290        if (app == mPreviousProcess) {
16291            mPreviousProcess = null;
16292        }
16293
16294        if (restart && !app.isolated) {
16295            // We have components that still need to be running in the
16296            // process, so re-launch it.
16297            if (index < 0) {
16298                ProcessList.remove(app.pid);
16299            }
16300            addProcessNameLocked(app);
16301            startProcessLocked(app, "restart", app.processName);
16302            return true;
16303        } else if (app.pid > 0 && app.pid != MY_PID) {
16304            // Goodbye!
16305            boolean removed;
16306            synchronized (mPidsSelfLocked) {
16307                mPidsSelfLocked.remove(app.pid);
16308                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16309            }
16310            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16311            if (app.isolated) {
16312                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16313            }
16314            app.setPid(0);
16315        }
16316        return false;
16317    }
16318
16319    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16320        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16321            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16322            if (cpr.launchingApp == app) {
16323                return true;
16324            }
16325        }
16326        return false;
16327    }
16328
16329    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16330        // Look through the content providers we are waiting to have launched,
16331        // and if any run in this process then either schedule a restart of
16332        // the process or kill the client waiting for it if this process has
16333        // gone bad.
16334        boolean restart = false;
16335        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16336            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16337            if (cpr.launchingApp == app) {
16338                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16339                    restart = true;
16340                } else {
16341                    removeDyingProviderLocked(app, cpr, true);
16342                }
16343            }
16344        }
16345        return restart;
16346    }
16347
16348    // =========================================================
16349    // SERVICES
16350    // =========================================================
16351
16352    @Override
16353    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16354            int flags) {
16355        enforceNotIsolatedCaller("getServices");
16356        synchronized (this) {
16357            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16358        }
16359    }
16360
16361    @Override
16362    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16363        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16364        synchronized (this) {
16365            return mServices.getRunningServiceControlPanelLocked(name);
16366        }
16367    }
16368
16369    @Override
16370    public ComponentName startService(IApplicationThread caller, Intent service,
16371            String resolvedType, String callingPackage, int userId)
16372            throws TransactionTooLargeException {
16373        enforceNotIsolatedCaller("startService");
16374        // Refuse possible leaked file descriptors
16375        if (service != null && service.hasFileDescriptors() == true) {
16376            throw new IllegalArgumentException("File descriptors passed in Intent");
16377        }
16378
16379        if (callingPackage == null) {
16380            throw new IllegalArgumentException("callingPackage cannot be null");
16381        }
16382
16383        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16384                "startService: " + service + " type=" + resolvedType);
16385        synchronized(this) {
16386            final int callingPid = Binder.getCallingPid();
16387            final int callingUid = Binder.getCallingUid();
16388            final long origId = Binder.clearCallingIdentity();
16389            ComponentName res = mServices.startServiceLocked(caller, service,
16390                    resolvedType, callingPid, callingUid, callingPackage, userId);
16391            Binder.restoreCallingIdentity(origId);
16392            return res;
16393        }
16394    }
16395
16396    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16397            String callingPackage, int userId)
16398            throws TransactionTooLargeException {
16399        synchronized(this) {
16400            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16401                    "startServiceInPackage: " + service + " type=" + resolvedType);
16402            final long origId = Binder.clearCallingIdentity();
16403            ComponentName res = mServices.startServiceLocked(null, service,
16404                    resolvedType, -1, uid, callingPackage, userId);
16405            Binder.restoreCallingIdentity(origId);
16406            return res;
16407        }
16408    }
16409
16410    @Override
16411    public int stopService(IApplicationThread caller, Intent service,
16412            String resolvedType, int userId) {
16413        enforceNotIsolatedCaller("stopService");
16414        // Refuse possible leaked file descriptors
16415        if (service != null && service.hasFileDescriptors() == true) {
16416            throw new IllegalArgumentException("File descriptors passed in Intent");
16417        }
16418
16419        synchronized(this) {
16420            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16421        }
16422    }
16423
16424    @Override
16425    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16426        enforceNotIsolatedCaller("peekService");
16427        // Refuse possible leaked file descriptors
16428        if (service != null && service.hasFileDescriptors() == true) {
16429            throw new IllegalArgumentException("File descriptors passed in Intent");
16430        }
16431
16432        if (callingPackage == null) {
16433            throw new IllegalArgumentException("callingPackage cannot be null");
16434        }
16435
16436        synchronized(this) {
16437            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16438        }
16439    }
16440
16441    @Override
16442    public boolean stopServiceToken(ComponentName className, IBinder token,
16443            int startId) {
16444        synchronized(this) {
16445            return mServices.stopServiceTokenLocked(className, token, startId);
16446        }
16447    }
16448
16449    @Override
16450    public void setServiceForeground(ComponentName className, IBinder token,
16451            int id, Notification notification, boolean removeNotification) {
16452        synchronized(this) {
16453            mServices.setServiceForegroundLocked(className, token, id, notification,
16454                    removeNotification);
16455        }
16456    }
16457
16458    @Override
16459    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16460            boolean requireFull, String name, String callerPackage) {
16461        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16462                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16463    }
16464
16465    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16466            String className, int flags) {
16467        boolean result = false;
16468        // For apps that don't have pre-defined UIDs, check for permission
16469        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16470            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16471                if (ActivityManager.checkUidPermission(
16472                        INTERACT_ACROSS_USERS,
16473                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16474                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16475                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16476                            + " requests FLAG_SINGLE_USER, but app does not hold "
16477                            + INTERACT_ACROSS_USERS;
16478                    Slog.w(TAG, msg);
16479                    throw new SecurityException(msg);
16480                }
16481                // Permission passed
16482                result = true;
16483            }
16484        } else if ("system".equals(componentProcessName)) {
16485            result = true;
16486        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16487            // Phone app and persistent apps are allowed to export singleuser providers.
16488            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16489                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16490        }
16491        if (DEBUG_MU) Slog.v(TAG_MU,
16492                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16493                + Integer.toHexString(flags) + ") = " + result);
16494        return result;
16495    }
16496
16497    /**
16498     * Checks to see if the caller is in the same app as the singleton
16499     * component, or the component is in a special app. It allows special apps
16500     * to export singleton components but prevents exporting singleton
16501     * components for regular apps.
16502     */
16503    boolean isValidSingletonCall(int callingUid, int componentUid) {
16504        int componentAppId = UserHandle.getAppId(componentUid);
16505        return UserHandle.isSameApp(callingUid, componentUid)
16506                || componentAppId == Process.SYSTEM_UID
16507                || componentAppId == Process.PHONE_UID
16508                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16509                        == PackageManager.PERMISSION_GRANTED;
16510    }
16511
16512    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16513            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16514            int userId) throws TransactionTooLargeException {
16515        enforceNotIsolatedCaller("bindService");
16516
16517        // Refuse possible leaked file descriptors
16518        if (service != null && service.hasFileDescriptors() == true) {
16519            throw new IllegalArgumentException("File descriptors passed in Intent");
16520        }
16521
16522        if (callingPackage == null) {
16523            throw new IllegalArgumentException("callingPackage cannot be null");
16524        }
16525
16526        synchronized(this) {
16527            return mServices.bindServiceLocked(caller, token, service,
16528                    resolvedType, connection, flags, callingPackage, userId);
16529        }
16530    }
16531
16532    public boolean unbindService(IServiceConnection connection) {
16533        synchronized (this) {
16534            return mServices.unbindServiceLocked(connection);
16535        }
16536    }
16537
16538    public void publishService(IBinder token, Intent intent, IBinder service) {
16539        // Refuse possible leaked file descriptors
16540        if (intent != null && intent.hasFileDescriptors() == true) {
16541            throw new IllegalArgumentException("File descriptors passed in Intent");
16542        }
16543
16544        synchronized(this) {
16545            if (!(token instanceof ServiceRecord)) {
16546                throw new IllegalArgumentException("Invalid service token");
16547            }
16548            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16549        }
16550    }
16551
16552    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16553        // Refuse possible leaked file descriptors
16554        if (intent != null && intent.hasFileDescriptors() == true) {
16555            throw new IllegalArgumentException("File descriptors passed in Intent");
16556        }
16557
16558        synchronized(this) {
16559            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16560        }
16561    }
16562
16563    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16564        synchronized(this) {
16565            if (!(token instanceof ServiceRecord)) {
16566                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16567                throw new IllegalArgumentException("Invalid service token");
16568            }
16569            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16570        }
16571    }
16572
16573    // =========================================================
16574    // BACKUP AND RESTORE
16575    // =========================================================
16576
16577    // Cause the target app to be launched if necessary and its backup agent
16578    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16579    // activity manager to announce its creation.
16580    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16581        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16582                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16583        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16584
16585        synchronized(this) {
16586            // !!! TODO: currently no check here that we're already bound
16587            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16588            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16589            synchronized (stats) {
16590                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16591            }
16592
16593            // Backup agent is now in use, its package can't be stopped.
16594            try {
16595                AppGlobals.getPackageManager().setPackageStoppedState(
16596                        app.packageName, false, UserHandle.getUserId(app.uid));
16597            } catch (RemoteException e) {
16598            } catch (IllegalArgumentException e) {
16599                Slog.w(TAG, "Failed trying to unstop package "
16600                        + app.packageName + ": " + e);
16601            }
16602
16603            BackupRecord r = new BackupRecord(ss, app, backupMode);
16604            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16605                    ? new ComponentName(app.packageName, app.backupAgentName)
16606                    : new ComponentName("android", "FullBackupAgent");
16607            // startProcessLocked() returns existing proc's record if it's already running
16608            ProcessRecord proc = startProcessLocked(app.processName, app,
16609                    false, 0, "backup", hostingName, false, false, false);
16610            if (proc == null) {
16611                Slog.e(TAG, "Unable to start backup agent process " + r);
16612                return false;
16613            }
16614
16615            r.app = proc;
16616            mBackupTarget = r;
16617            mBackupAppName = app.packageName;
16618
16619            // Try not to kill the process during backup
16620            updateOomAdjLocked(proc);
16621
16622            // If the process is already attached, schedule the creation of the backup agent now.
16623            // If it is not yet live, this will be done when it attaches to the framework.
16624            if (proc.thread != null) {
16625                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16626                try {
16627                    proc.thread.scheduleCreateBackupAgent(app,
16628                            compatibilityInfoForPackageLocked(app), backupMode);
16629                } catch (RemoteException e) {
16630                    // Will time out on the backup manager side
16631                }
16632            } else {
16633                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16634            }
16635            // Invariants: at this point, the target app process exists and the application
16636            // is either already running or in the process of coming up.  mBackupTarget and
16637            // mBackupAppName describe the app, so that when it binds back to the AM we
16638            // know that it's scheduled for a backup-agent operation.
16639        }
16640
16641        return true;
16642    }
16643
16644    @Override
16645    public void clearPendingBackup() {
16646        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16647        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16648
16649        synchronized (this) {
16650            mBackupTarget = null;
16651            mBackupAppName = null;
16652        }
16653    }
16654
16655    // A backup agent has just come up
16656    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16657        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16658                + " = " + agent);
16659
16660        synchronized(this) {
16661            if (!agentPackageName.equals(mBackupAppName)) {
16662                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16663                return;
16664            }
16665        }
16666
16667        long oldIdent = Binder.clearCallingIdentity();
16668        try {
16669            IBackupManager bm = IBackupManager.Stub.asInterface(
16670                    ServiceManager.getService(Context.BACKUP_SERVICE));
16671            bm.agentConnected(agentPackageName, agent);
16672        } catch (RemoteException e) {
16673            // can't happen; the backup manager service is local
16674        } catch (Exception e) {
16675            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16676            e.printStackTrace();
16677        } finally {
16678            Binder.restoreCallingIdentity(oldIdent);
16679        }
16680    }
16681
16682    // done with this agent
16683    public void unbindBackupAgent(ApplicationInfo appInfo) {
16684        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16685        if (appInfo == null) {
16686            Slog.w(TAG, "unbind backup agent for null app");
16687            return;
16688        }
16689
16690        synchronized(this) {
16691            try {
16692                if (mBackupAppName == null) {
16693                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16694                    return;
16695                }
16696
16697                if (!mBackupAppName.equals(appInfo.packageName)) {
16698                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16699                    return;
16700                }
16701
16702                // Not backing this app up any more; reset its OOM adjustment
16703                final ProcessRecord proc = mBackupTarget.app;
16704                updateOomAdjLocked(proc);
16705
16706                // If the app crashed during backup, 'thread' will be null here
16707                if (proc.thread != null) {
16708                    try {
16709                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16710                                compatibilityInfoForPackageLocked(appInfo));
16711                    } catch (Exception e) {
16712                        Slog.e(TAG, "Exception when unbinding backup agent:");
16713                        e.printStackTrace();
16714                    }
16715                }
16716            } finally {
16717                mBackupTarget = null;
16718                mBackupAppName = null;
16719            }
16720        }
16721    }
16722    // =========================================================
16723    // BROADCASTS
16724    // =========================================================
16725
16726    boolean isPendingBroadcastProcessLocked(int pid) {
16727        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16728                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16729    }
16730
16731    void skipPendingBroadcastLocked(int pid) {
16732            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16733            for (BroadcastQueue queue : mBroadcastQueues) {
16734                queue.skipPendingBroadcastLocked(pid);
16735            }
16736    }
16737
16738    // The app just attached; send any pending broadcasts that it should receive
16739    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16740        boolean didSomething = false;
16741        for (BroadcastQueue queue : mBroadcastQueues) {
16742            didSomething |= queue.sendPendingBroadcastsLocked(app);
16743        }
16744        return didSomething;
16745    }
16746
16747    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16748            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16749        enforceNotIsolatedCaller("registerReceiver");
16750        ArrayList<Intent> stickyIntents = null;
16751        ProcessRecord callerApp = null;
16752        int callingUid;
16753        int callingPid;
16754        synchronized(this) {
16755            if (caller != null) {
16756                callerApp = getRecordForAppLocked(caller);
16757                if (callerApp == null) {
16758                    throw new SecurityException(
16759                            "Unable to find app for caller " + caller
16760                            + " (pid=" + Binder.getCallingPid()
16761                            + ") when registering receiver " + receiver);
16762                }
16763                if (callerApp.info.uid != Process.SYSTEM_UID &&
16764                        !callerApp.pkgList.containsKey(callerPackage) &&
16765                        !"android".equals(callerPackage)) {
16766                    throw new SecurityException("Given caller package " + callerPackage
16767                            + " is not running in process " + callerApp);
16768                }
16769                callingUid = callerApp.info.uid;
16770                callingPid = callerApp.pid;
16771            } else {
16772                callerPackage = null;
16773                callingUid = Binder.getCallingUid();
16774                callingPid = Binder.getCallingPid();
16775            }
16776
16777            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16778                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16779
16780            Iterator<String> actions = filter.actionsIterator();
16781            if (actions == null) {
16782                ArrayList<String> noAction = new ArrayList<String>(1);
16783                noAction.add(null);
16784                actions = noAction.iterator();
16785            }
16786
16787            // Collect stickies of users
16788            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16789            while (actions.hasNext()) {
16790                String action = actions.next();
16791                for (int id : userIds) {
16792                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16793                    if (stickies != null) {
16794                        ArrayList<Intent> intents = stickies.get(action);
16795                        if (intents != null) {
16796                            if (stickyIntents == null) {
16797                                stickyIntents = new ArrayList<Intent>();
16798                            }
16799                            stickyIntents.addAll(intents);
16800                        }
16801                    }
16802                }
16803            }
16804        }
16805
16806        ArrayList<Intent> allSticky = null;
16807        if (stickyIntents != null) {
16808            final ContentResolver resolver = mContext.getContentResolver();
16809            // Look for any matching sticky broadcasts...
16810            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16811                Intent intent = stickyIntents.get(i);
16812                // If intent has scheme "content", it will need to acccess
16813                // provider that needs to lock mProviderMap in ActivityThread
16814                // and also it may need to wait application response, so we
16815                // cannot lock ActivityManagerService here.
16816                if (filter.match(resolver, intent, true, TAG) >= 0) {
16817                    if (allSticky == null) {
16818                        allSticky = new ArrayList<Intent>();
16819                    }
16820                    allSticky.add(intent);
16821                }
16822            }
16823        }
16824
16825        // The first sticky in the list is returned directly back to the client.
16826        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16827        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16828        if (receiver == null) {
16829            return sticky;
16830        }
16831
16832        synchronized (this) {
16833            if (callerApp != null && (callerApp.thread == null
16834                    || callerApp.thread.asBinder() != caller.asBinder())) {
16835                // Original caller already died
16836                return null;
16837            }
16838            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16839            if (rl == null) {
16840                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16841                        userId, receiver);
16842                if (rl.app != null) {
16843                    rl.app.receivers.add(rl);
16844                } else {
16845                    try {
16846                        receiver.asBinder().linkToDeath(rl, 0);
16847                    } catch (RemoteException e) {
16848                        return sticky;
16849                    }
16850                    rl.linkedToDeath = true;
16851                }
16852                mRegisteredReceivers.put(receiver.asBinder(), rl);
16853            } else if (rl.uid != callingUid) {
16854                throw new IllegalArgumentException(
16855                        "Receiver requested to register for uid " + callingUid
16856                        + " was previously registered for uid " + rl.uid);
16857            } else if (rl.pid != callingPid) {
16858                throw new IllegalArgumentException(
16859                        "Receiver requested to register for pid " + callingPid
16860                        + " was previously registered for pid " + rl.pid);
16861            } else if (rl.userId != userId) {
16862                throw new IllegalArgumentException(
16863                        "Receiver requested to register for user " + userId
16864                        + " was previously registered for user " + rl.userId);
16865            }
16866            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16867                    permission, callingUid, userId);
16868            rl.add(bf);
16869            if (!bf.debugCheck()) {
16870                Slog.w(TAG, "==> For Dynamic broadcast");
16871            }
16872            mReceiverResolver.addFilter(bf);
16873
16874            // Enqueue broadcasts for all existing stickies that match
16875            // this filter.
16876            if (allSticky != null) {
16877                ArrayList receivers = new ArrayList();
16878                receivers.add(bf);
16879
16880                final int stickyCount = allSticky.size();
16881                for (int i = 0; i < stickyCount; i++) {
16882                    Intent intent = allSticky.get(i);
16883                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16884                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16885                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16886                            null, 0, null, null, false, true, true, -1);
16887                    queue.enqueueParallelBroadcastLocked(r);
16888                    queue.scheduleBroadcastsLocked();
16889                }
16890            }
16891
16892            return sticky;
16893        }
16894    }
16895
16896    public void unregisterReceiver(IIntentReceiver receiver) {
16897        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16898
16899        final long origId = Binder.clearCallingIdentity();
16900        try {
16901            boolean doTrim = false;
16902
16903            synchronized(this) {
16904                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16905                if (rl != null) {
16906                    final BroadcastRecord r = rl.curBroadcast;
16907                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16908                        final boolean doNext = r.queue.finishReceiverLocked(
16909                                r, r.resultCode, r.resultData, r.resultExtras,
16910                                r.resultAbort, false);
16911                        if (doNext) {
16912                            doTrim = true;
16913                            r.queue.processNextBroadcast(false);
16914                        }
16915                    }
16916
16917                    if (rl.app != null) {
16918                        rl.app.receivers.remove(rl);
16919                    }
16920                    removeReceiverLocked(rl);
16921                    if (rl.linkedToDeath) {
16922                        rl.linkedToDeath = false;
16923                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16924                    }
16925                }
16926            }
16927
16928            // If we actually concluded any broadcasts, we might now be able
16929            // to trim the recipients' apps from our working set
16930            if (doTrim) {
16931                trimApplications();
16932                return;
16933            }
16934
16935        } finally {
16936            Binder.restoreCallingIdentity(origId);
16937        }
16938    }
16939
16940    void removeReceiverLocked(ReceiverList rl) {
16941        mRegisteredReceivers.remove(rl.receiver.asBinder());
16942        for (int i = rl.size() - 1; i >= 0; i--) {
16943            mReceiverResolver.removeFilter(rl.get(i));
16944        }
16945    }
16946
16947    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16948        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16949            ProcessRecord r = mLruProcesses.get(i);
16950            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16951                try {
16952                    r.thread.dispatchPackageBroadcast(cmd, packages);
16953                } catch (RemoteException ex) {
16954                }
16955            }
16956        }
16957    }
16958
16959    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16960            int callingUid, int[] users) {
16961        // TODO: come back and remove this assumption to triage all broadcasts
16962        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16963
16964        List<ResolveInfo> receivers = null;
16965        try {
16966            HashSet<ComponentName> singleUserReceivers = null;
16967            boolean scannedFirstReceivers = false;
16968            for (int user : users) {
16969                // Skip users that have Shell restrictions, with exception of always permitted
16970                // Shell broadcasts
16971                if (callingUid == Process.SHELL_UID
16972                        && mUserController.hasUserRestriction(
16973                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
16974                        && !isPermittedShellBroadcast(intent)) {
16975                    continue;
16976                }
16977                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16978                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
16979                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16980                    // If this is not the system user, we need to check for
16981                    // any receivers that should be filtered out.
16982                    for (int i=0; i<newReceivers.size(); i++) {
16983                        ResolveInfo ri = newReceivers.get(i);
16984                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16985                            newReceivers.remove(i);
16986                            i--;
16987                        }
16988                    }
16989                }
16990                if (newReceivers != null && newReceivers.size() == 0) {
16991                    newReceivers = null;
16992                }
16993                if (receivers == null) {
16994                    receivers = newReceivers;
16995                } else if (newReceivers != null) {
16996                    // We need to concatenate the additional receivers
16997                    // found with what we have do far.  This would be easy,
16998                    // but we also need to de-dup any receivers that are
16999                    // singleUser.
17000                    if (!scannedFirstReceivers) {
17001                        // Collect any single user receivers we had already retrieved.
17002                        scannedFirstReceivers = true;
17003                        for (int i=0; i<receivers.size(); i++) {
17004                            ResolveInfo ri = receivers.get(i);
17005                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17006                                ComponentName cn = new ComponentName(
17007                                        ri.activityInfo.packageName, ri.activityInfo.name);
17008                                if (singleUserReceivers == null) {
17009                                    singleUserReceivers = new HashSet<ComponentName>();
17010                                }
17011                                singleUserReceivers.add(cn);
17012                            }
17013                        }
17014                    }
17015                    // Add the new results to the existing results, tracking
17016                    // and de-dupping single user receivers.
17017                    for (int i=0; i<newReceivers.size(); i++) {
17018                        ResolveInfo ri = newReceivers.get(i);
17019                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17020                            ComponentName cn = new ComponentName(
17021                                    ri.activityInfo.packageName, ri.activityInfo.name);
17022                            if (singleUserReceivers == null) {
17023                                singleUserReceivers = new HashSet<ComponentName>();
17024                            }
17025                            if (!singleUserReceivers.contains(cn)) {
17026                                singleUserReceivers.add(cn);
17027                                receivers.add(ri);
17028                            }
17029                        } else {
17030                            receivers.add(ri);
17031                        }
17032                    }
17033                }
17034            }
17035        } catch (RemoteException ex) {
17036            // pm is in same process, this will never happen.
17037        }
17038        return receivers;
17039    }
17040
17041    private boolean isPermittedShellBroadcast(Intent intent) {
17042        // remote bugreport should always be allowed to be taken
17043        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17044    }
17045
17046    final int broadcastIntentLocked(ProcessRecord callerApp,
17047            String callerPackage, Intent intent, String resolvedType,
17048            IIntentReceiver resultTo, int resultCode, String resultData,
17049            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17050            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17051        intent = new Intent(intent);
17052
17053        // By default broadcasts do not go to stopped apps.
17054        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17055
17056        // If we have not finished booting, don't allow this to launch new processes.
17057        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17058            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17059        }
17060
17061        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17062                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17063                + " ordered=" + ordered + " userid=" + userId);
17064        if ((resultTo != null) && !ordered) {
17065            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17066        }
17067
17068        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17069                ALLOW_NON_FULL, "broadcast", callerPackage);
17070
17071        // Make sure that the user who is receiving this broadcast is running.
17072        // If not, we will just skip it. Make an exception for shutdown broadcasts
17073        // and upgrade steps.
17074
17075        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17076            if ((callingUid != Process.SYSTEM_UID
17077                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17078                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17079                Slog.w(TAG, "Skipping broadcast of " + intent
17080                        + ": user " + userId + " is stopped");
17081                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17082            }
17083        }
17084
17085        BroadcastOptions brOptions = null;
17086        if (bOptions != null) {
17087            brOptions = new BroadcastOptions(bOptions);
17088            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17089                // See if the caller is allowed to do this.  Note we are checking against
17090                // the actual real caller (not whoever provided the operation as say a
17091                // PendingIntent), because that who is actually supplied the arguments.
17092                if (checkComponentPermission(
17093                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17094                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17095                        != PackageManager.PERMISSION_GRANTED) {
17096                    String msg = "Permission Denial: " + intent.getAction()
17097                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17098                            + ", uid=" + callingUid + ")"
17099                            + " requires "
17100                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17101                    Slog.w(TAG, msg);
17102                    throw new SecurityException(msg);
17103                }
17104            }
17105        }
17106
17107        // Verify that protected broadcasts are only being sent by system code,
17108        // and that system code is only sending protected broadcasts.
17109        final String action = intent.getAction();
17110        final boolean isProtectedBroadcast;
17111        try {
17112            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17113        } catch (RemoteException e) {
17114            Slog.w(TAG, "Remote exception", e);
17115            return ActivityManager.BROADCAST_SUCCESS;
17116        }
17117
17118        final boolean isCallerSystem;
17119        switch (UserHandle.getAppId(callingUid)) {
17120            case Process.ROOT_UID:
17121            case Process.SYSTEM_UID:
17122            case Process.PHONE_UID:
17123            case Process.BLUETOOTH_UID:
17124            case Process.NFC_UID:
17125                isCallerSystem = true;
17126                break;
17127            default:
17128                isCallerSystem = (callerApp != null) && callerApp.persistent;
17129                break;
17130        }
17131
17132        if (isCallerSystem) {
17133            if (isProtectedBroadcast
17134                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17135                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17136                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17137                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17138                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17139                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17140                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17141                // Broadcast is either protected, or it's a public action that
17142                // we've relaxed, so it's fine for system internals to send.
17143            } else {
17144                // The vast majority of broadcasts sent from system internals
17145                // should be protected to avoid security holes, so yell loudly
17146                // to ensure we examine these cases.
17147                Log.wtf(TAG, "Sending non-protected broadcast " + action
17148                        + " from system", new Throwable());
17149            }
17150
17151        } else {
17152            if (isProtectedBroadcast) {
17153                String msg = "Permission Denial: not allowed to send broadcast "
17154                        + action + " from pid="
17155                        + callingPid + ", uid=" + callingUid;
17156                Slog.w(TAG, msg);
17157                throw new SecurityException(msg);
17158
17159            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17160                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17161                // Special case for compatibility: we don't want apps to send this,
17162                // but historically it has not been protected and apps may be using it
17163                // to poke their own app widget.  So, instead of making it protected,
17164                // just limit it to the caller.
17165                if (callerPackage == null) {
17166                    String msg = "Permission Denial: not allowed to send broadcast "
17167                            + action + " from unknown caller.";
17168                    Slog.w(TAG, msg);
17169                    throw new SecurityException(msg);
17170                } else if (intent.getComponent() != null) {
17171                    // They are good enough to send to an explicit component...  verify
17172                    // it is being sent to the calling app.
17173                    if (!intent.getComponent().getPackageName().equals(
17174                            callerPackage)) {
17175                        String msg = "Permission Denial: not allowed to send broadcast "
17176                                + action + " to "
17177                                + intent.getComponent().getPackageName() + " from "
17178                                + callerPackage;
17179                        Slog.w(TAG, msg);
17180                        throw new SecurityException(msg);
17181                    }
17182                } else {
17183                    // Limit broadcast to their own package.
17184                    intent.setPackage(callerPackage);
17185                }
17186            }
17187        }
17188
17189        if (action != null) {
17190            switch (action) {
17191                case Intent.ACTION_UID_REMOVED:
17192                case Intent.ACTION_PACKAGE_REMOVED:
17193                case Intent.ACTION_PACKAGE_CHANGED:
17194                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17195                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17196                case Intent.ACTION_PACKAGES_SUSPENDED:
17197                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17198                    // Handle special intents: if this broadcast is from the package
17199                    // manager about a package being removed, we need to remove all of
17200                    // its activities from the history stack.
17201                    if (checkComponentPermission(
17202                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17203                            callingPid, callingUid, -1, true)
17204                            != PackageManager.PERMISSION_GRANTED) {
17205                        String msg = "Permission Denial: " + intent.getAction()
17206                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17207                                + ", uid=" + callingUid + ")"
17208                                + " requires "
17209                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17210                        Slog.w(TAG, msg);
17211                        throw new SecurityException(msg);
17212                    }
17213                    switch (action) {
17214                        case Intent.ACTION_UID_REMOVED:
17215                            final Bundle intentExtras = intent.getExtras();
17216                            final int uid = intentExtras != null
17217                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17218                            if (uid >= 0) {
17219                                mBatteryStatsService.removeUid(uid);
17220                                mAppOpsService.uidRemoved(uid);
17221                            }
17222                            break;
17223                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17224                            // If resources are unavailable just force stop all those packages
17225                            // and flush the attribute cache as well.
17226                            String list[] =
17227                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17228                            if (list != null && list.length > 0) {
17229                                for (int i = 0; i < list.length; i++) {
17230                                    forceStopPackageLocked(list[i], -1, false, true, true,
17231                                            false, false, userId, "storage unmount");
17232                                }
17233                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17234                                sendPackageBroadcastLocked(
17235                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17236                                        userId);
17237                            }
17238                            break;
17239                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17240                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17241                            break;
17242                        case Intent.ACTION_PACKAGE_REMOVED:
17243                        case Intent.ACTION_PACKAGE_CHANGED:
17244                            Uri data = intent.getData();
17245                            String ssp;
17246                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17247                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17248                                final boolean replacing =
17249                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17250                                final boolean killProcess =
17251                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17252                                final boolean fullUninstall = removed && !replacing;
17253                                if (killProcess) {
17254                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17255                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17256                                            false, true, true, false, fullUninstall, userId,
17257                                            removed ? "pkg removed" : "pkg changed");
17258                                }
17259                                if (removed) {
17260                                    final int cmd = killProcess
17261                                            ? IApplicationThread.PACKAGE_REMOVED
17262                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17263                                    sendPackageBroadcastLocked(cmd,
17264                                            new String[] {ssp}, userId);
17265                                    if (fullUninstall) {
17266                                        mAppOpsService.packageRemoved(
17267                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17268
17269                                        // Remove all permissions granted from/to this package
17270                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17271
17272                                        removeTasksByPackageNameLocked(ssp, userId);
17273                                        mBatteryStatsService.notePackageUninstalled(ssp);
17274                                    }
17275                                } else {
17276                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17277                                            intent.getStringArrayExtra(
17278                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17279                                }
17280                            }
17281                            break;
17282                        case Intent.ACTION_PACKAGES_SUSPENDED:
17283                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17284                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17285                                    intent.getAction());
17286                            final String[] packageNames = intent.getStringArrayExtra(
17287                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17288                            final int userHandle = intent.getIntExtra(
17289                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17290
17291                            synchronized(ActivityManagerService.this) {
17292                                mRecentTasks.onPackagesSuspendedChanged(
17293                                        packageNames, suspended, userHandle);
17294                            }
17295                            break;
17296                    }
17297                    break;
17298                case Intent.ACTION_PACKAGE_REPLACED:
17299                {
17300                    final Uri data = intent.getData();
17301                    final String ssp;
17302                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17303                        final ApplicationInfo aInfo =
17304                                getPackageManagerInternalLocked().getApplicationInfo(
17305                                        ssp,
17306                                        userId);
17307                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17308                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17309                                new String[] {ssp}, userId);
17310                    }
17311                    break;
17312                }
17313                case Intent.ACTION_PACKAGE_ADDED:
17314                {
17315                    // Special case for adding a package: by default turn on compatibility mode.
17316                    Uri data = intent.getData();
17317                    String ssp;
17318                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17319                        final boolean replacing =
17320                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17321                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17322
17323                        try {
17324                            ApplicationInfo ai = AppGlobals.getPackageManager().
17325                                    getApplicationInfo(ssp, 0, 0);
17326                            mBatteryStatsService.notePackageInstalled(ssp,
17327                                    ai != null ? ai.versionCode : 0);
17328                        } catch (RemoteException e) {
17329                        }
17330                    }
17331                    break;
17332                }
17333                case Intent.ACTION_TIMEZONE_CHANGED:
17334                    // If this is the time zone changed action, queue up a message that will reset
17335                    // the timezone of all currently running processes. This message will get
17336                    // queued up before the broadcast happens.
17337                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17338                    break;
17339                case Intent.ACTION_TIME_CHANGED:
17340                    // If the user set the time, let all running processes know.
17341                    final int is24Hour =
17342                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17343                                    : 0;
17344                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17345                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17346                    synchronized (stats) {
17347                        stats.noteCurrentTimeChangedLocked();
17348                    }
17349                    break;
17350                case Intent.ACTION_CLEAR_DNS_CACHE:
17351                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17352                    break;
17353                case Proxy.PROXY_CHANGE_ACTION:
17354                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17355                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17356                    break;
17357                case android.hardware.Camera.ACTION_NEW_PICTURE:
17358                case android.hardware.Camera.ACTION_NEW_VIDEO:
17359                    // These broadcasts are no longer allowed by the system, since they can
17360                    // cause significant thrashing at a crictical point (using the camera).
17361                    // Apps should use JobScehduler to monitor for media provider changes.
17362                    Slog.w(TAG, action + " no longer allowed; dropping from "
17363                            + UserHandle.formatUid(callingUid));
17364                    // Lie; we don't want to crash the app.
17365                    return ActivityManager.BROADCAST_SUCCESS;
17366            }
17367        }
17368
17369        // Add to the sticky list if requested.
17370        if (sticky) {
17371            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17372                    callingPid, callingUid)
17373                    != PackageManager.PERMISSION_GRANTED) {
17374                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17375                        + callingPid + ", uid=" + callingUid
17376                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17377                Slog.w(TAG, msg);
17378                throw new SecurityException(msg);
17379            }
17380            if (requiredPermissions != null && requiredPermissions.length > 0) {
17381                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17382                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17383                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17384            }
17385            if (intent.getComponent() != null) {
17386                throw new SecurityException(
17387                        "Sticky broadcasts can't target a specific component");
17388            }
17389            // We use userId directly here, since the "all" target is maintained
17390            // as a separate set of sticky broadcasts.
17391            if (userId != UserHandle.USER_ALL) {
17392                // But first, if this is not a broadcast to all users, then
17393                // make sure it doesn't conflict with an existing broadcast to
17394                // all users.
17395                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17396                        UserHandle.USER_ALL);
17397                if (stickies != null) {
17398                    ArrayList<Intent> list = stickies.get(intent.getAction());
17399                    if (list != null) {
17400                        int N = list.size();
17401                        int i;
17402                        for (i=0; i<N; i++) {
17403                            if (intent.filterEquals(list.get(i))) {
17404                                throw new IllegalArgumentException(
17405                                        "Sticky broadcast " + intent + " for user "
17406                                        + userId + " conflicts with existing global broadcast");
17407                            }
17408                        }
17409                    }
17410                }
17411            }
17412            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17413            if (stickies == null) {
17414                stickies = new ArrayMap<>();
17415                mStickyBroadcasts.put(userId, stickies);
17416            }
17417            ArrayList<Intent> list = stickies.get(intent.getAction());
17418            if (list == null) {
17419                list = new ArrayList<>();
17420                stickies.put(intent.getAction(), list);
17421            }
17422            final int stickiesCount = list.size();
17423            int i;
17424            for (i = 0; i < stickiesCount; i++) {
17425                if (intent.filterEquals(list.get(i))) {
17426                    // This sticky already exists, replace it.
17427                    list.set(i, new Intent(intent));
17428                    break;
17429                }
17430            }
17431            if (i >= stickiesCount) {
17432                list.add(new Intent(intent));
17433            }
17434        }
17435
17436        int[] users;
17437        if (userId == UserHandle.USER_ALL) {
17438            // Caller wants broadcast to go to all started users.
17439            users = mUserController.getStartedUserArrayLocked();
17440        } else {
17441            // Caller wants broadcast to go to one specific user.
17442            users = new int[] {userId};
17443        }
17444
17445        // Figure out who all will receive this broadcast.
17446        List receivers = null;
17447        List<BroadcastFilter> registeredReceivers = null;
17448        // Need to resolve the intent to interested receivers...
17449        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17450                 == 0) {
17451            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17452        }
17453        if (intent.getComponent() == null) {
17454            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17455                // Query one target user at a time, excluding shell-restricted users
17456                for (int i = 0; i < users.length; i++) {
17457                    if (mUserController.hasUserRestriction(
17458                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17459                        continue;
17460                    }
17461                    List<BroadcastFilter> registeredReceiversForUser =
17462                            mReceiverResolver.queryIntent(intent,
17463                                    resolvedType, false, users[i]);
17464                    if (registeredReceivers == null) {
17465                        registeredReceivers = registeredReceiversForUser;
17466                    } else if (registeredReceiversForUser != null) {
17467                        registeredReceivers.addAll(registeredReceiversForUser);
17468                    }
17469                }
17470            } else {
17471                registeredReceivers = mReceiverResolver.queryIntent(intent,
17472                        resolvedType, false, userId);
17473            }
17474        }
17475
17476        final boolean replacePending =
17477                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17478
17479        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17480                + " replacePending=" + replacePending);
17481
17482        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17483        if (!ordered && NR > 0) {
17484            // If we are not serializing this broadcast, then send the
17485            // registered receivers separately so they don't wait for the
17486            // components to be launched.
17487            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17488            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17489                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17490                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17491                    resultExtras, ordered, sticky, false, userId);
17492            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17493            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17494            if (!replaced) {
17495                queue.enqueueParallelBroadcastLocked(r);
17496                queue.scheduleBroadcastsLocked();
17497            }
17498            registeredReceivers = null;
17499            NR = 0;
17500        }
17501
17502        // Merge into one list.
17503        int ir = 0;
17504        if (receivers != null) {
17505            // A special case for PACKAGE_ADDED: do not allow the package
17506            // being added to see this broadcast.  This prevents them from
17507            // using this as a back door to get run as soon as they are
17508            // installed.  Maybe in the future we want to have a special install
17509            // broadcast or such for apps, but we'd like to deliberately make
17510            // this decision.
17511            String skipPackages[] = null;
17512            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17513                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17514                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17515                Uri data = intent.getData();
17516                if (data != null) {
17517                    String pkgName = data.getSchemeSpecificPart();
17518                    if (pkgName != null) {
17519                        skipPackages = new String[] { pkgName };
17520                    }
17521                }
17522            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17523                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17524            }
17525            if (skipPackages != null && (skipPackages.length > 0)) {
17526                for (String skipPackage : skipPackages) {
17527                    if (skipPackage != null) {
17528                        int NT = receivers.size();
17529                        for (int it=0; it<NT; it++) {
17530                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17531                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17532                                receivers.remove(it);
17533                                it--;
17534                                NT--;
17535                            }
17536                        }
17537                    }
17538                }
17539            }
17540
17541            int NT = receivers != null ? receivers.size() : 0;
17542            int it = 0;
17543            ResolveInfo curt = null;
17544            BroadcastFilter curr = null;
17545            while (it < NT && ir < NR) {
17546                if (curt == null) {
17547                    curt = (ResolveInfo)receivers.get(it);
17548                }
17549                if (curr == null) {
17550                    curr = registeredReceivers.get(ir);
17551                }
17552                if (curr.getPriority() >= curt.priority) {
17553                    // Insert this broadcast record into the final list.
17554                    receivers.add(it, curr);
17555                    ir++;
17556                    curr = null;
17557                    it++;
17558                    NT++;
17559                } else {
17560                    // Skip to the next ResolveInfo in the final list.
17561                    it++;
17562                    curt = null;
17563                }
17564            }
17565        }
17566        while (ir < NR) {
17567            if (receivers == null) {
17568                receivers = new ArrayList();
17569            }
17570            receivers.add(registeredReceivers.get(ir));
17571            ir++;
17572        }
17573
17574        if ((receivers != null && receivers.size() > 0)
17575                || resultTo != null) {
17576            BroadcastQueue queue = broadcastQueueForIntent(intent);
17577            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17578                    callerPackage, callingPid, callingUid, resolvedType,
17579                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17580                    resultData, resultExtras, ordered, sticky, false, userId);
17581
17582            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17583                    + ": prev had " + queue.mOrderedBroadcasts.size());
17584            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17585                    "Enqueueing broadcast " + r.intent.getAction());
17586
17587            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17588            if (!replaced) {
17589                queue.enqueueOrderedBroadcastLocked(r);
17590                queue.scheduleBroadcastsLocked();
17591            }
17592        }
17593
17594        return ActivityManager.BROADCAST_SUCCESS;
17595    }
17596
17597    final Intent verifyBroadcastLocked(Intent intent) {
17598        // Refuse possible leaked file descriptors
17599        if (intent != null && intent.hasFileDescriptors() == true) {
17600            throw new IllegalArgumentException("File descriptors passed in Intent");
17601        }
17602
17603        int flags = intent.getFlags();
17604
17605        if (!mProcessesReady) {
17606            // if the caller really truly claims to know what they're doing, go
17607            // ahead and allow the broadcast without launching any receivers
17608            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17609                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17610            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17611                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17612                        + " before boot completion");
17613                throw new IllegalStateException("Cannot broadcast before boot completed");
17614            }
17615        }
17616
17617        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17618            throw new IllegalArgumentException(
17619                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17620        }
17621
17622        return intent;
17623    }
17624
17625    public final int broadcastIntent(IApplicationThread caller,
17626            Intent intent, String resolvedType, IIntentReceiver resultTo,
17627            int resultCode, String resultData, Bundle resultExtras,
17628            String[] requiredPermissions, int appOp, Bundle bOptions,
17629            boolean serialized, boolean sticky, int userId) {
17630        enforceNotIsolatedCaller("broadcastIntent");
17631        synchronized(this) {
17632            intent = verifyBroadcastLocked(intent);
17633
17634            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17635            final int callingPid = Binder.getCallingPid();
17636            final int callingUid = Binder.getCallingUid();
17637            final long origId = Binder.clearCallingIdentity();
17638            int res = broadcastIntentLocked(callerApp,
17639                    callerApp != null ? callerApp.info.packageName : null,
17640                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17641                    requiredPermissions, appOp, null, serialized, sticky,
17642                    callingPid, callingUid, userId);
17643            Binder.restoreCallingIdentity(origId);
17644            return res;
17645        }
17646    }
17647
17648
17649    int broadcastIntentInPackage(String packageName, int uid,
17650            Intent intent, String resolvedType, IIntentReceiver resultTo,
17651            int resultCode, String resultData, Bundle resultExtras,
17652            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17653            int userId) {
17654        synchronized(this) {
17655            intent = verifyBroadcastLocked(intent);
17656
17657            final long origId = Binder.clearCallingIdentity();
17658            String[] requiredPermissions = requiredPermission == null ? null
17659                    : new String[] {requiredPermission};
17660            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17661                    resultTo, resultCode, resultData, resultExtras,
17662                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17663                    sticky, -1, uid, userId);
17664            Binder.restoreCallingIdentity(origId);
17665            return res;
17666        }
17667    }
17668
17669    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17670        // Refuse possible leaked file descriptors
17671        if (intent != null && intent.hasFileDescriptors() == true) {
17672            throw new IllegalArgumentException("File descriptors passed in Intent");
17673        }
17674
17675        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17676                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17677
17678        synchronized(this) {
17679            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17680                    != PackageManager.PERMISSION_GRANTED) {
17681                String msg = "Permission Denial: unbroadcastIntent() from pid="
17682                        + Binder.getCallingPid()
17683                        + ", uid=" + Binder.getCallingUid()
17684                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17685                Slog.w(TAG, msg);
17686                throw new SecurityException(msg);
17687            }
17688            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17689            if (stickies != null) {
17690                ArrayList<Intent> list = stickies.get(intent.getAction());
17691                if (list != null) {
17692                    int N = list.size();
17693                    int i;
17694                    for (i=0; i<N; i++) {
17695                        if (intent.filterEquals(list.get(i))) {
17696                            list.remove(i);
17697                            break;
17698                        }
17699                    }
17700                    if (list.size() <= 0) {
17701                        stickies.remove(intent.getAction());
17702                    }
17703                }
17704                if (stickies.size() <= 0) {
17705                    mStickyBroadcasts.remove(userId);
17706                }
17707            }
17708        }
17709    }
17710
17711    void backgroundServicesFinishedLocked(int userId) {
17712        for (BroadcastQueue queue : mBroadcastQueues) {
17713            queue.backgroundServicesFinishedLocked(userId);
17714        }
17715    }
17716
17717    public void finishReceiver(IBinder who, int resultCode, String resultData,
17718            Bundle resultExtras, boolean resultAbort, int flags) {
17719        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17720
17721        // Refuse possible leaked file descriptors
17722        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17723            throw new IllegalArgumentException("File descriptors passed in Bundle");
17724        }
17725
17726        final long origId = Binder.clearCallingIdentity();
17727        try {
17728            boolean doNext = false;
17729            BroadcastRecord r;
17730
17731            synchronized(this) {
17732                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17733                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17734                r = queue.getMatchingOrderedReceiver(who);
17735                if (r != null) {
17736                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17737                        resultData, resultExtras, resultAbort, true);
17738                }
17739            }
17740
17741            if (doNext) {
17742                r.queue.processNextBroadcast(false);
17743            }
17744            trimApplications();
17745        } finally {
17746            Binder.restoreCallingIdentity(origId);
17747        }
17748    }
17749
17750    // =========================================================
17751    // INSTRUMENTATION
17752    // =========================================================
17753
17754    public boolean startInstrumentation(ComponentName className,
17755            String profileFile, int flags, Bundle arguments,
17756            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17757            int userId, String abiOverride) {
17758        enforceNotIsolatedCaller("startInstrumentation");
17759        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17760                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17761        // Refuse possible leaked file descriptors
17762        if (arguments != null && arguments.hasFileDescriptors()) {
17763            throw new IllegalArgumentException("File descriptors passed in Bundle");
17764        }
17765
17766        synchronized(this) {
17767            InstrumentationInfo ii = null;
17768            ApplicationInfo ai = null;
17769            try {
17770                ii = mContext.getPackageManager().getInstrumentationInfo(
17771                    className, STOCK_PM_FLAGS);
17772                ai = AppGlobals.getPackageManager().getApplicationInfo(
17773                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17774            } catch (PackageManager.NameNotFoundException e) {
17775            } catch (RemoteException e) {
17776            }
17777            if (ii == null) {
17778                reportStartInstrumentationFailureLocked(watcher, className,
17779                        "Unable to find instrumentation info for: " + className);
17780                return false;
17781            }
17782            if (ai == null) {
17783                reportStartInstrumentationFailureLocked(watcher, className,
17784                        "Unable to find instrumentation target package: " + ii.targetPackage);
17785                return false;
17786            }
17787            if (!ai.hasCode()) {
17788                reportStartInstrumentationFailureLocked(watcher, className,
17789                        "Instrumentation target has no code: " + ii.targetPackage);
17790                return false;
17791            }
17792
17793            int match = mContext.getPackageManager().checkSignatures(
17794                    ii.targetPackage, ii.packageName);
17795            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17796                String msg = "Permission Denial: starting instrumentation "
17797                        + className + " from pid="
17798                        + Binder.getCallingPid()
17799                        + ", uid=" + Binder.getCallingPid()
17800                        + " not allowed because package " + ii.packageName
17801                        + " does not have a signature matching the target "
17802                        + ii.targetPackage;
17803                reportStartInstrumentationFailureLocked(watcher, className, msg);
17804                throw new SecurityException(msg);
17805            }
17806
17807            final long origId = Binder.clearCallingIdentity();
17808            // Instrumentation can kill and relaunch even persistent processes
17809            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17810                    "start instr");
17811            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17812            app.instrumentationClass = className;
17813            app.instrumentationInfo = ai;
17814            app.instrumentationProfileFile = profileFile;
17815            app.instrumentationArguments = arguments;
17816            app.instrumentationWatcher = watcher;
17817            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17818            app.instrumentationResultClass = className;
17819            Binder.restoreCallingIdentity(origId);
17820        }
17821
17822        return true;
17823    }
17824
17825    /**
17826     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17827     * error to the logs, but if somebody is watching, send the report there too.  This enables
17828     * the "am" command to report errors with more information.
17829     *
17830     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17831     * @param cn The component name of the instrumentation.
17832     * @param report The error report.
17833     */
17834    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17835            ComponentName cn, String report) {
17836        Slog.w(TAG, report);
17837        if (watcher != null) {
17838            Bundle results = new Bundle();
17839            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17840            results.putString("Error", report);
17841            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17842        }
17843    }
17844
17845    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17846        if (app.instrumentationWatcher != null) {
17847            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17848                    app.instrumentationClass, resultCode, results);
17849        }
17850
17851        // Can't call out of the system process with a lock held, so post a message.
17852        if (app.instrumentationUiAutomationConnection != null) {
17853            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17854                    app.instrumentationUiAutomationConnection).sendToTarget();
17855        }
17856
17857        app.instrumentationWatcher = null;
17858        app.instrumentationUiAutomationConnection = null;
17859        app.instrumentationClass = null;
17860        app.instrumentationInfo = null;
17861        app.instrumentationProfileFile = null;
17862        app.instrumentationArguments = null;
17863
17864        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17865                "finished inst");
17866    }
17867
17868    public void finishInstrumentation(IApplicationThread target,
17869            int resultCode, Bundle results) {
17870        int userId = UserHandle.getCallingUserId();
17871        // Refuse possible leaked file descriptors
17872        if (results != null && results.hasFileDescriptors()) {
17873            throw new IllegalArgumentException("File descriptors passed in Intent");
17874        }
17875
17876        synchronized(this) {
17877            ProcessRecord app = getRecordForAppLocked(target);
17878            if (app == null) {
17879                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17880                return;
17881            }
17882            final long origId = Binder.clearCallingIdentity();
17883            finishInstrumentationLocked(app, resultCode, results);
17884            Binder.restoreCallingIdentity(origId);
17885        }
17886    }
17887
17888    // =========================================================
17889    // CONFIGURATION
17890    // =========================================================
17891
17892    public ConfigurationInfo getDeviceConfigurationInfo() {
17893        ConfigurationInfo config = new ConfigurationInfo();
17894        synchronized (this) {
17895            config.reqTouchScreen = mConfiguration.touchscreen;
17896            config.reqKeyboardType = mConfiguration.keyboard;
17897            config.reqNavigation = mConfiguration.navigation;
17898            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17899                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17900                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17901            }
17902            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17903                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17904                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17905            }
17906            config.reqGlEsVersion = GL_ES_VERSION;
17907        }
17908        return config;
17909    }
17910
17911    ActivityStack getFocusedStack() {
17912        return mStackSupervisor.getFocusedStack();
17913    }
17914
17915    @Override
17916    public int getFocusedStackId() throws RemoteException {
17917        ActivityStack focusedStack = getFocusedStack();
17918        if (focusedStack != null) {
17919            return focusedStack.getStackId();
17920        }
17921        return -1;
17922    }
17923
17924    public Configuration getConfiguration() {
17925        Configuration ci;
17926        synchronized(this) {
17927            ci = new Configuration(mConfiguration);
17928            ci.userSetLocale = false;
17929        }
17930        return ci;
17931    }
17932
17933    @Override
17934    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17935        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17936        synchronized (this) {
17937            mSuppressResizeConfigChanges = suppress;
17938        }
17939    }
17940
17941    @Override
17942    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17943        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17944        if (fromStackId == HOME_STACK_ID) {
17945            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17946        }
17947        synchronized (this) {
17948            final long origId = Binder.clearCallingIdentity();
17949            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
17950            if (stack != null) {
17951                mWindowManager.deferSurfaceLayout();
17952                try {
17953                    if (fromStackId == DOCKED_STACK_ID) {
17954
17955                        // We are moving all tasks from the docked stack to the fullscreen stack,
17956                        // which is dismissing the docked stack, so resize all other stacks to
17957                        // fullscreen here already so we don't end up with resize trashing.
17958                        for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
17959                            if (StackId.isResizeableByDockedStack(i)) {
17960                                ActivityStack otherStack = mStackSupervisor.getStack(i);
17961                                if (otherStack != null) {
17962                                    mStackSupervisor.resizeStackLocked(i,
17963                                            null, null, null, PRESERVE_WINDOWS,
17964                                            true /* allowResizeInDockedMode */);
17965                                }
17966                            }
17967                        }
17968                    }
17969                    final ArrayList<TaskRecord> tasks = stack.getAllTasks();
17970                    final int size = tasks.size();
17971                    if (onTop) {
17972                        for (int i = 0; i < size; i++) {
17973                            mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
17974                                    FULLSCREEN_WORKSPACE_STACK_ID, onTop, !FORCE_FOCUS,
17975                                    "moveTasksToFullscreenStack", ANIMATE);
17976                        }
17977                    } else {
17978                        for (int i = size - 1; i >= 0; i--) {
17979                            mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
17980                                    FULLSCREEN_WORKSPACE_STACK_ID, 0);
17981                        }
17982                    }
17983                } finally {
17984                    mWindowManager.continueSurfaceLayout();
17985                }
17986
17987            }
17988            Binder.restoreCallingIdentity(origId);
17989        }
17990    }
17991
17992    @Override
17993    public void updatePersistentConfiguration(Configuration values) {
17994        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17995                "updateConfiguration()");
17996        enforceWriteSettingsPermission("updateConfiguration()");
17997        if (values == null) {
17998            throw new NullPointerException("Configuration must not be null");
17999        }
18000
18001        int userId = UserHandle.getCallingUserId();
18002
18003        synchronized(this) {
18004            final long origId = Binder.clearCallingIdentity();
18005            updateConfigurationLocked(values, null, false, true, userId);
18006            Binder.restoreCallingIdentity(origId);
18007        }
18008    }
18009
18010    private void updateFontScaleIfNeeded() {
18011        final int currentUserId;
18012        synchronized(this) {
18013            currentUserId = mUserController.getCurrentUserIdLocked();
18014        }
18015        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18016                FONT_SCALE, 1.0f, currentUserId);
18017        if (mConfiguration.fontScale != scaleFactor) {
18018            final Configuration configuration = mWindowManager.computeNewConfiguration();
18019            configuration.fontScale = scaleFactor;
18020            updatePersistentConfiguration(configuration);
18021        }
18022    }
18023
18024    private void enforceWriteSettingsPermission(String func) {
18025        int uid = Binder.getCallingUid();
18026        if (uid == Process.ROOT_UID) {
18027            return;
18028        }
18029
18030        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18031                Settings.getPackageNameForUid(mContext, uid), false)) {
18032            return;
18033        }
18034
18035        String msg = "Permission Denial: " + func + " from pid="
18036                + Binder.getCallingPid()
18037                + ", uid=" + uid
18038                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18039        Slog.w(TAG, msg);
18040        throw new SecurityException(msg);
18041    }
18042
18043    public void updateConfiguration(Configuration values) {
18044        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18045                "updateConfiguration()");
18046
18047        synchronized(this) {
18048            if (values == null && mWindowManager != null) {
18049                // sentinel: fetch the current configuration from the window manager
18050                values = mWindowManager.computeNewConfiguration();
18051            }
18052
18053            if (mWindowManager != null) {
18054                mProcessList.applyDisplaySize(mWindowManager);
18055            }
18056
18057            final long origId = Binder.clearCallingIdentity();
18058            if (values != null) {
18059                Settings.System.clearConfiguration(values);
18060            }
18061            updateConfigurationLocked(values, null, false);
18062            Binder.restoreCallingIdentity(origId);
18063        }
18064    }
18065
18066    void updateUserConfigurationLocked() {
18067        Configuration configuration = new Configuration(mConfiguration);
18068        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18069                mUserController.getCurrentUserIdLocked());
18070        updateConfigurationLocked(configuration, null, false);
18071    }
18072
18073    boolean updateConfigurationLocked(Configuration values,
18074            ActivityRecord starting, boolean initLocale) {
18075        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18076        return updateConfigurationLocked(values, starting, initLocale, false,
18077                UserHandle.USER_NULL);
18078    }
18079
18080    // To cache the list of supported system locales
18081    private String[] mSupportedSystemLocales = null;
18082
18083    /**
18084     * Do either or both things: (1) change the current configuration, and (2)
18085     * make sure the given activity is running with the (now) current
18086     * configuration.  Returns true if the activity has been left running, or
18087     * false if <var>starting</var> is being destroyed to match the new
18088     * configuration.
18089     *
18090     * @param userId is only used when persistent parameter is set to true to persist configuration
18091     *               for that particular user
18092     */
18093    private boolean updateConfigurationLocked(Configuration values,
18094            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18095        int changes = 0;
18096
18097        if (mWindowManager != null) {
18098            mWindowManager.deferSurfaceLayout();
18099        }
18100        if (values != null) {
18101            Configuration newConfig = new Configuration(mConfiguration);
18102            changes = newConfig.updateFrom(values);
18103            if (changes != 0) {
18104                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18105                        "Updating configuration to: " + values);
18106
18107                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18108
18109                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18110                    final Locale locale;
18111                    if (values.getLocales().size() == 1) {
18112                        // This is an optimization to avoid the JNI call when the result of
18113                        // getFirstMatch() does not depend on the supported locales.
18114                        locale = values.getLocales().get(0);
18115                    } else {
18116                        if (mSupportedSystemLocales == null) {
18117                            mSupportedSystemLocales =
18118                                    Resources.getSystem().getAssets().getLocales();
18119                        }
18120                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18121                    }
18122                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18123                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18124                            locale));
18125                }
18126
18127                mConfigurationSeq++;
18128                if (mConfigurationSeq <= 0) {
18129                    mConfigurationSeq = 1;
18130                }
18131                newConfig.seq = mConfigurationSeq;
18132                mConfiguration = newConfig;
18133                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18134                mUsageStatsService.reportConfigurationChange(newConfig,
18135                        mUserController.getCurrentUserIdLocked());
18136                //mUsageStatsService.noteStartConfig(newConfig);
18137
18138                final Configuration configCopy = new Configuration(mConfiguration);
18139
18140                // TODO: If our config changes, should we auto dismiss any currently
18141                // showing dialogs?
18142                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18143
18144                AttributeCache ac = AttributeCache.instance();
18145                if (ac != null) {
18146                    ac.updateConfiguration(configCopy);
18147                }
18148
18149                // Make sure all resources in our process are updated
18150                // right now, so that anyone who is going to retrieve
18151                // resource values after we return will be sure to get
18152                // the new ones.  This is especially important during
18153                // boot, where the first config change needs to guarantee
18154                // all resources have that config before following boot
18155                // code is executed.
18156                mSystemThread.applyConfigurationToResources(configCopy);
18157
18158                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18159                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18160                    msg.obj = new Configuration(configCopy);
18161                    msg.arg1 = userId;
18162                    mHandler.sendMessage(msg);
18163                }
18164
18165                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18166                if (isDensityChange) {
18167                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18168                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18169                }
18170
18171                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18172                    ProcessRecord app = mLruProcesses.get(i);
18173                    try {
18174                        if (app.thread != null) {
18175                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18176                                    + app.processName + " new config " + mConfiguration);
18177                            app.thread.scheduleConfigurationChanged(configCopy);
18178                        }
18179                    } catch (Exception e) {
18180                    }
18181                }
18182                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18183                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18184                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18185                        | Intent.FLAG_RECEIVER_FOREGROUND);
18186                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18187                        null, AppOpsManager.OP_NONE, null, false, false,
18188                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18189                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18190                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18191                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18192                    if (!mProcessesReady) {
18193                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18194                    }
18195                    broadcastIntentLocked(null, null, intent,
18196                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18197                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18198                }
18199            }
18200            // Update the configuration with WM first and check if any of the stacks need to be
18201            // resized due to the configuration change. If so, resize the stacks now and do any
18202            // relaunches if necessary. This way we don't need to relaunch again below in
18203            // ensureActivityConfigurationLocked().
18204            if (mWindowManager != null) {
18205                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18206                if (resizedStacks != null) {
18207                    for (int stackId : resizedStacks) {
18208                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18209                        mStackSupervisor.resizeStackLocked(
18210                                stackId, newBounds, null, null, false, false);
18211                    }
18212                }
18213            }
18214        }
18215
18216        boolean kept = true;
18217        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18218        // mainStack is null during startup.
18219        if (mainStack != null) {
18220            if (changes != 0 && starting == null) {
18221                // If the configuration changed, and the caller is not already
18222                // in the process of starting an activity, then find the top
18223                // activity to check if its configuration needs to change.
18224                starting = mainStack.topRunningActivityLocked();
18225            }
18226
18227            if (starting != null) {
18228                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18229                // And we need to make sure at this point that all other activities
18230                // are made visible with the correct configuration.
18231                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18232                        !PRESERVE_WINDOWS);
18233            }
18234        }
18235        if (mWindowManager != null) {
18236            mWindowManager.continueSurfaceLayout();
18237        }
18238        return kept;
18239    }
18240
18241    /**
18242     * Decide based on the configuration whether we should shouw the ANR,
18243     * crash, etc dialogs.  The idea is that if there is no affordnace to
18244     * press the on-screen buttons, we shouldn't show the dialog.
18245     *
18246     * A thought: SystemUI might also want to get told about this, the Power
18247     * dialog / global actions also might want different behaviors.
18248     */
18249    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18250        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18251                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18252                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18253        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18254                                    == Configuration.UI_MODE_TYPE_CAR);
18255        return inputMethodExists && uiIsNotCarType && !inVrMode;
18256    }
18257
18258    @Override
18259    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18260        synchronized (this) {
18261            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18262            if (srec != null) {
18263                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18264            }
18265        }
18266        return false;
18267    }
18268
18269    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18270            Intent resultData) {
18271
18272        synchronized (this) {
18273            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18274            if (r != null) {
18275                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18276            }
18277            return false;
18278        }
18279    }
18280
18281    public int getLaunchedFromUid(IBinder activityToken) {
18282        ActivityRecord srec;
18283        synchronized (this) {
18284            srec = ActivityRecord.forTokenLocked(activityToken);
18285        }
18286        if (srec == null) {
18287            return -1;
18288        }
18289        return srec.launchedFromUid;
18290    }
18291
18292    public String getLaunchedFromPackage(IBinder activityToken) {
18293        ActivityRecord srec;
18294        synchronized (this) {
18295            srec = ActivityRecord.forTokenLocked(activityToken);
18296        }
18297        if (srec == null) {
18298            return null;
18299        }
18300        return srec.launchedFromPackage;
18301    }
18302
18303    // =========================================================
18304    // LIFETIME MANAGEMENT
18305    // =========================================================
18306
18307    // Returns which broadcast queue the app is the current [or imminent] receiver
18308    // on, or 'null' if the app is not an active broadcast recipient.
18309    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18310        BroadcastRecord r = app.curReceiver;
18311        if (r != null) {
18312            return r.queue;
18313        }
18314
18315        // It's not the current receiver, but it might be starting up to become one
18316        synchronized (this) {
18317            for (BroadcastQueue queue : mBroadcastQueues) {
18318                r = queue.mPendingBroadcast;
18319                if (r != null && r.curApp == app) {
18320                    // found it; report which queue it's in
18321                    return queue;
18322                }
18323            }
18324        }
18325
18326        return null;
18327    }
18328
18329    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18330            int targetUid, ComponentName targetComponent, String targetProcess) {
18331        if (!mTrackingAssociations) {
18332            return null;
18333        }
18334        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18335                = mAssociations.get(targetUid);
18336        if (components == null) {
18337            components = new ArrayMap<>();
18338            mAssociations.put(targetUid, components);
18339        }
18340        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18341        if (sourceUids == null) {
18342            sourceUids = new SparseArray<>();
18343            components.put(targetComponent, sourceUids);
18344        }
18345        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18346        if (sourceProcesses == null) {
18347            sourceProcesses = new ArrayMap<>();
18348            sourceUids.put(sourceUid, sourceProcesses);
18349        }
18350        Association ass = sourceProcesses.get(sourceProcess);
18351        if (ass == null) {
18352            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18353                    targetProcess);
18354            sourceProcesses.put(sourceProcess, ass);
18355        }
18356        ass.mCount++;
18357        ass.mNesting++;
18358        if (ass.mNesting == 1) {
18359            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18360            ass.mLastState = sourceState;
18361        }
18362        return ass;
18363    }
18364
18365    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18366            ComponentName targetComponent) {
18367        if (!mTrackingAssociations) {
18368            return;
18369        }
18370        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18371                = mAssociations.get(targetUid);
18372        if (components == null) {
18373            return;
18374        }
18375        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18376        if (sourceUids == null) {
18377            return;
18378        }
18379        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18380        if (sourceProcesses == null) {
18381            return;
18382        }
18383        Association ass = sourceProcesses.get(sourceProcess);
18384        if (ass == null || ass.mNesting <= 0) {
18385            return;
18386        }
18387        ass.mNesting--;
18388        if (ass.mNesting == 0) {
18389            long uptime = SystemClock.uptimeMillis();
18390            ass.mTime += uptime - ass.mStartTime;
18391            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18392                    += uptime - ass.mLastStateUptime;
18393            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18394        }
18395    }
18396
18397    private void noteUidProcessState(final int uid, final int state) {
18398        mBatteryStatsService.noteUidProcessState(uid, state);
18399        if (mTrackingAssociations) {
18400            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18401                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18402                        = mAssociations.valueAt(i1);
18403                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18404                    SparseArray<ArrayMap<String, Association>> sourceUids
18405                            = targetComponents.valueAt(i2);
18406                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18407                    if (sourceProcesses != null) {
18408                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18409                            Association ass = sourceProcesses.valueAt(i4);
18410                            if (ass.mNesting >= 1) {
18411                                // currently associated
18412                                long uptime = SystemClock.uptimeMillis();
18413                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18414                                        += uptime - ass.mLastStateUptime;
18415                                ass.mLastState = state;
18416                                ass.mLastStateUptime = uptime;
18417                            }
18418                        }
18419                    }
18420                }
18421            }
18422        }
18423    }
18424
18425    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18426            boolean doingAll, long now) {
18427        if (mAdjSeq == app.adjSeq) {
18428            // This adjustment has already been computed.
18429            return app.curRawAdj;
18430        }
18431
18432        if (app.thread == null) {
18433            app.adjSeq = mAdjSeq;
18434            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18435            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18436            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18437        }
18438
18439        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18440        app.adjSource = null;
18441        app.adjTarget = null;
18442        app.empty = false;
18443        app.cached = false;
18444
18445        final int activitiesSize = app.activities.size();
18446
18447        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18448            // The max adjustment doesn't allow this app to be anything
18449            // below foreground, so it is not worth doing work for it.
18450            app.adjType = "fixed";
18451            app.adjSeq = mAdjSeq;
18452            app.curRawAdj = app.maxAdj;
18453            app.foregroundActivities = false;
18454            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18455            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18456            // System processes can do UI, and when they do we want to have
18457            // them trim their memory after the user leaves the UI.  To
18458            // facilitate this, here we need to determine whether or not it
18459            // is currently showing UI.
18460            app.systemNoUi = true;
18461            if (app == TOP_APP) {
18462                app.systemNoUi = false;
18463            } else if (activitiesSize > 0) {
18464                for (int j = 0; j < activitiesSize; j++) {
18465                    final ActivityRecord r = app.activities.get(j);
18466                    if (r.visible) {
18467                        app.systemNoUi = false;
18468                    }
18469                }
18470            }
18471            if (!app.systemNoUi) {
18472                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18473            }
18474            return (app.curAdj=app.maxAdj);
18475        }
18476
18477        app.systemNoUi = false;
18478
18479        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18480
18481        // Determine the importance of the process, starting with most
18482        // important to least, and assign an appropriate OOM adjustment.
18483        int adj;
18484        int schedGroup;
18485        int procState;
18486        boolean foregroundActivities = false;
18487        BroadcastQueue queue;
18488        if (app == TOP_APP) {
18489            // The last app on the list is the foreground app.
18490            adj = ProcessList.FOREGROUND_APP_ADJ;
18491            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18492            app.adjType = "top-activity";
18493            foregroundActivities = true;
18494            procState = PROCESS_STATE_CUR_TOP;
18495        } else if (app.instrumentationClass != null) {
18496            // Don't want to kill running instrumentation.
18497            adj = ProcessList.FOREGROUND_APP_ADJ;
18498            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18499            app.adjType = "instrumentation";
18500            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18501        } else if ((queue = isReceivingBroadcast(app)) != null) {
18502            // An app that is currently receiving a broadcast also
18503            // counts as being in the foreground for OOM killer purposes.
18504            // It's placed in a sched group based on the nature of the
18505            // broadcast as reflected by which queue it's active in.
18506            adj = ProcessList.FOREGROUND_APP_ADJ;
18507            schedGroup = (queue == mFgBroadcastQueue)
18508                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18509            app.adjType = "broadcast";
18510            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18511        } else if (app.executingServices.size() > 0) {
18512            // An app that is currently executing a service callback also
18513            // counts as being in the foreground.
18514            adj = ProcessList.FOREGROUND_APP_ADJ;
18515            schedGroup = app.execServicesFg ?
18516                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18517            app.adjType = "exec-service";
18518            procState = ActivityManager.PROCESS_STATE_SERVICE;
18519            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18520        } else {
18521            // As far as we know the process is empty.  We may change our mind later.
18522            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18523            // At this point we don't actually know the adjustment.  Use the cached adj
18524            // value that the caller wants us to.
18525            adj = cachedAdj;
18526            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18527            app.cached = true;
18528            app.empty = true;
18529            app.adjType = "cch-empty";
18530        }
18531
18532        // Examine all activities if not already foreground.
18533        if (!foregroundActivities && activitiesSize > 0) {
18534            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18535            for (int j = 0; j < activitiesSize; j++) {
18536                final ActivityRecord r = app.activities.get(j);
18537                if (r.app != app) {
18538                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18539                            + " instead of expected " + app);
18540                    if (r.app == null || (r.app.uid == app.uid)) {
18541                        // Only fix things up when they look sane
18542                        r.app = app;
18543                    } else {
18544                        continue;
18545                    }
18546                }
18547                if (r.visible) {
18548                    // App has a visible activity; only upgrade adjustment.
18549                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18550                        adj = ProcessList.VISIBLE_APP_ADJ;
18551                        app.adjType = "visible";
18552                    }
18553                    if (procState > PROCESS_STATE_CUR_TOP) {
18554                        procState = PROCESS_STATE_CUR_TOP;
18555                    }
18556                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18557                    app.cached = false;
18558                    app.empty = false;
18559                    foregroundActivities = true;
18560                    if (r.task != null && minLayer > 0) {
18561                        final int layer = r.task.mLayerRank;
18562                        if (layer >= 0 && minLayer > layer) {
18563                            minLayer = layer;
18564                        }
18565                    }
18566                    break;
18567                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18568                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18569                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18570                        app.adjType = "pausing";
18571                    }
18572                    if (procState > PROCESS_STATE_CUR_TOP) {
18573                        procState = PROCESS_STATE_CUR_TOP;
18574                    }
18575                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18576                    app.cached = false;
18577                    app.empty = false;
18578                    foregroundActivities = true;
18579                } else if (r.state == ActivityState.STOPPING) {
18580                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18581                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18582                        app.adjType = "stopping";
18583                    }
18584                    // For the process state, we will at this point consider the
18585                    // process to be cached.  It will be cached either as an activity
18586                    // or empty depending on whether the activity is finishing.  We do
18587                    // this so that we can treat the process as cached for purposes of
18588                    // memory trimming (determing current memory level, trim command to
18589                    // send to process) since there can be an arbitrary number of stopping
18590                    // processes and they should soon all go into the cached state.
18591                    if (!r.finishing) {
18592                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18593                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18594                        }
18595                    }
18596                    app.cached = false;
18597                    app.empty = false;
18598                    foregroundActivities = true;
18599                } else {
18600                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18601                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18602                        app.adjType = "cch-act";
18603                    }
18604                }
18605            }
18606            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18607                adj += minLayer;
18608            }
18609        }
18610
18611        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18612                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18613            if (app.foregroundServices) {
18614                // The user is aware of this app, so make it visible.
18615                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18616                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18617                app.cached = false;
18618                app.adjType = "fg-service";
18619                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18620            } else if (app.forcingToForeground != null) {
18621                // The user is aware of this app, so make it visible.
18622                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18623                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18624                app.cached = false;
18625                app.adjType = "force-fg";
18626                app.adjSource = app.forcingToForeground;
18627                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18628            }
18629        }
18630
18631        if (app == mHeavyWeightProcess) {
18632            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18633                // We don't want to kill the current heavy-weight process.
18634                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18635                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18636                app.cached = false;
18637                app.adjType = "heavy";
18638            }
18639            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18640                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18641            }
18642        }
18643
18644        if (app == mHomeProcess) {
18645            if (adj > ProcessList.HOME_APP_ADJ) {
18646                // This process is hosting what we currently consider to be the
18647                // home app, so we don't want to let it go into the background.
18648                adj = ProcessList.HOME_APP_ADJ;
18649                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18650                app.cached = false;
18651                app.adjType = "home";
18652            }
18653            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18654                procState = ActivityManager.PROCESS_STATE_HOME;
18655            }
18656        }
18657
18658        if (app == mPreviousProcess && app.activities.size() > 0) {
18659            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18660                // This was the previous process that showed UI to the user.
18661                // We want to try to keep it around more aggressively, to give
18662                // a good experience around switching between two apps.
18663                adj = ProcessList.PREVIOUS_APP_ADJ;
18664                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18665                app.cached = false;
18666                app.adjType = "previous";
18667            }
18668            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18669                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18670            }
18671        }
18672
18673        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18674                + " reason=" + app.adjType);
18675
18676        // By default, we use the computed adjustment.  It may be changed if
18677        // there are applications dependent on our services or providers, but
18678        // this gives us a baseline and makes sure we don't get into an
18679        // infinite recursion.
18680        app.adjSeq = mAdjSeq;
18681        app.curRawAdj = adj;
18682        app.hasStartedServices = false;
18683
18684        if (mBackupTarget != null && app == mBackupTarget.app) {
18685            // If possible we want to avoid killing apps while they're being backed up
18686            if (adj > ProcessList.BACKUP_APP_ADJ) {
18687                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18688                adj = ProcessList.BACKUP_APP_ADJ;
18689                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18690                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18691                }
18692                app.adjType = "backup";
18693                app.cached = false;
18694            }
18695            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18696                procState = ActivityManager.PROCESS_STATE_BACKUP;
18697            }
18698        }
18699
18700        boolean mayBeTop = false;
18701
18702        for (int is = app.services.size()-1;
18703                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18704                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18705                        || procState > ActivityManager.PROCESS_STATE_TOP);
18706                is--) {
18707            ServiceRecord s = app.services.valueAt(is);
18708            if (s.startRequested) {
18709                app.hasStartedServices = true;
18710                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18711                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18712                }
18713                if (app.hasShownUi && app != mHomeProcess) {
18714                    // If this process has shown some UI, let it immediately
18715                    // go to the LRU list because it may be pretty heavy with
18716                    // UI stuff.  We'll tag it with a label just to help
18717                    // debug and understand what is going on.
18718                    if (adj > ProcessList.SERVICE_ADJ) {
18719                        app.adjType = "cch-started-ui-services";
18720                    }
18721                } else {
18722                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18723                        // This service has seen some activity within
18724                        // recent memory, so we will keep its process ahead
18725                        // of the background processes.
18726                        if (adj > ProcessList.SERVICE_ADJ) {
18727                            adj = ProcessList.SERVICE_ADJ;
18728                            app.adjType = "started-services";
18729                            app.cached = false;
18730                        }
18731                    }
18732                    // If we have let the service slide into the background
18733                    // state, still have some text describing what it is doing
18734                    // even though the service no longer has an impact.
18735                    if (adj > ProcessList.SERVICE_ADJ) {
18736                        app.adjType = "cch-started-services";
18737                    }
18738                }
18739            }
18740            for (int conni = s.connections.size()-1;
18741                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18742                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18743                            || procState > ActivityManager.PROCESS_STATE_TOP);
18744                    conni--) {
18745                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18746                for (int i = 0;
18747                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18748                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18749                                || procState > ActivityManager.PROCESS_STATE_TOP);
18750                        i++) {
18751                    // XXX should compute this based on the max of
18752                    // all connected clients.
18753                    ConnectionRecord cr = clist.get(i);
18754                    if (cr.binding.client == app) {
18755                        // Binding to ourself is not interesting.
18756                        continue;
18757                    }
18758                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18759                        ProcessRecord client = cr.binding.client;
18760                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18761                                TOP_APP, doingAll, now);
18762                        int clientProcState = client.curProcState;
18763                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18764                            // If the other app is cached for any reason, for purposes here
18765                            // we are going to consider it empty.  The specific cached state
18766                            // doesn't propagate except under certain conditions.
18767                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18768                        }
18769                        String adjType = null;
18770                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18771                            // Not doing bind OOM management, so treat
18772                            // this guy more like a started service.
18773                            if (app.hasShownUi && app != mHomeProcess) {
18774                                // If this process has shown some UI, let it immediately
18775                                // go to the LRU list because it may be pretty heavy with
18776                                // UI stuff.  We'll tag it with a label just to help
18777                                // debug and understand what is going on.
18778                                if (adj > clientAdj) {
18779                                    adjType = "cch-bound-ui-services";
18780                                }
18781                                app.cached = false;
18782                                clientAdj = adj;
18783                                clientProcState = procState;
18784                            } else {
18785                                if (now >= (s.lastActivity
18786                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18787                                    // This service has not seen activity within
18788                                    // recent memory, so allow it to drop to the
18789                                    // LRU list if there is no other reason to keep
18790                                    // it around.  We'll also tag it with a label just
18791                                    // to help debug and undertand what is going on.
18792                                    if (adj > clientAdj) {
18793                                        adjType = "cch-bound-services";
18794                                    }
18795                                    clientAdj = adj;
18796                                }
18797                            }
18798                        }
18799                        if (adj > clientAdj) {
18800                            // If this process has recently shown UI, and
18801                            // the process that is binding to it is less
18802                            // important than being visible, then we don't
18803                            // care about the binding as much as we care
18804                            // about letting this process get into the LRU
18805                            // list to be killed and restarted if needed for
18806                            // memory.
18807                            if (app.hasShownUi && app != mHomeProcess
18808                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18809                                adjType = "cch-bound-ui-services";
18810                            } else {
18811                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18812                                        |Context.BIND_IMPORTANT)) != 0) {
18813                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18814                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18815                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18816                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18817                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18818                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18819                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18820                                    adj = clientAdj;
18821                                } else {
18822                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18823                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18824                                    }
18825                                }
18826                                if (!client.cached) {
18827                                    app.cached = false;
18828                                }
18829                                adjType = "service";
18830                            }
18831                        }
18832                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18833                            // This will treat important bound services identically to
18834                            // the top app, which may behave differently than generic
18835                            // foreground work.
18836                            if (client.curSchedGroup > schedGroup) {
18837                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18838                                    schedGroup = client.curSchedGroup;
18839                                } else {
18840                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18841                                }
18842                            }
18843                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18844                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18845                                    // Special handling of clients who are in the top state.
18846                                    // We *may* want to consider this process to be in the
18847                                    // top state as well, but only if there is not another
18848                                    // reason for it to be running.  Being on the top is a
18849                                    // special state, meaning you are specifically running
18850                                    // for the current top app.  If the process is already
18851                                    // running in the background for some other reason, it
18852                                    // is more important to continue considering it to be
18853                                    // in the background state.
18854                                    mayBeTop = true;
18855                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18856                                } else {
18857                                    // Special handling for above-top states (persistent
18858                                    // processes).  These should not bring the current process
18859                                    // into the top state, since they are not on top.  Instead
18860                                    // give them the best state after that.
18861                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18862                                        clientProcState =
18863                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18864                                    } else if (mWakefulness
18865                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18866                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18867                                                    != 0) {
18868                                        clientProcState =
18869                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18870                                    } else {
18871                                        clientProcState =
18872                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18873                                    }
18874                                }
18875                            }
18876                        } else {
18877                            if (clientProcState <
18878                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18879                                clientProcState =
18880                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18881                            }
18882                        }
18883                        if (procState > clientProcState) {
18884                            procState = clientProcState;
18885                        }
18886                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18887                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18888                            app.pendingUiClean = true;
18889                        }
18890                        if (adjType != null) {
18891                            app.adjType = adjType;
18892                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18893                                    .REASON_SERVICE_IN_USE;
18894                            app.adjSource = cr.binding.client;
18895                            app.adjSourceProcState = clientProcState;
18896                            app.adjTarget = s.name;
18897                        }
18898                    }
18899                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18900                        app.treatLikeActivity = true;
18901                    }
18902                    final ActivityRecord a = cr.activity;
18903                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18904                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18905                            (a.visible || a.state == ActivityState.RESUMED ||
18906                             a.state == ActivityState.PAUSING)) {
18907                            adj = ProcessList.FOREGROUND_APP_ADJ;
18908                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18909                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18910                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18911                                } else {
18912                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18913                                }
18914                            }
18915                            app.cached = false;
18916                            app.adjType = "service";
18917                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18918                                    .REASON_SERVICE_IN_USE;
18919                            app.adjSource = a;
18920                            app.adjSourceProcState = procState;
18921                            app.adjTarget = s.name;
18922                        }
18923                    }
18924                }
18925            }
18926        }
18927
18928        for (int provi = app.pubProviders.size()-1;
18929                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18930                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18931                        || procState > ActivityManager.PROCESS_STATE_TOP);
18932                provi--) {
18933            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18934            for (int i = cpr.connections.size()-1;
18935                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18936                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18937                            || procState > ActivityManager.PROCESS_STATE_TOP);
18938                    i--) {
18939                ContentProviderConnection conn = cpr.connections.get(i);
18940                ProcessRecord client = conn.client;
18941                if (client == app) {
18942                    // Being our own client is not interesting.
18943                    continue;
18944                }
18945                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18946                int clientProcState = client.curProcState;
18947                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18948                    // If the other app is cached for any reason, for purposes here
18949                    // we are going to consider it empty.
18950                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18951                }
18952                if (adj > clientAdj) {
18953                    if (app.hasShownUi && app != mHomeProcess
18954                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18955                        app.adjType = "cch-ui-provider";
18956                    } else {
18957                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18958                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18959                        app.adjType = "provider";
18960                    }
18961                    app.cached &= client.cached;
18962                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18963                            .REASON_PROVIDER_IN_USE;
18964                    app.adjSource = client;
18965                    app.adjSourceProcState = clientProcState;
18966                    app.adjTarget = cpr.name;
18967                }
18968                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18969                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18970                        // Special handling of clients who are in the top state.
18971                        // We *may* want to consider this process to be in the
18972                        // top state as well, but only if there is not another
18973                        // reason for it to be running.  Being on the top is a
18974                        // special state, meaning you are specifically running
18975                        // for the current top app.  If the process is already
18976                        // running in the background for some other reason, it
18977                        // is more important to continue considering it to be
18978                        // in the background state.
18979                        mayBeTop = true;
18980                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18981                    } else {
18982                        // Special handling for above-top states (persistent
18983                        // processes).  These should not bring the current process
18984                        // into the top state, since they are not on top.  Instead
18985                        // give them the best state after that.
18986                        clientProcState =
18987                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18988                    }
18989                }
18990                if (procState > clientProcState) {
18991                    procState = clientProcState;
18992                }
18993                if (client.curSchedGroup > schedGroup) {
18994                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18995                }
18996            }
18997            // If the provider has external (non-framework) process
18998            // dependencies, ensure that its adjustment is at least
18999            // FOREGROUND_APP_ADJ.
19000            if (cpr.hasExternalProcessHandles()) {
19001                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19002                    adj = ProcessList.FOREGROUND_APP_ADJ;
19003                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19004                    app.cached = false;
19005                    app.adjType = "provider";
19006                    app.adjTarget = cpr.name;
19007                }
19008                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19009                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19010                }
19011            }
19012        }
19013
19014        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19015            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19016                adj = ProcessList.PREVIOUS_APP_ADJ;
19017                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19018                app.cached = false;
19019                app.adjType = "provider";
19020            }
19021            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19022                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19023            }
19024        }
19025
19026        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19027            // A client of one of our services or providers is in the top state.  We
19028            // *may* want to be in the top state, but not if we are already running in
19029            // the background for some other reason.  For the decision here, we are going
19030            // to pick out a few specific states that we want to remain in when a client
19031            // is top (states that tend to be longer-term) and otherwise allow it to go
19032            // to the top state.
19033            switch (procState) {
19034                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19035                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19036                case ActivityManager.PROCESS_STATE_SERVICE:
19037                    // These all are longer-term states, so pull them up to the top
19038                    // of the background states, but not all the way to the top state.
19039                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19040                    break;
19041                default:
19042                    // Otherwise, top is a better choice, so take it.
19043                    procState = ActivityManager.PROCESS_STATE_TOP;
19044                    break;
19045            }
19046        }
19047
19048        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19049            if (app.hasClientActivities) {
19050                // This is a cached process, but with client activities.  Mark it so.
19051                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19052                app.adjType = "cch-client-act";
19053            } else if (app.treatLikeActivity) {
19054                // This is a cached process, but somebody wants us to treat it like it has
19055                // an activity, okay!
19056                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19057                app.adjType = "cch-as-act";
19058            }
19059        }
19060
19061        if (adj == ProcessList.SERVICE_ADJ) {
19062            if (doingAll) {
19063                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19064                mNewNumServiceProcs++;
19065                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19066                if (!app.serviceb) {
19067                    // This service isn't far enough down on the LRU list to
19068                    // normally be a B service, but if we are low on RAM and it
19069                    // is large we want to force it down since we would prefer to
19070                    // keep launcher over it.
19071                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19072                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19073                        app.serviceHighRam = true;
19074                        app.serviceb = true;
19075                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19076                    } else {
19077                        mNewNumAServiceProcs++;
19078                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19079                    }
19080                } else {
19081                    app.serviceHighRam = false;
19082                }
19083            }
19084            if (app.serviceb) {
19085                adj = ProcessList.SERVICE_B_ADJ;
19086            }
19087        }
19088
19089        app.curRawAdj = adj;
19090
19091        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19092        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19093        if (adj > app.maxAdj) {
19094            adj = app.maxAdj;
19095            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19096                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19097            }
19098        }
19099
19100        // Do final modification to adj.  Everything we do between here and applying
19101        // the final setAdj must be done in this function, because we will also use
19102        // it when computing the final cached adj later.  Note that we don't need to
19103        // worry about this for max adj above, since max adj will always be used to
19104        // keep it out of the cached vaues.
19105        app.curAdj = app.modifyRawOomAdj(adj);
19106        app.curSchedGroup = schedGroup;
19107        app.curProcState = procState;
19108        app.foregroundActivities = foregroundActivities;
19109
19110        return app.curRawAdj;
19111    }
19112
19113    /**
19114     * Record new PSS sample for a process.
19115     */
19116    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19117            long now) {
19118        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19119                swapPss * 1024);
19120        proc.lastPssTime = now;
19121        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19122        if (DEBUG_PSS) Slog.d(TAG_PSS,
19123                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19124                + " state=" + ProcessList.makeProcStateString(procState));
19125        if (proc.initialIdlePss == 0) {
19126            proc.initialIdlePss = pss;
19127        }
19128        proc.lastPss = pss;
19129        proc.lastSwapPss = swapPss;
19130        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19131            proc.lastCachedPss = pss;
19132            proc.lastCachedSwapPss = swapPss;
19133        }
19134
19135        final SparseArray<Pair<Long, String>> watchUids
19136                = mMemWatchProcesses.getMap().get(proc.processName);
19137        Long check = null;
19138        if (watchUids != null) {
19139            Pair<Long, String> val = watchUids.get(proc.uid);
19140            if (val == null) {
19141                val = watchUids.get(0);
19142            }
19143            if (val != null) {
19144                check = val.first;
19145            }
19146        }
19147        if (check != null) {
19148            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19149                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19150                if (!isDebuggable) {
19151                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19152                        isDebuggable = true;
19153                    }
19154                }
19155                if (isDebuggable) {
19156                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19157                    final ProcessRecord myProc = proc;
19158                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19159                    mMemWatchDumpProcName = proc.processName;
19160                    mMemWatchDumpFile = heapdumpFile.toString();
19161                    mMemWatchDumpPid = proc.pid;
19162                    mMemWatchDumpUid = proc.uid;
19163                    BackgroundThread.getHandler().post(new Runnable() {
19164                        @Override
19165                        public void run() {
19166                            revokeUriPermission(ActivityThread.currentActivityThread()
19167                                            .getApplicationThread(),
19168                                    DumpHeapActivity.JAVA_URI,
19169                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19170                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19171                                    UserHandle.myUserId());
19172                            ParcelFileDescriptor fd = null;
19173                            try {
19174                                heapdumpFile.delete();
19175                                fd = ParcelFileDescriptor.open(heapdumpFile,
19176                                        ParcelFileDescriptor.MODE_CREATE |
19177                                                ParcelFileDescriptor.MODE_TRUNCATE |
19178                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19179                                                ParcelFileDescriptor.MODE_APPEND);
19180                                IApplicationThread thread = myProc.thread;
19181                                if (thread != null) {
19182                                    try {
19183                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19184                                                "Requesting dump heap from "
19185                                                + myProc + " to " + heapdumpFile);
19186                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19187                                    } catch (RemoteException e) {
19188                                    }
19189                                }
19190                            } catch (FileNotFoundException e) {
19191                                e.printStackTrace();
19192                            } finally {
19193                                if (fd != null) {
19194                                    try {
19195                                        fd.close();
19196                                    } catch (IOException e) {
19197                                    }
19198                                }
19199                            }
19200                        }
19201                    });
19202                } else {
19203                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19204                            + ", but debugging not enabled");
19205                }
19206            }
19207        }
19208    }
19209
19210    /**
19211     * Schedule PSS collection of a process.
19212     */
19213    void requestPssLocked(ProcessRecord proc, int procState) {
19214        if (mPendingPssProcesses.contains(proc)) {
19215            return;
19216        }
19217        if (mPendingPssProcesses.size() == 0) {
19218            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19219        }
19220        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19221        proc.pssProcState = procState;
19222        mPendingPssProcesses.add(proc);
19223    }
19224
19225    /**
19226     * Schedule PSS collection of all processes.
19227     */
19228    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19229        if (!always) {
19230            if (now < (mLastFullPssTime +
19231                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19232                return;
19233            }
19234        }
19235        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19236        mLastFullPssTime = now;
19237        mFullPssPending = true;
19238        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19239        mPendingPssProcesses.clear();
19240        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19241            ProcessRecord app = mLruProcesses.get(i);
19242            if (app.thread == null
19243                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19244                continue;
19245            }
19246            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19247                app.pssProcState = app.setProcState;
19248                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19249                        mTestPssMode, isSleeping(), now);
19250                mPendingPssProcesses.add(app);
19251            }
19252        }
19253        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19254    }
19255
19256    public void setTestPssMode(boolean enabled) {
19257        synchronized (this) {
19258            mTestPssMode = enabled;
19259            if (enabled) {
19260                // Whenever we enable the mode, we want to take a snapshot all of current
19261                // process mem use.
19262                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19263            }
19264        }
19265    }
19266
19267    /**
19268     * Ask a given process to GC right now.
19269     */
19270    final void performAppGcLocked(ProcessRecord app) {
19271        try {
19272            app.lastRequestedGc = SystemClock.uptimeMillis();
19273            if (app.thread != null) {
19274                if (app.reportLowMemory) {
19275                    app.reportLowMemory = false;
19276                    app.thread.scheduleLowMemory();
19277                } else {
19278                    app.thread.processInBackground();
19279                }
19280            }
19281        } catch (Exception e) {
19282            // whatever.
19283        }
19284    }
19285
19286    /**
19287     * Returns true if things are idle enough to perform GCs.
19288     */
19289    private final boolean canGcNowLocked() {
19290        boolean processingBroadcasts = false;
19291        for (BroadcastQueue q : mBroadcastQueues) {
19292            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19293                processingBroadcasts = true;
19294            }
19295        }
19296        return !processingBroadcasts
19297                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19298    }
19299
19300    /**
19301     * Perform GCs on all processes that are waiting for it, but only
19302     * if things are idle.
19303     */
19304    final void performAppGcsLocked() {
19305        final int N = mProcessesToGc.size();
19306        if (N <= 0) {
19307            return;
19308        }
19309        if (canGcNowLocked()) {
19310            while (mProcessesToGc.size() > 0) {
19311                ProcessRecord proc = mProcessesToGc.remove(0);
19312                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19313                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19314                            <= SystemClock.uptimeMillis()) {
19315                        // To avoid spamming the system, we will GC processes one
19316                        // at a time, waiting a few seconds between each.
19317                        performAppGcLocked(proc);
19318                        scheduleAppGcsLocked();
19319                        return;
19320                    } else {
19321                        // It hasn't been long enough since we last GCed this
19322                        // process...  put it in the list to wait for its time.
19323                        addProcessToGcListLocked(proc);
19324                        break;
19325                    }
19326                }
19327            }
19328
19329            scheduleAppGcsLocked();
19330        }
19331    }
19332
19333    /**
19334     * If all looks good, perform GCs on all processes waiting for them.
19335     */
19336    final void performAppGcsIfAppropriateLocked() {
19337        if (canGcNowLocked()) {
19338            performAppGcsLocked();
19339            return;
19340        }
19341        // Still not idle, wait some more.
19342        scheduleAppGcsLocked();
19343    }
19344
19345    /**
19346     * Schedule the execution of all pending app GCs.
19347     */
19348    final void scheduleAppGcsLocked() {
19349        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19350
19351        if (mProcessesToGc.size() > 0) {
19352            // Schedule a GC for the time to the next process.
19353            ProcessRecord proc = mProcessesToGc.get(0);
19354            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19355
19356            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19357            long now = SystemClock.uptimeMillis();
19358            if (when < (now+GC_TIMEOUT)) {
19359                when = now + GC_TIMEOUT;
19360            }
19361            mHandler.sendMessageAtTime(msg, when);
19362        }
19363    }
19364
19365    /**
19366     * Add a process to the array of processes waiting to be GCed.  Keeps the
19367     * list in sorted order by the last GC time.  The process can't already be
19368     * on the list.
19369     */
19370    final void addProcessToGcListLocked(ProcessRecord proc) {
19371        boolean added = false;
19372        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19373            if (mProcessesToGc.get(i).lastRequestedGc <
19374                    proc.lastRequestedGc) {
19375                added = true;
19376                mProcessesToGc.add(i+1, proc);
19377                break;
19378            }
19379        }
19380        if (!added) {
19381            mProcessesToGc.add(0, proc);
19382        }
19383    }
19384
19385    /**
19386     * Set up to ask a process to GC itself.  This will either do it
19387     * immediately, or put it on the list of processes to gc the next
19388     * time things are idle.
19389     */
19390    final void scheduleAppGcLocked(ProcessRecord app) {
19391        long now = SystemClock.uptimeMillis();
19392        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19393            return;
19394        }
19395        if (!mProcessesToGc.contains(app)) {
19396            addProcessToGcListLocked(app);
19397            scheduleAppGcsLocked();
19398        }
19399    }
19400
19401    final void checkExcessivePowerUsageLocked(boolean doKills) {
19402        updateCpuStatsNow();
19403
19404        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19405        boolean doWakeKills = doKills;
19406        boolean doCpuKills = doKills;
19407        if (mLastPowerCheckRealtime == 0) {
19408            doWakeKills = false;
19409        }
19410        if (mLastPowerCheckUptime == 0) {
19411            doCpuKills = false;
19412        }
19413        if (stats.isScreenOn()) {
19414            doWakeKills = false;
19415        }
19416        final long curRealtime = SystemClock.elapsedRealtime();
19417        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19418        final long curUptime = SystemClock.uptimeMillis();
19419        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19420        mLastPowerCheckRealtime = curRealtime;
19421        mLastPowerCheckUptime = curUptime;
19422        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19423            doWakeKills = false;
19424        }
19425        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19426            doCpuKills = false;
19427        }
19428        int i = mLruProcesses.size();
19429        while (i > 0) {
19430            i--;
19431            ProcessRecord app = mLruProcesses.get(i);
19432            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19433                long wtime;
19434                synchronized (stats) {
19435                    wtime = stats.getProcessWakeTime(app.info.uid,
19436                            app.pid, curRealtime);
19437                }
19438                long wtimeUsed = wtime - app.lastWakeTime;
19439                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19440                if (DEBUG_POWER) {
19441                    StringBuilder sb = new StringBuilder(128);
19442                    sb.append("Wake for ");
19443                    app.toShortString(sb);
19444                    sb.append(": over ");
19445                    TimeUtils.formatDuration(realtimeSince, sb);
19446                    sb.append(" used ");
19447                    TimeUtils.formatDuration(wtimeUsed, sb);
19448                    sb.append(" (");
19449                    sb.append((wtimeUsed*100)/realtimeSince);
19450                    sb.append("%)");
19451                    Slog.i(TAG_POWER, sb.toString());
19452                    sb.setLength(0);
19453                    sb.append("CPU for ");
19454                    app.toShortString(sb);
19455                    sb.append(": over ");
19456                    TimeUtils.formatDuration(uptimeSince, sb);
19457                    sb.append(" used ");
19458                    TimeUtils.formatDuration(cputimeUsed, sb);
19459                    sb.append(" (");
19460                    sb.append((cputimeUsed*100)/uptimeSince);
19461                    sb.append("%)");
19462                    Slog.i(TAG_POWER, sb.toString());
19463                }
19464                // If a process has held a wake lock for more
19465                // than 50% of the time during this period,
19466                // that sounds bad.  Kill!
19467                if (doWakeKills && realtimeSince > 0
19468                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19469                    synchronized (stats) {
19470                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19471                                realtimeSince, wtimeUsed);
19472                    }
19473                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19474                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19475                } else if (doCpuKills && uptimeSince > 0
19476                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19477                    synchronized (stats) {
19478                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19479                                uptimeSince, cputimeUsed);
19480                    }
19481                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19482                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19483                } else {
19484                    app.lastWakeTime = wtime;
19485                    app.lastCpuTime = app.curCpuTime;
19486                }
19487            }
19488        }
19489    }
19490
19491    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19492            long nowElapsed) {
19493        boolean success = true;
19494
19495        if (app.curRawAdj != app.setRawAdj) {
19496            app.setRawAdj = app.curRawAdj;
19497        }
19498
19499        int changes = 0;
19500
19501        if (app.curAdj != app.setAdj) {
19502            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19503            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19504                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19505                    + app.adjType);
19506            app.setAdj = app.curAdj;
19507        }
19508
19509        if (app.setSchedGroup != app.curSchedGroup) {
19510            app.setSchedGroup = app.curSchedGroup;
19511            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19512                    "Setting sched group of " + app.processName
19513                    + " to " + app.curSchedGroup);
19514            if (app.waitingToKill != null && app.curReceiver == null
19515                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19516                app.kill(app.waitingToKill, true);
19517                success = false;
19518            } else {
19519                int processGroup;
19520                switch (app.curSchedGroup) {
19521                    case ProcessList.SCHED_GROUP_BACKGROUND:
19522                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19523                        break;
19524                    case ProcessList.SCHED_GROUP_TOP_APP:
19525                        processGroup = Process.THREAD_GROUP_TOP_APP;
19526                        break;
19527                    default:
19528                        processGroup = Process.THREAD_GROUP_DEFAULT;
19529                        break;
19530                }
19531                if (true) {
19532                    long oldId = Binder.clearCallingIdentity();
19533                    try {
19534                        Process.setProcessGroup(app.pid, processGroup);
19535                    } catch (Exception e) {
19536                        Slog.w(TAG, "Failed setting process group of " + app.pid
19537                                + " to " + app.curSchedGroup);
19538                        e.printStackTrace();
19539                    } finally {
19540                        Binder.restoreCallingIdentity(oldId);
19541                    }
19542                } else {
19543                    if (app.thread != null) {
19544                        try {
19545                            app.thread.setSchedulingGroup(processGroup);
19546                        } catch (RemoteException e) {
19547                        }
19548                    }
19549                }
19550            }
19551        }
19552        if (app.repForegroundActivities != app.foregroundActivities) {
19553            app.repForegroundActivities = app.foregroundActivities;
19554            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19555        }
19556        if (app.repProcState != app.curProcState) {
19557            app.repProcState = app.curProcState;
19558            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19559            if (app.thread != null) {
19560                try {
19561                    if (false) {
19562                        //RuntimeException h = new RuntimeException("here");
19563                        Slog.i(TAG, "Sending new process state " + app.repProcState
19564                                + " to " + app /*, h*/);
19565                    }
19566                    app.thread.setProcessState(app.repProcState);
19567                } catch (RemoteException e) {
19568                }
19569            }
19570        }
19571        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19572                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19573            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19574                // Experimental code to more aggressively collect pss while
19575                // running test...  the problem is that this tends to collect
19576                // the data right when a process is transitioning between process
19577                // states, which well tend to give noisy data.
19578                long start = SystemClock.uptimeMillis();
19579                long pss = Debug.getPss(app.pid, mTmpLong, null);
19580                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19581                mPendingPssProcesses.remove(app);
19582                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19583                        + " to " + app.curProcState + ": "
19584                        + (SystemClock.uptimeMillis()-start) + "ms");
19585            }
19586            app.lastStateTime = now;
19587            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19588                    mTestPssMode, isSleeping(), now);
19589            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19590                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19591                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19592                    + (app.nextPssTime-now) + ": " + app);
19593        } else {
19594            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19595                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19596                    mTestPssMode)))) {
19597                requestPssLocked(app, app.setProcState);
19598                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19599                        mTestPssMode, isSleeping(), now);
19600            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19601                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19602        }
19603        if (app.setProcState != app.curProcState) {
19604            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19605                    "Proc state change of " + app.processName
19606                            + " to " + app.curProcState);
19607            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19608            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19609            if (setImportant && !curImportant) {
19610                // This app is no longer something we consider important enough to allow to
19611                // use arbitrary amounts of battery power.  Note
19612                // its current wake lock time to later know to kill it if
19613                // it is not behaving well.
19614                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19615                synchronized (stats) {
19616                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19617                            app.pid, nowElapsed);
19618                }
19619                app.lastCpuTime = app.curCpuTime;
19620
19621            }
19622            // Inform UsageStats of important process state change
19623            // Must be called before updating setProcState
19624            maybeUpdateUsageStatsLocked(app, nowElapsed);
19625
19626            app.setProcState = app.curProcState;
19627            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19628                app.notCachedSinceIdle = false;
19629            }
19630            if (!doingAll) {
19631                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19632            } else {
19633                app.procStateChanged = true;
19634            }
19635        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19636                > USAGE_STATS_INTERACTION_INTERVAL) {
19637            // For apps that sit around for a long time in the interactive state, we need
19638            // to report this at least once a day so they don't go idle.
19639            maybeUpdateUsageStatsLocked(app, nowElapsed);
19640        }
19641
19642        if (changes != 0) {
19643            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19644                    "Changes in " + app + ": " + changes);
19645            int i = mPendingProcessChanges.size()-1;
19646            ProcessChangeItem item = null;
19647            while (i >= 0) {
19648                item = mPendingProcessChanges.get(i);
19649                if (item.pid == app.pid) {
19650                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19651                            "Re-using existing item: " + item);
19652                    break;
19653                }
19654                i--;
19655            }
19656            if (i < 0) {
19657                // No existing item in pending changes; need a new one.
19658                final int NA = mAvailProcessChanges.size();
19659                if (NA > 0) {
19660                    item = mAvailProcessChanges.remove(NA-1);
19661                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19662                            "Retrieving available item: " + item);
19663                } else {
19664                    item = new ProcessChangeItem();
19665                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19666                            "Allocating new item: " + item);
19667                }
19668                item.changes = 0;
19669                item.pid = app.pid;
19670                item.uid = app.info.uid;
19671                if (mPendingProcessChanges.size() == 0) {
19672                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19673                            "*** Enqueueing dispatch processes changed!");
19674                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19675                }
19676                mPendingProcessChanges.add(item);
19677            }
19678            item.changes |= changes;
19679            item.processState = app.repProcState;
19680            item.foregroundActivities = app.repForegroundActivities;
19681            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19682                    "Item " + Integer.toHexString(System.identityHashCode(item))
19683                    + " " + app.toShortString() + ": changes=" + item.changes
19684                    + " procState=" + item.processState
19685                    + " foreground=" + item.foregroundActivities
19686                    + " type=" + app.adjType + " source=" + app.adjSource
19687                    + " target=" + app.adjTarget);
19688        }
19689
19690        return success;
19691    }
19692
19693    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19694        final UidRecord.ChangeItem pendingChange;
19695        if (uidRec == null || uidRec.pendingChange == null) {
19696            if (mPendingUidChanges.size() == 0) {
19697                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19698                        "*** Enqueueing dispatch uid changed!");
19699                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19700            }
19701            final int NA = mAvailUidChanges.size();
19702            if (NA > 0) {
19703                pendingChange = mAvailUidChanges.remove(NA-1);
19704                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19705                        "Retrieving available item: " + pendingChange);
19706            } else {
19707                pendingChange = new UidRecord.ChangeItem();
19708                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19709                        "Allocating new item: " + pendingChange);
19710            }
19711            if (uidRec != null) {
19712                uidRec.pendingChange = pendingChange;
19713                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19714                    // If this uid is going away, and we haven't yet reported it is gone,
19715                    // then do so now.
19716                    change = UidRecord.CHANGE_GONE_IDLE;
19717                }
19718            } else if (uid < 0) {
19719                throw new IllegalArgumentException("No UidRecord or uid");
19720            }
19721            pendingChange.uidRecord = uidRec;
19722            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19723            mPendingUidChanges.add(pendingChange);
19724        } else {
19725            pendingChange = uidRec.pendingChange;
19726            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19727                change = UidRecord.CHANGE_GONE_IDLE;
19728            }
19729        }
19730        pendingChange.change = change;
19731        pendingChange.processState = uidRec != null
19732                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19733    }
19734
19735    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19736            String authority) {
19737        if (app == null) return;
19738        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19739            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19740            if (userState == null) return;
19741            final long now = SystemClock.elapsedRealtime();
19742            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19743            if (lastReported == null || lastReported < now - 60 * 1000L) {
19744                mUsageStatsService.reportContentProviderUsage(
19745                        authority, providerPkgName, app.userId);
19746                userState.mProviderLastReportedFg.put(authority, now);
19747            }
19748        }
19749    }
19750
19751    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19752        if (DEBUG_USAGE_STATS) {
19753            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19754                    + "] state changes: old = " + app.setProcState + ", new = "
19755                    + app.curProcState);
19756        }
19757        if (mUsageStatsService == null) {
19758            return;
19759        }
19760        boolean isInteraction;
19761        // To avoid some abuse patterns, we are going to be careful about what we consider
19762        // to be an app interaction.  Being the top activity doesn't count while the display
19763        // is sleeping, nor do short foreground services.
19764        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19765            isInteraction = true;
19766            app.fgInteractionTime = 0;
19767        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19768            if (app.fgInteractionTime == 0) {
19769                app.fgInteractionTime = nowElapsed;
19770                isInteraction = false;
19771            } else {
19772                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19773            }
19774        } else {
19775            isInteraction = app.curProcState
19776                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19777            app.fgInteractionTime = 0;
19778        }
19779        if (isInteraction && (!app.reportedInteraction
19780                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19781            app.interactionEventTime = nowElapsed;
19782            String[] packages = app.getPackageList();
19783            if (packages != null) {
19784                for (int i = 0; i < packages.length; i++) {
19785                    mUsageStatsService.reportEvent(packages[i], app.userId,
19786                            UsageEvents.Event.SYSTEM_INTERACTION);
19787                }
19788            }
19789        }
19790        app.reportedInteraction = isInteraction;
19791        if (!isInteraction) {
19792            app.interactionEventTime = 0;
19793        }
19794    }
19795
19796    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19797        if (proc.thread != null) {
19798            if (proc.baseProcessTracker != null) {
19799                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19800            }
19801        }
19802    }
19803
19804    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19805            ProcessRecord TOP_APP, boolean doingAll, long now) {
19806        if (app.thread == null) {
19807            return false;
19808        }
19809
19810        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19811
19812        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19813    }
19814
19815    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19816            boolean oomAdj) {
19817        if (isForeground != proc.foregroundServices) {
19818            proc.foregroundServices = isForeground;
19819            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19820                    proc.info.uid);
19821            if (isForeground) {
19822                if (curProcs == null) {
19823                    curProcs = new ArrayList<ProcessRecord>();
19824                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19825                }
19826                if (!curProcs.contains(proc)) {
19827                    curProcs.add(proc);
19828                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19829                            proc.info.packageName, proc.info.uid);
19830                }
19831            } else {
19832                if (curProcs != null) {
19833                    if (curProcs.remove(proc)) {
19834                        mBatteryStatsService.noteEvent(
19835                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19836                                proc.info.packageName, proc.info.uid);
19837                        if (curProcs.size() <= 0) {
19838                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19839                        }
19840                    }
19841                }
19842            }
19843            if (oomAdj) {
19844                updateOomAdjLocked();
19845            }
19846        }
19847    }
19848
19849    private final ActivityRecord resumedAppLocked() {
19850        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19851        String pkg;
19852        int uid;
19853        if (act != null) {
19854            pkg = act.packageName;
19855            uid = act.info.applicationInfo.uid;
19856        } else {
19857            pkg = null;
19858            uid = -1;
19859        }
19860        // Has the UID or resumed package name changed?
19861        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19862                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19863            if (mCurResumedPackage != null) {
19864                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19865                        mCurResumedPackage, mCurResumedUid);
19866            }
19867            mCurResumedPackage = pkg;
19868            mCurResumedUid = uid;
19869            if (mCurResumedPackage != null) {
19870                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19871                        mCurResumedPackage, mCurResumedUid);
19872            }
19873        }
19874        return act;
19875    }
19876
19877    final boolean updateOomAdjLocked(ProcessRecord app) {
19878        final ActivityRecord TOP_ACT = resumedAppLocked();
19879        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19880        final boolean wasCached = app.cached;
19881
19882        mAdjSeq++;
19883
19884        // This is the desired cached adjusment we want to tell it to use.
19885        // If our app is currently cached, we know it, and that is it.  Otherwise,
19886        // we don't know it yet, and it needs to now be cached we will then
19887        // need to do a complete oom adj.
19888        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19889                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19890        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19891                SystemClock.uptimeMillis());
19892        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19893            // Changed to/from cached state, so apps after it in the LRU
19894            // list may also be changed.
19895            updateOomAdjLocked();
19896        }
19897        return success;
19898    }
19899
19900    final void updateOomAdjLocked() {
19901        final ActivityRecord TOP_ACT = resumedAppLocked();
19902        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19903        final long now = SystemClock.uptimeMillis();
19904        final long nowElapsed = SystemClock.elapsedRealtime();
19905        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19906        final int N = mLruProcesses.size();
19907
19908        if (false) {
19909            RuntimeException e = new RuntimeException();
19910            e.fillInStackTrace();
19911            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19912        }
19913
19914        // Reset state in all uid records.
19915        for (int i=mActiveUids.size()-1; i>=0; i--) {
19916            final UidRecord uidRec = mActiveUids.valueAt(i);
19917            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19918                    "Starting update of " + uidRec);
19919            uidRec.reset();
19920        }
19921
19922        mStackSupervisor.rankTaskLayersIfNeeded();
19923
19924        mAdjSeq++;
19925        mNewNumServiceProcs = 0;
19926        mNewNumAServiceProcs = 0;
19927
19928        final int emptyProcessLimit;
19929        final int cachedProcessLimit;
19930        if (mProcessLimit <= 0) {
19931            emptyProcessLimit = cachedProcessLimit = 0;
19932        } else if (mProcessLimit == 1) {
19933            emptyProcessLimit = 1;
19934            cachedProcessLimit = 0;
19935        } else {
19936            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19937            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19938        }
19939
19940        // Let's determine how many processes we have running vs.
19941        // how many slots we have for background processes; we may want
19942        // to put multiple processes in a slot of there are enough of
19943        // them.
19944        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19945                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19946        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19947        if (numEmptyProcs > cachedProcessLimit) {
19948            // If there are more empty processes than our limit on cached
19949            // processes, then use the cached process limit for the factor.
19950            // This ensures that the really old empty processes get pushed
19951            // down to the bottom, so if we are running low on memory we will
19952            // have a better chance at keeping around more cached processes
19953            // instead of a gazillion empty processes.
19954            numEmptyProcs = cachedProcessLimit;
19955        }
19956        int emptyFactor = numEmptyProcs/numSlots;
19957        if (emptyFactor < 1) emptyFactor = 1;
19958        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19959        if (cachedFactor < 1) cachedFactor = 1;
19960        int stepCached = 0;
19961        int stepEmpty = 0;
19962        int numCached = 0;
19963        int numEmpty = 0;
19964        int numTrimming = 0;
19965
19966        mNumNonCachedProcs = 0;
19967        mNumCachedHiddenProcs = 0;
19968
19969        // First update the OOM adjustment for each of the
19970        // application processes based on their current state.
19971        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19972        int nextCachedAdj = curCachedAdj+1;
19973        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19974        int nextEmptyAdj = curEmptyAdj+2;
19975        for (int i=N-1; i>=0; i--) {
19976            ProcessRecord app = mLruProcesses.get(i);
19977            if (!app.killedByAm && app.thread != null) {
19978                app.procStateChanged = false;
19979                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19980
19981                // If we haven't yet assigned the final cached adj
19982                // to the process, do that now.
19983                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19984                    switch (app.curProcState) {
19985                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19986                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19987                            // This process is a cached process holding activities...
19988                            // assign it the next cached value for that type, and then
19989                            // step that cached level.
19990                            app.curRawAdj = curCachedAdj;
19991                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19992                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19993                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19994                                    + ")");
19995                            if (curCachedAdj != nextCachedAdj) {
19996                                stepCached++;
19997                                if (stepCached >= cachedFactor) {
19998                                    stepCached = 0;
19999                                    curCachedAdj = nextCachedAdj;
20000                                    nextCachedAdj += 2;
20001                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20002                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20003                                    }
20004                                }
20005                            }
20006                            break;
20007                        default:
20008                            // For everything else, assign next empty cached process
20009                            // level and bump that up.  Note that this means that
20010                            // long-running services that have dropped down to the
20011                            // cached level will be treated as empty (since their process
20012                            // state is still as a service), which is what we want.
20013                            app.curRawAdj = curEmptyAdj;
20014                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20015                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20016                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20017                                    + ")");
20018                            if (curEmptyAdj != nextEmptyAdj) {
20019                                stepEmpty++;
20020                                if (stepEmpty >= emptyFactor) {
20021                                    stepEmpty = 0;
20022                                    curEmptyAdj = nextEmptyAdj;
20023                                    nextEmptyAdj += 2;
20024                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20025                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20026                                    }
20027                                }
20028                            }
20029                            break;
20030                    }
20031                }
20032
20033                applyOomAdjLocked(app, true, now, nowElapsed);
20034
20035                // Count the number of process types.
20036                switch (app.curProcState) {
20037                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20038                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20039                        mNumCachedHiddenProcs++;
20040                        numCached++;
20041                        if (numCached > cachedProcessLimit) {
20042                            app.kill("cached #" + numCached, true);
20043                        }
20044                        break;
20045                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20046                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20047                                && app.lastActivityTime < oldTime) {
20048                            app.kill("empty for "
20049                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20050                                    / 1000) + "s", true);
20051                        } else {
20052                            numEmpty++;
20053                            if (numEmpty > emptyProcessLimit) {
20054                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
20055                            }
20056                        }
20057                        break;
20058                    default:
20059                        mNumNonCachedProcs++;
20060                        break;
20061                }
20062
20063                if (app.isolated && app.services.size() <= 0) {
20064                    // If this is an isolated process, and there are no
20065                    // services running in it, then the process is no longer
20066                    // needed.  We agressively kill these because we can by
20067                    // definition not re-use the same process again, and it is
20068                    // good to avoid having whatever code was running in them
20069                    // left sitting around after no longer needed.
20070                    app.kill("isolated not needed", true);
20071                } else {
20072                    // Keeping this process, update its uid.
20073                    final UidRecord uidRec = app.uidRecord;
20074                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20075                        uidRec.curProcState = app.curProcState;
20076                    }
20077                }
20078
20079                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20080                        && !app.killedByAm) {
20081                    numTrimming++;
20082                }
20083            }
20084        }
20085
20086        mNumServiceProcs = mNewNumServiceProcs;
20087
20088        // Now determine the memory trimming level of background processes.
20089        // Unfortunately we need to start at the back of the list to do this
20090        // properly.  We only do this if the number of background apps we
20091        // are managing to keep around is less than half the maximum we desire;
20092        // if we are keeping a good number around, we'll let them use whatever
20093        // memory they want.
20094        final int numCachedAndEmpty = numCached + numEmpty;
20095        int memFactor;
20096        if (numCached <= ProcessList.TRIM_CACHED_APPS
20097                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20098            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20099                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20100            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20101                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20102            } else {
20103                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20104            }
20105        } else {
20106            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20107        }
20108        // We always allow the memory level to go up (better).  We only allow it to go
20109        // down if we are in a state where that is allowed, *and* the total number of processes
20110        // has gone down since last time.
20111        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20112                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20113                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20114        if (memFactor > mLastMemoryLevel) {
20115            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20116                memFactor = mLastMemoryLevel;
20117                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20118            }
20119        }
20120        mLastMemoryLevel = memFactor;
20121        mLastNumProcesses = mLruProcesses.size();
20122        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20123        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20124        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20125            if (mLowRamStartTime == 0) {
20126                mLowRamStartTime = now;
20127            }
20128            int step = 0;
20129            int fgTrimLevel;
20130            switch (memFactor) {
20131                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20132                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20133                    break;
20134                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20135                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20136                    break;
20137                default:
20138                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20139                    break;
20140            }
20141            int factor = numTrimming/3;
20142            int minFactor = 2;
20143            if (mHomeProcess != null) minFactor++;
20144            if (mPreviousProcess != null) minFactor++;
20145            if (factor < minFactor) factor = minFactor;
20146            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20147            for (int i=N-1; i>=0; i--) {
20148                ProcessRecord app = mLruProcesses.get(i);
20149                if (allChanged || app.procStateChanged) {
20150                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20151                    app.procStateChanged = false;
20152                }
20153                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20154                        && !app.killedByAm) {
20155                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20156                        try {
20157                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20158                                    "Trimming memory of " + app.processName + " to " + curLevel);
20159                            app.thread.scheduleTrimMemory(curLevel);
20160                        } catch (RemoteException e) {
20161                        }
20162                        if (false) {
20163                            // For now we won't do this; our memory trimming seems
20164                            // to be good enough at this point that destroying
20165                            // activities causes more harm than good.
20166                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20167                                    && app != mHomeProcess && app != mPreviousProcess) {
20168                                // Need to do this on its own message because the stack may not
20169                                // be in a consistent state at this point.
20170                                // For these apps we will also finish their activities
20171                                // to help them free memory.
20172                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20173                            }
20174                        }
20175                    }
20176                    app.trimMemoryLevel = curLevel;
20177                    step++;
20178                    if (step >= factor) {
20179                        step = 0;
20180                        switch (curLevel) {
20181                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20182                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20183                                break;
20184                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20185                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20186                                break;
20187                        }
20188                    }
20189                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20190                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20191                            && app.thread != null) {
20192                        try {
20193                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20194                                    "Trimming memory of heavy-weight " + app.processName
20195                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20196                            app.thread.scheduleTrimMemory(
20197                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20198                        } catch (RemoteException e) {
20199                        }
20200                    }
20201                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20202                } else {
20203                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20204                            || app.systemNoUi) && app.pendingUiClean) {
20205                        // If this application is now in the background and it
20206                        // had done UI, then give it the special trim level to
20207                        // have it free UI resources.
20208                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20209                        if (app.trimMemoryLevel < level && app.thread != null) {
20210                            try {
20211                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20212                                        "Trimming memory of bg-ui " + app.processName
20213                                        + " to " + level);
20214                                app.thread.scheduleTrimMemory(level);
20215                            } catch (RemoteException e) {
20216                            }
20217                        }
20218                        app.pendingUiClean = false;
20219                    }
20220                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20221                        try {
20222                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20223                                    "Trimming memory of fg " + app.processName
20224                                    + " to " + fgTrimLevel);
20225                            app.thread.scheduleTrimMemory(fgTrimLevel);
20226                        } catch (RemoteException e) {
20227                        }
20228                    }
20229                    app.trimMemoryLevel = fgTrimLevel;
20230                }
20231            }
20232        } else {
20233            if (mLowRamStartTime != 0) {
20234                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20235                mLowRamStartTime = 0;
20236            }
20237            for (int i=N-1; i>=0; i--) {
20238                ProcessRecord app = mLruProcesses.get(i);
20239                if (allChanged || app.procStateChanged) {
20240                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20241                    app.procStateChanged = false;
20242                }
20243                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20244                        || app.systemNoUi) && app.pendingUiClean) {
20245                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20246                            && app.thread != null) {
20247                        try {
20248                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20249                                    "Trimming memory of ui hidden " + app.processName
20250                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20251                            app.thread.scheduleTrimMemory(
20252                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20253                        } catch (RemoteException e) {
20254                        }
20255                    }
20256                    app.pendingUiClean = false;
20257                }
20258                app.trimMemoryLevel = 0;
20259            }
20260        }
20261
20262        if (mAlwaysFinishActivities) {
20263            // Need to do this on its own message because the stack may not
20264            // be in a consistent state at this point.
20265            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20266        }
20267
20268        if (allChanged) {
20269            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20270        }
20271
20272        // Update from any uid changes.
20273        for (int i=mActiveUids.size()-1; i>=0; i--) {
20274            final UidRecord uidRec = mActiveUids.valueAt(i);
20275            int uidChange = UidRecord.CHANGE_PROCSTATE;
20276            if (uidRec.setProcState != uidRec.curProcState) {
20277                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20278                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20279                        + " to " + uidRec.curProcState);
20280                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20281                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20282                        uidRec.lastBackgroundTime = nowElapsed;
20283                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20284                            // Note: the background settle time is in elapsed realtime, while
20285                            // the handler time base is uptime.  All this means is that we may
20286                            // stop background uids later than we had intended, but that only
20287                            // happens because the device was sleeping so we are okay anyway.
20288                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20289                        }
20290                    }
20291                } else {
20292                    if (uidRec.idle) {
20293                        uidChange = UidRecord.CHANGE_ACTIVE;
20294                        uidRec.idle = false;
20295                    }
20296                    uidRec.lastBackgroundTime = 0;
20297                }
20298                uidRec.setProcState = uidRec.curProcState;
20299                enqueueUidChangeLocked(uidRec, -1, uidChange);
20300                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20301            }
20302        }
20303
20304        if (mProcessStats.shouldWriteNowLocked(now)) {
20305            mHandler.post(new Runnable() {
20306                @Override public void run() {
20307                    synchronized (ActivityManagerService.this) {
20308                        mProcessStats.writeStateAsyncLocked();
20309                    }
20310                }
20311            });
20312        }
20313
20314        if (DEBUG_OOM_ADJ) {
20315            final long duration = SystemClock.uptimeMillis() - now;
20316            if (false) {
20317                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20318                        new RuntimeException("here").fillInStackTrace());
20319            } else {
20320                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20321            }
20322        }
20323    }
20324
20325    final void idleUids() {
20326        synchronized (this) {
20327            final long nowElapsed = SystemClock.elapsedRealtime();
20328            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20329            long nextTime = 0;
20330            for (int i=mActiveUids.size()-1; i>=0; i--) {
20331                final UidRecord uidRec = mActiveUids.valueAt(i);
20332                final long bgTime = uidRec.lastBackgroundTime;
20333                if (bgTime > 0 && !uidRec.idle) {
20334                    if (bgTime <= maxBgTime) {
20335                        uidRec.idle = true;
20336                        doStopUidLocked(uidRec.uid, uidRec);
20337                    } else {
20338                        if (nextTime == 0 || nextTime > bgTime) {
20339                            nextTime = bgTime;
20340                        }
20341                    }
20342                }
20343            }
20344            if (nextTime > 0) {
20345                mHandler.removeMessages(IDLE_UIDS_MSG);
20346                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20347                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20348            }
20349        }
20350    }
20351
20352    final void runInBackgroundDisabled(int uid) {
20353        synchronized (this) {
20354            UidRecord uidRec = mActiveUids.get(uid);
20355            if (uidRec != null) {
20356                // This uid is actually running...  should it be considered background now?
20357                if (uidRec.idle) {
20358                    doStopUidLocked(uidRec.uid, uidRec);
20359                }
20360            } else {
20361                // This uid isn't actually running...  still send a report about it being "stopped".
20362                doStopUidLocked(uid, null);
20363            }
20364        }
20365    }
20366
20367    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20368        mServices.stopInBackgroundLocked(uid);
20369        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20370    }
20371
20372    final void trimApplications() {
20373        synchronized (this) {
20374            int i;
20375
20376            // First remove any unused application processes whose package
20377            // has been removed.
20378            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20379                final ProcessRecord app = mRemovedProcesses.get(i);
20380                if (app.activities.size() == 0
20381                        && app.curReceiver == null && app.services.size() == 0) {
20382                    Slog.i(
20383                        TAG, "Exiting empty application process "
20384                        + app.processName + " ("
20385                        + (app.thread != null ? app.thread.asBinder() : null)
20386                        + ")\n");
20387                    if (app.pid > 0 && app.pid != MY_PID) {
20388                        app.kill("empty", false);
20389                    } else {
20390                        try {
20391                            app.thread.scheduleExit();
20392                        } catch (Exception e) {
20393                            // Ignore exceptions.
20394                        }
20395                    }
20396                    cleanUpApplicationRecordLocked(app, false, true, -1);
20397                    mRemovedProcesses.remove(i);
20398
20399                    if (app.persistent) {
20400                        addAppLocked(app.info, false, null /* ABI override */);
20401                    }
20402                }
20403            }
20404
20405            // Now update the oom adj for all processes.
20406            updateOomAdjLocked();
20407        }
20408    }
20409
20410    /** This method sends the specified signal to each of the persistent apps */
20411    public void signalPersistentProcesses(int sig) throws RemoteException {
20412        if (sig != Process.SIGNAL_USR1) {
20413            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20414        }
20415
20416        synchronized (this) {
20417            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20418                    != PackageManager.PERMISSION_GRANTED) {
20419                throw new SecurityException("Requires permission "
20420                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20421            }
20422
20423            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20424                ProcessRecord r = mLruProcesses.get(i);
20425                if (r.thread != null && r.persistent) {
20426                    Process.sendSignal(r.pid, sig);
20427                }
20428            }
20429        }
20430    }
20431
20432    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20433        if (proc == null || proc == mProfileProc) {
20434            proc = mProfileProc;
20435            profileType = mProfileType;
20436            clearProfilerLocked();
20437        }
20438        if (proc == null) {
20439            return;
20440        }
20441        try {
20442            proc.thread.profilerControl(false, null, profileType);
20443        } catch (RemoteException e) {
20444            throw new IllegalStateException("Process disappeared");
20445        }
20446    }
20447
20448    private void clearProfilerLocked() {
20449        if (mProfileFd != null) {
20450            try {
20451                mProfileFd.close();
20452            } catch (IOException e) {
20453            }
20454        }
20455        mProfileApp = null;
20456        mProfileProc = null;
20457        mProfileFile = null;
20458        mProfileType = 0;
20459        mAutoStopProfiler = false;
20460        mSamplingInterval = 0;
20461    }
20462
20463    public boolean profileControl(String process, int userId, boolean start,
20464            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20465
20466        try {
20467            synchronized (this) {
20468                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20469                // its own permission.
20470                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20471                        != PackageManager.PERMISSION_GRANTED) {
20472                    throw new SecurityException("Requires permission "
20473                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20474                }
20475
20476                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20477                    throw new IllegalArgumentException("null profile info or fd");
20478                }
20479
20480                ProcessRecord proc = null;
20481                if (process != null) {
20482                    proc = findProcessLocked(process, userId, "profileControl");
20483                }
20484
20485                if (start && (proc == null || proc.thread == null)) {
20486                    throw new IllegalArgumentException("Unknown process: " + process);
20487                }
20488
20489                if (start) {
20490                    stopProfilerLocked(null, 0);
20491                    setProfileApp(proc.info, proc.processName, profilerInfo);
20492                    mProfileProc = proc;
20493                    mProfileType = profileType;
20494                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20495                    try {
20496                        fd = fd.dup();
20497                    } catch (IOException e) {
20498                        fd = null;
20499                    }
20500                    profilerInfo.profileFd = fd;
20501                    proc.thread.profilerControl(start, profilerInfo, profileType);
20502                    fd = null;
20503                    mProfileFd = null;
20504                } else {
20505                    stopProfilerLocked(proc, profileType);
20506                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20507                        try {
20508                            profilerInfo.profileFd.close();
20509                        } catch (IOException e) {
20510                        }
20511                    }
20512                }
20513
20514                return true;
20515            }
20516        } catch (RemoteException e) {
20517            throw new IllegalStateException("Process disappeared");
20518        } finally {
20519            if (profilerInfo != null && profilerInfo.profileFd != null) {
20520                try {
20521                    profilerInfo.profileFd.close();
20522                } catch (IOException e) {
20523                }
20524            }
20525        }
20526    }
20527
20528    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20529        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20530                userId, true, ALLOW_FULL_ONLY, callName, null);
20531        ProcessRecord proc = null;
20532        try {
20533            int pid = Integer.parseInt(process);
20534            synchronized (mPidsSelfLocked) {
20535                proc = mPidsSelfLocked.get(pid);
20536            }
20537        } catch (NumberFormatException e) {
20538        }
20539
20540        if (proc == null) {
20541            ArrayMap<String, SparseArray<ProcessRecord>> all
20542                    = mProcessNames.getMap();
20543            SparseArray<ProcessRecord> procs = all.get(process);
20544            if (procs != null && procs.size() > 0) {
20545                proc = procs.valueAt(0);
20546                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20547                    for (int i=1; i<procs.size(); i++) {
20548                        ProcessRecord thisProc = procs.valueAt(i);
20549                        if (thisProc.userId == userId) {
20550                            proc = thisProc;
20551                            break;
20552                        }
20553                    }
20554                }
20555            }
20556        }
20557
20558        return proc;
20559    }
20560
20561    public boolean dumpHeap(String process, int userId, boolean managed,
20562            String path, ParcelFileDescriptor fd) throws RemoteException {
20563
20564        try {
20565            synchronized (this) {
20566                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20567                // its own permission (same as profileControl).
20568                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20569                        != PackageManager.PERMISSION_GRANTED) {
20570                    throw new SecurityException("Requires permission "
20571                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20572                }
20573
20574                if (fd == null) {
20575                    throw new IllegalArgumentException("null fd");
20576                }
20577
20578                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20579                if (proc == null || proc.thread == null) {
20580                    throw new IllegalArgumentException("Unknown process: " + process);
20581                }
20582
20583                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20584                if (!isDebuggable) {
20585                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20586                        throw new SecurityException("Process not debuggable: " + proc);
20587                    }
20588                }
20589
20590                proc.thread.dumpHeap(managed, path, fd);
20591                fd = null;
20592                return true;
20593            }
20594        } catch (RemoteException e) {
20595            throw new IllegalStateException("Process disappeared");
20596        } finally {
20597            if (fd != null) {
20598                try {
20599                    fd.close();
20600                } catch (IOException e) {
20601                }
20602            }
20603        }
20604    }
20605
20606    @Override
20607    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20608            String reportPackage) {
20609        if (processName != null) {
20610            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20611                    "setDumpHeapDebugLimit()");
20612        } else {
20613            synchronized (mPidsSelfLocked) {
20614                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20615                if (proc == null) {
20616                    throw new SecurityException("No process found for calling pid "
20617                            + Binder.getCallingPid());
20618                }
20619                if (!Build.IS_DEBUGGABLE
20620                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20621                    throw new SecurityException("Not running a debuggable build");
20622                }
20623                processName = proc.processName;
20624                uid = proc.uid;
20625                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20626                    throw new SecurityException("Package " + reportPackage + " is not running in "
20627                            + proc);
20628                }
20629            }
20630        }
20631        synchronized (this) {
20632            if (maxMemSize > 0) {
20633                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20634            } else {
20635                if (uid != 0) {
20636                    mMemWatchProcesses.remove(processName, uid);
20637                } else {
20638                    mMemWatchProcesses.getMap().remove(processName);
20639                }
20640            }
20641        }
20642    }
20643
20644    @Override
20645    public void dumpHeapFinished(String path) {
20646        synchronized (this) {
20647            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20648                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20649                        + " does not match last pid " + mMemWatchDumpPid);
20650                return;
20651            }
20652            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20653                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20654                        + " does not match last path " + mMemWatchDumpFile);
20655                return;
20656            }
20657            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20658            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20659        }
20660    }
20661
20662    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20663    public void monitor() {
20664        synchronized (this) { }
20665    }
20666
20667    void onCoreSettingsChange(Bundle settings) {
20668        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20669            ProcessRecord processRecord = mLruProcesses.get(i);
20670            try {
20671                if (processRecord.thread != null) {
20672                    processRecord.thread.setCoreSettings(settings);
20673                }
20674            } catch (RemoteException re) {
20675                /* ignore */
20676            }
20677        }
20678    }
20679
20680    // Multi-user methods
20681
20682    /**
20683     * Start user, if its not already running, but don't bring it to foreground.
20684     */
20685    @Override
20686    public boolean startUserInBackground(final int userId) {
20687        return mUserController.startUser(userId, /* foreground */ false);
20688    }
20689
20690    @Override
20691    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20692        return mUserController.unlockUser(userId, token, secret, new ProgressReporter(0, listener));
20693    }
20694
20695    @Override
20696    public boolean switchUser(final int targetUserId) {
20697        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20698        UserInfo currentUserInfo;
20699        UserInfo targetUserInfo;
20700        synchronized (this) {
20701            int currentUserId = mUserController.getCurrentUserIdLocked();
20702            currentUserInfo = mUserController.getUserInfo(currentUserId);
20703            targetUserInfo = mUserController.getUserInfo(targetUserId);
20704            if (targetUserInfo == null) {
20705                Slog.w(TAG, "No user info for user #" + targetUserId);
20706                return false;
20707            }
20708            if (!targetUserInfo.supportsSwitchTo()) {
20709                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20710                return false;
20711            }
20712            if (targetUserInfo.isManagedProfile()) {
20713                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20714                return false;
20715            }
20716            mUserController.setTargetUserIdLocked(targetUserId);
20717        }
20718        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20719        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20720        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20721        return true;
20722    }
20723
20724    void scheduleStartProfilesLocked() {
20725        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20726            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20727                    DateUtils.SECOND_IN_MILLIS);
20728        }
20729    }
20730
20731    @Override
20732    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20733        return mUserController.stopUser(userId, force, callback);
20734    }
20735
20736    @Override
20737    public UserInfo getCurrentUser() {
20738        return mUserController.getCurrentUser();
20739    }
20740
20741    @Override
20742    public boolean isUserRunning(int userId, int flags) {
20743        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20744                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20745            String msg = "Permission Denial: isUserRunning() from pid="
20746                    + Binder.getCallingPid()
20747                    + ", uid=" + Binder.getCallingUid()
20748                    + " requires " + INTERACT_ACROSS_USERS;
20749            Slog.w(TAG, msg);
20750            throw new SecurityException(msg);
20751        }
20752        synchronized (this) {
20753            return mUserController.isUserRunningLocked(userId, flags);
20754        }
20755    }
20756
20757    @Override
20758    public int[] getRunningUserIds() {
20759        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20760                != PackageManager.PERMISSION_GRANTED) {
20761            String msg = "Permission Denial: isUserRunning() from pid="
20762                    + Binder.getCallingPid()
20763                    + ", uid=" + Binder.getCallingUid()
20764                    + " requires " + INTERACT_ACROSS_USERS;
20765            Slog.w(TAG, msg);
20766            throw new SecurityException(msg);
20767        }
20768        synchronized (this) {
20769            return mUserController.getStartedUserArrayLocked();
20770        }
20771    }
20772
20773    @Override
20774    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20775        mUserController.registerUserSwitchObserver(observer);
20776    }
20777
20778    @Override
20779    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20780        mUserController.unregisterUserSwitchObserver(observer);
20781    }
20782
20783    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20784        if (info == null) return null;
20785        ApplicationInfo newInfo = new ApplicationInfo(info);
20786        newInfo.initForUser(userId);
20787        return newInfo;
20788    }
20789
20790    public boolean isUserStopped(int userId) {
20791        synchronized (this) {
20792            return mUserController.getStartedUserStateLocked(userId) == null;
20793        }
20794    }
20795
20796    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20797        if (aInfo == null
20798                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20799            return aInfo;
20800        }
20801
20802        ActivityInfo info = new ActivityInfo(aInfo);
20803        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20804        return info;
20805    }
20806
20807    private boolean processSanityChecksLocked(ProcessRecord process) {
20808        if (process == null || process.thread == null) {
20809            return false;
20810        }
20811
20812        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20813        if (!isDebuggable) {
20814            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20815                return false;
20816            }
20817        }
20818
20819        return true;
20820    }
20821
20822    public boolean startBinderTracking() throws RemoteException {
20823        synchronized (this) {
20824            mBinderTransactionTrackingEnabled = true;
20825            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20826            // permission (same as profileControl).
20827            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20828                    != PackageManager.PERMISSION_GRANTED) {
20829                throw new SecurityException("Requires permission "
20830                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20831            }
20832
20833            for (int i = 0; i < mLruProcesses.size(); i++) {
20834                ProcessRecord process = mLruProcesses.get(i);
20835                if (!processSanityChecksLocked(process)) {
20836                    continue;
20837                }
20838                try {
20839                    process.thread.startBinderTracking();
20840                } catch (RemoteException e) {
20841                    Log.v(TAG, "Process disappared");
20842                }
20843            }
20844            return true;
20845        }
20846    }
20847
20848    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20849        try {
20850            synchronized (this) {
20851                mBinderTransactionTrackingEnabled = false;
20852                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20853                // permission (same as profileControl).
20854                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20855                        != PackageManager.PERMISSION_GRANTED) {
20856                    throw new SecurityException("Requires permission "
20857                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20858                }
20859
20860                if (fd == null) {
20861                    throw new IllegalArgumentException("null fd");
20862                }
20863
20864                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20865                pw.println("Binder transaction traces for all processes.\n");
20866                for (ProcessRecord process : mLruProcesses) {
20867                    if (!processSanityChecksLocked(process)) {
20868                        continue;
20869                    }
20870
20871                    pw.println("Traces for process: " + process.processName);
20872                    pw.flush();
20873                    try {
20874                        TransferPipe tp = new TransferPipe();
20875                        try {
20876                            process.thread.stopBinderTrackingAndDump(
20877                                    tp.getWriteFd().getFileDescriptor());
20878                            tp.go(fd.getFileDescriptor());
20879                        } finally {
20880                            tp.kill();
20881                        }
20882                    } catch (IOException e) {
20883                        pw.println("Failure while dumping IPC traces from " + process +
20884                                ".  Exception: " + e);
20885                        pw.flush();
20886                    } catch (RemoteException e) {
20887                        pw.println("Got a RemoteException while dumping IPC traces from " +
20888                                process + ".  Exception: " + e);
20889                        pw.flush();
20890                    }
20891                }
20892                fd = null;
20893                return true;
20894            }
20895        } finally {
20896            if (fd != null) {
20897                try {
20898                    fd.close();
20899                } catch (IOException e) {
20900                }
20901            }
20902        }
20903    }
20904
20905    private final class LocalService extends ActivityManagerInternal {
20906        @Override
20907        public void onWakefulnessChanged(int wakefulness) {
20908            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20909        }
20910
20911        @Override
20912        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20913                String processName, String abiOverride, int uid, Runnable crashHandler) {
20914            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20915                    processName, abiOverride, uid, crashHandler);
20916        }
20917
20918        @Override
20919        public SleepToken acquireSleepToken(String tag) {
20920            Preconditions.checkNotNull(tag);
20921
20922            synchronized (ActivityManagerService.this) {
20923                SleepTokenImpl token = new SleepTokenImpl(tag);
20924                mSleepTokens.add(token);
20925                updateSleepIfNeededLocked();
20926                applyVrModeIfNeededLocked(mFocusedActivity, false);
20927                return token;
20928            }
20929        }
20930
20931        @Override
20932        public ComponentName getHomeActivityForUser(int userId) {
20933            synchronized (ActivityManagerService.this) {
20934                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20935                return homeActivity == null ? null : homeActivity.realActivity;
20936            }
20937        }
20938
20939        @Override
20940        public void onUserRemoved(int userId) {
20941            synchronized (ActivityManagerService.this) {
20942                ActivityManagerService.this.onUserStoppedLocked(userId);
20943            }
20944        }
20945
20946        @Override
20947        public void onLocalVoiceInteractionStarted(IBinder activity,
20948                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20949            synchronized (ActivityManagerService.this) {
20950                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20951                        voiceSession, voiceInteractor);
20952            }
20953        }
20954
20955        @Override
20956        public void notifyStartingWindowDrawn() {
20957            synchronized (ActivityManagerService.this) {
20958                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20959            }
20960        }
20961
20962        @Override
20963        public void notifyAppTransitionStarting(int reason) {
20964            synchronized (ActivityManagerService.this) {
20965                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20966            }
20967        }
20968
20969        @Override
20970        public void notifyAppTransitionFinished() {
20971            synchronized (ActivityManagerService.this) {
20972                mStackSupervisor.notifyAppTransitionDone();
20973            }
20974        }
20975
20976        @Override
20977        public void notifyAppTransitionCancelled() {
20978            synchronized (ActivityManagerService.this) {
20979                mStackSupervisor.notifyAppTransitionDone();
20980            }
20981        }
20982    }
20983
20984    private final class SleepTokenImpl extends SleepToken {
20985        private final String mTag;
20986        private final long mAcquireTime;
20987
20988        public SleepTokenImpl(String tag) {
20989            mTag = tag;
20990            mAcquireTime = SystemClock.uptimeMillis();
20991        }
20992
20993        @Override
20994        public void release() {
20995            synchronized (ActivityManagerService.this) {
20996                if (mSleepTokens.remove(this)) {
20997                    updateSleepIfNeededLocked();
20998                }
20999            }
21000        }
21001
21002        @Override
21003        public String toString() {
21004            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21005        }
21006    }
21007
21008    /**
21009     * An implementation of IAppTask, that allows an app to manage its own tasks via
21010     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21011     * only the process that calls getAppTasks() can call the AppTask methods.
21012     */
21013    class AppTaskImpl extends IAppTask.Stub {
21014        private int mTaskId;
21015        private int mCallingUid;
21016
21017        public AppTaskImpl(int taskId, int callingUid) {
21018            mTaskId = taskId;
21019            mCallingUid = callingUid;
21020        }
21021
21022        private void checkCaller() {
21023            if (mCallingUid != Binder.getCallingUid()) {
21024                throw new SecurityException("Caller " + mCallingUid
21025                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21026            }
21027        }
21028
21029        @Override
21030        public void finishAndRemoveTask() {
21031            checkCaller();
21032
21033            synchronized (ActivityManagerService.this) {
21034                long origId = Binder.clearCallingIdentity();
21035                try {
21036                    // We remove the task from recents to preserve backwards
21037                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21038                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21039                    }
21040                } finally {
21041                    Binder.restoreCallingIdentity(origId);
21042                }
21043            }
21044        }
21045
21046        @Override
21047        public ActivityManager.RecentTaskInfo getTaskInfo() {
21048            checkCaller();
21049
21050            synchronized (ActivityManagerService.this) {
21051                long origId = Binder.clearCallingIdentity();
21052                try {
21053                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21054                    if (tr == null) {
21055                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21056                    }
21057                    return createRecentTaskInfoFromTaskRecord(tr);
21058                } finally {
21059                    Binder.restoreCallingIdentity(origId);
21060                }
21061            }
21062        }
21063
21064        @Override
21065        public void moveToFront() {
21066            checkCaller();
21067            // Will bring task to front if it already has a root activity.
21068            final long origId = Binder.clearCallingIdentity();
21069            try {
21070                synchronized (this) {
21071                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21072                }
21073            } finally {
21074                Binder.restoreCallingIdentity(origId);
21075            }
21076        }
21077
21078        @Override
21079        public int startActivity(IBinder whoThread, String callingPackage,
21080                Intent intent, String resolvedType, Bundle bOptions) {
21081            checkCaller();
21082
21083            int callingUser = UserHandle.getCallingUserId();
21084            TaskRecord tr;
21085            IApplicationThread appThread;
21086            synchronized (ActivityManagerService.this) {
21087                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21088                if (tr == null) {
21089                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21090                }
21091                appThread = ApplicationThreadNative.asInterface(whoThread);
21092                if (appThread == null) {
21093                    throw new IllegalArgumentException("Bad app thread " + appThread);
21094                }
21095            }
21096            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21097                    resolvedType, null, null, null, null, 0, 0, null, null,
21098                    null, bOptions, false, callingUser, null, tr);
21099        }
21100
21101        @Override
21102        public void setExcludeFromRecents(boolean exclude) {
21103            checkCaller();
21104
21105            synchronized (ActivityManagerService.this) {
21106                long origId = Binder.clearCallingIdentity();
21107                try {
21108                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21109                    if (tr == null) {
21110                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21111                    }
21112                    Intent intent = tr.getBaseIntent();
21113                    if (exclude) {
21114                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21115                    } else {
21116                        intent.setFlags(intent.getFlags()
21117                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21118                    }
21119                } finally {
21120                    Binder.restoreCallingIdentity(origId);
21121                }
21122            }
21123        }
21124    }
21125
21126    /**
21127     * Kill processes for the user with id userId and that depend on the package named packageName
21128     */
21129    @Override
21130    public void killPackageDependents(String packageName, int userId) {
21131        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21132        if (packageName == null) {
21133            throw new NullPointerException(
21134                    "Cannot kill the dependents of a package without its name.");
21135        }
21136
21137        long callingId = Binder.clearCallingIdentity();
21138        IPackageManager pm = AppGlobals.getPackageManager();
21139        int pkgUid = -1;
21140        try {
21141            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21142        } catch (RemoteException e) {
21143        }
21144        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21145            throw new IllegalArgumentException(
21146                    "Cannot kill dependents of non-existing package " + packageName);
21147        }
21148        try {
21149            synchronized(this) {
21150                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21151                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21152                        "dep: " + packageName);
21153            }
21154        } finally {
21155            Binder.restoreCallingIdentity(callingId);
21156        }
21157    }
21158}
21159