ActivityManagerService.java revision e8222e551f8abd2d82ca4f77ddb275e2e509751e
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 Bundle receiverExtras;
632
633        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
634                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
635            activity = _activity;
636            extras = _extras;
637            intent = _intent;
638            hint = _hint;
639            receiver = _receiver;
640            receiverExtras = _receiverExtras;
641            userHandle = _userHandle;
642        }
643        @Override
644        public void run() {
645            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
646            synchronized (this) {
647                haveResult = true;
648                notifyAll();
649            }
650            pendingAssistExtrasTimedOut(this);
651        }
652    }
653
654    final ArrayList<PendingAssistExtras> mPendingAssistExtras
655            = new ArrayList<PendingAssistExtras>();
656
657    /**
658     * Process management.
659     */
660    final ProcessList mProcessList = new ProcessList();
661
662    /**
663     * All of the applications we currently have running organized by name.
664     * The keys are strings of the application package name (as
665     * returned by the package manager), and the keys are ApplicationRecord
666     * objects.
667     */
668    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
669
670    /**
671     * Tracking long-term execution of processes to look for abuse and other
672     * bad app behavior.
673     */
674    final ProcessStatsService mProcessStats;
675
676    /**
677     * The currently running isolated processes.
678     */
679    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
680
681    /**
682     * Counter for assigning isolated process uids, to avoid frequently reusing the
683     * same ones.
684     */
685    int mNextIsolatedProcessUid = 0;
686
687    /**
688     * The currently running heavy-weight process, if any.
689     */
690    ProcessRecord mHeavyWeightProcess = null;
691
692    /**
693     * All of the processes we currently have running organized by pid.
694     * The keys are the pid running the application.
695     *
696     * <p>NOTE: This object is protected by its own lock, NOT the global
697     * activity manager lock!
698     */
699    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
700
701    /**
702     * All of the processes that have been forced to be foreground.  The key
703     * is the pid of the caller who requested it (we hold a death
704     * link on it).
705     */
706    abstract class ForegroundToken implements IBinder.DeathRecipient {
707        int pid;
708        IBinder token;
709    }
710    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
711
712    /**
713     * List of records for processes that someone had tried to start before the
714     * system was ready.  We don't start them at that point, but ensure they
715     * are started by the time booting is complete.
716     */
717    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
718
719    /**
720     * List of persistent applications that are in the process
721     * of being started.
722     */
723    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
724
725    /**
726     * Processes that are being forcibly torn down.
727     */
728    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
729
730    /**
731     * List of running applications, sorted by recent usage.
732     * The first entry in the list is the least recently used.
733     */
734    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
735
736    /**
737     * Where in mLruProcesses that the processes hosting activities start.
738     */
739    int mLruProcessActivityStart = 0;
740
741    /**
742     * Where in mLruProcesses that the processes hosting services start.
743     * This is after (lower index) than mLruProcessesActivityStart.
744     */
745    int mLruProcessServiceStart = 0;
746
747    /**
748     * List of processes that should gc as soon as things are idle.
749     */
750    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
751
752    /**
753     * Processes we want to collect PSS data from.
754     */
755    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
756
757    private boolean mBinderTransactionTrackingEnabled = false;
758
759    /**
760     * Last time we requested PSS data of all processes.
761     */
762    long mLastFullPssTime = SystemClock.uptimeMillis();
763
764    /**
765     * If set, the next time we collect PSS data we should do a full collection
766     * with data from native processes and the kernel.
767     */
768    boolean mFullPssPending = false;
769
770    /**
771     * This is the process holding what we currently consider to be
772     * the "home" activity.
773     */
774    ProcessRecord mHomeProcess;
775
776    /**
777     * This is the process holding the activity the user last visited that
778     * is in a different process from the one they are currently in.
779     */
780    ProcessRecord mPreviousProcess;
781
782    /**
783     * The time at which the previous process was last visible.
784     */
785    long mPreviousProcessVisibleTime;
786
787    /**
788     * Track all uids that have actively running processes.
789     */
790    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
791
792    /**
793     * This is for verifying the UID report flow.
794     */
795    static final boolean VALIDATE_UID_STATES = true;
796    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
797
798    /**
799     * Packages that the user has asked to have run in screen size
800     * compatibility mode instead of filling the screen.
801     */
802    final CompatModePackages mCompatModePackages;
803
804    /**
805     * Set of IntentSenderRecord objects that are currently active.
806     */
807    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
808            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
809
810    /**
811     * Fingerprints (hashCode()) of stack traces that we've
812     * already logged DropBox entries for.  Guarded by itself.  If
813     * something (rogue user app) forces this over
814     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
815     */
816    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
817    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
818
819    /**
820     * Strict Mode background batched logging state.
821     *
822     * The string buffer is guarded by itself, and its lock is also
823     * used to determine if another batched write is already
824     * in-flight.
825     */
826    private final StringBuilder mStrictModeBuffer = new StringBuilder();
827
828    /**
829     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
830     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
831     */
832    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
833
834    /**
835     * Resolver for broadcast intents to registered receivers.
836     * Holds BroadcastFilter (subclass of IntentFilter).
837     */
838    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
839            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
840        @Override
841        protected boolean allowFilterResult(
842                BroadcastFilter filter, List<BroadcastFilter> dest) {
843            IBinder target = filter.receiverList.receiver.asBinder();
844            for (int i = dest.size() - 1; i >= 0; i--) {
845                if (dest.get(i).receiverList.receiver.asBinder() == target) {
846                    return false;
847                }
848            }
849            return true;
850        }
851
852        @Override
853        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
854            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
855                    || userId == filter.owningUserId) {
856                return super.newResult(filter, match, userId);
857            }
858            return null;
859        }
860
861        @Override
862        protected BroadcastFilter[] newArray(int size) {
863            return new BroadcastFilter[size];
864        }
865
866        @Override
867        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
868            return packageName.equals(filter.packageName);
869        }
870    };
871
872    /**
873     * State of all active sticky broadcasts per user.  Keys are the action of the
874     * sticky Intent, values are an ArrayList of all broadcasted intents with
875     * that action (which should usually be one).  The SparseArray is keyed
876     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
877     * for stickies that are sent to all users.
878     */
879    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
880            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
881
882    final ActiveServices mServices;
883
884    final static class Association {
885        final int mSourceUid;
886        final String mSourceProcess;
887        final int mTargetUid;
888        final ComponentName mTargetComponent;
889        final String mTargetProcess;
890
891        int mCount;
892        long mTime;
893
894        int mNesting;
895        long mStartTime;
896
897        // states of the source process when the bind occurred.
898        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
899        long mLastStateUptime;
900        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
901                - ActivityManager.MIN_PROCESS_STATE+1];
902
903        Association(int sourceUid, String sourceProcess, int targetUid,
904                ComponentName targetComponent, String targetProcess) {
905            mSourceUid = sourceUid;
906            mSourceProcess = sourceProcess;
907            mTargetUid = targetUid;
908            mTargetComponent = targetComponent;
909            mTargetProcess = targetProcess;
910        }
911    }
912
913    /**
914     * When service association tracking is enabled, this is all of the associations we
915     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
916     * -> association data.
917     */
918    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
919            mAssociations = new SparseArray<>();
920    boolean mTrackingAssociations;
921
922    /**
923     * Backup/restore process management
924     */
925    String mBackupAppName = null;
926    BackupRecord mBackupTarget = null;
927
928    final ProviderMap mProviderMap;
929
930    /**
931     * List of content providers who have clients waiting for them.  The
932     * application is currently being launched and the provider will be
933     * removed from this list once it is published.
934     */
935    final ArrayList<ContentProviderRecord> mLaunchingProviders
936            = new ArrayList<ContentProviderRecord>();
937
938    /**
939     * File storing persisted {@link #mGrantedUriPermissions}.
940     */
941    private final AtomicFile mGrantFile;
942
943    /** XML constants used in {@link #mGrantFile} */
944    private static final String TAG_URI_GRANTS = "uri-grants";
945    private static final String TAG_URI_GRANT = "uri-grant";
946    private static final String ATTR_USER_HANDLE = "userHandle";
947    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
948    private static final String ATTR_TARGET_USER_ID = "targetUserId";
949    private static final String ATTR_SOURCE_PKG = "sourcePkg";
950    private static final String ATTR_TARGET_PKG = "targetPkg";
951    private static final String ATTR_URI = "uri";
952    private static final String ATTR_MODE_FLAGS = "modeFlags";
953    private static final String ATTR_CREATED_TIME = "createdTime";
954    private static final String ATTR_PREFIX = "prefix";
955
956    /**
957     * Global set of specific {@link Uri} permissions that have been granted.
958     * This optimized lookup structure maps from {@link UriPermission#targetUid}
959     * to {@link UriPermission#uri} to {@link UriPermission}.
960     */
961    @GuardedBy("this")
962    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
963            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
964
965    public static class GrantUri {
966        public final int sourceUserId;
967        public final Uri uri;
968        public boolean prefix;
969
970        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
971            this.sourceUserId = sourceUserId;
972            this.uri = uri;
973            this.prefix = prefix;
974        }
975
976        @Override
977        public int hashCode() {
978            int hashCode = 1;
979            hashCode = 31 * hashCode + sourceUserId;
980            hashCode = 31 * hashCode + uri.hashCode();
981            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
982            return hashCode;
983        }
984
985        @Override
986        public boolean equals(Object o) {
987            if (o instanceof GrantUri) {
988                GrantUri other = (GrantUri) o;
989                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
990                        && prefix == other.prefix;
991            }
992            return false;
993        }
994
995        @Override
996        public String toString() {
997            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
998            if (prefix) result += " [prefix]";
999            return result;
1000        }
1001
1002        public String toSafeString() {
1003            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1004            if (prefix) result += " [prefix]";
1005            return result;
1006        }
1007
1008        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1009            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1010                    ContentProvider.getUriWithoutUserId(uri), false);
1011        }
1012    }
1013
1014    CoreSettingsObserver mCoreSettingsObserver;
1015
1016    FontScaleSettingObserver mFontScaleSettingObserver;
1017
1018    private final class FontScaleSettingObserver extends ContentObserver {
1019        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1020
1021        public FontScaleSettingObserver() {
1022            super(mHandler);
1023            ContentResolver resolver = mContext.getContentResolver();
1024            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1025        }
1026
1027        @Override
1028        public void onChange(boolean selfChange, Uri uri) {
1029            if (mFontScaleUri.equals(uri)) {
1030                updateFontScaleIfNeeded();
1031            }
1032        }
1033    }
1034
1035    /**
1036     * Thread-local storage used to carry caller permissions over through
1037     * indirect content-provider access.
1038     */
1039    private class Identity {
1040        public final IBinder token;
1041        public final int pid;
1042        public final int uid;
1043
1044        Identity(IBinder _token, int _pid, int _uid) {
1045            token = _token;
1046            pid = _pid;
1047            uid = _uid;
1048        }
1049    }
1050
1051    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1052
1053    /**
1054     * All information we have collected about the runtime performance of
1055     * any user id that can impact battery performance.
1056     */
1057    final BatteryStatsService mBatteryStatsService;
1058
1059    /**
1060     * Information about component usage
1061     */
1062    UsageStatsManagerInternal mUsageStatsService;
1063
1064    /**
1065     * Access to DeviceIdleController service.
1066     */
1067    DeviceIdleController.LocalService mLocalDeviceIdleController;
1068
1069    /**
1070     * Information about and control over application operations
1071     */
1072    final AppOpsService mAppOpsService;
1073
1074    /**
1075     * Current configuration information.  HistoryRecord objects are given
1076     * a reference to this object to indicate which configuration they are
1077     * currently running in, so this object must be kept immutable.
1078     */
1079    Configuration mConfiguration = new Configuration();
1080
1081    /**
1082     * Current sequencing integer of the configuration, for skipping old
1083     * configurations.
1084     */
1085    int mConfigurationSeq = 0;
1086
1087    boolean mSuppressResizeConfigChanges = false;
1088
1089    /**
1090     * Hardware-reported OpenGLES version.
1091     */
1092    final int GL_ES_VERSION;
1093
1094    /**
1095     * List of initialization arguments to pass to all processes when binding applications to them.
1096     * For example, references to the commonly used services.
1097     */
1098    HashMap<String, IBinder> mAppBindArgs;
1099
1100    /**
1101     * Temporary to avoid allocations.  Protected by main lock.
1102     */
1103    final StringBuilder mStringBuilder = new StringBuilder(256);
1104
1105    /**
1106     * Used to control how we initialize the service.
1107     */
1108    ComponentName mTopComponent;
1109    String mTopAction = Intent.ACTION_MAIN;
1110    String mTopData;
1111
1112    volatile boolean mProcessesReady = false;
1113    volatile boolean mSystemReady = false;
1114    volatile boolean mOnBattery = false;
1115    volatile int mFactoryTest;
1116
1117    @GuardedBy("this") boolean mBooting = false;
1118    @GuardedBy("this") boolean mCallFinishBooting = false;
1119    @GuardedBy("this") boolean mBootAnimationComplete = false;
1120    @GuardedBy("this") boolean mLaunchWarningShown = false;
1121    @GuardedBy("this") boolean mCheckedForSetup = false;
1122
1123    Context mContext;
1124
1125    /**
1126     * The time at which we will allow normal application switches again,
1127     * after a call to {@link #stopAppSwitches()}.
1128     */
1129    long mAppSwitchesAllowedTime;
1130
1131    /**
1132     * This is set to true after the first switch after mAppSwitchesAllowedTime
1133     * is set; any switches after that will clear the time.
1134     */
1135    boolean mDidAppSwitch;
1136
1137    /**
1138     * Last time (in realtime) at which we checked for power usage.
1139     */
1140    long mLastPowerCheckRealtime;
1141
1142    /**
1143     * Last time (in uptime) at which we checked for power usage.
1144     */
1145    long mLastPowerCheckUptime;
1146
1147    /**
1148     * Set while we are wanting to sleep, to prevent any
1149     * activities from being started/resumed.
1150     */
1151    private boolean mSleeping = false;
1152
1153    /**
1154     * The process state used for processes that are running the top activities.
1155     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1156     */
1157    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1158
1159    /**
1160     * Set while we are running a voice interaction.  This overrides
1161     * sleeping while it is active.
1162     */
1163    private IVoiceInteractionSession mRunningVoice;
1164
1165    /**
1166     * For some direct access we need to power manager.
1167     */
1168    PowerManagerInternal mLocalPowerManager;
1169
1170    /**
1171     * We want to hold a wake lock while running a voice interaction session, since
1172     * this may happen with the screen off and we need to keep the CPU running to
1173     * be able to continue to interact with the user.
1174     */
1175    PowerManager.WakeLock mVoiceWakeLock;
1176
1177    /**
1178     * State of external calls telling us if the device is awake or asleep.
1179     */
1180    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1181
1182    /**
1183     * A list of tokens that cause the top activity to be put to sleep.
1184     * They are used by components that may hide and block interaction with underlying
1185     * activities.
1186     */
1187    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1188
1189    static final int LOCK_SCREEN_HIDDEN = 0;
1190    static final int LOCK_SCREEN_LEAVING = 1;
1191    static final int LOCK_SCREEN_SHOWN = 2;
1192    /**
1193     * State of external call telling us if the lock screen is shown.
1194     */
1195    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1196
1197    /**
1198     * Set if we are shutting down the system, similar to sleeping.
1199     */
1200    boolean mShuttingDown = false;
1201
1202    /**
1203     * Current sequence id for oom_adj computation traversal.
1204     */
1205    int mAdjSeq = 0;
1206
1207    /**
1208     * Current sequence id for process LRU updating.
1209     */
1210    int mLruSeq = 0;
1211
1212    /**
1213     * Keep track of the non-cached/empty process we last found, to help
1214     * determine how to distribute cached/empty processes next time.
1215     */
1216    int mNumNonCachedProcs = 0;
1217
1218    /**
1219     * Keep track of the number of cached hidden procs, to balance oom adj
1220     * distribution between those and empty procs.
1221     */
1222    int mNumCachedHiddenProcs = 0;
1223
1224    /**
1225     * Keep track of the number of service processes we last found, to
1226     * determine on the next iteration which should be B services.
1227     */
1228    int mNumServiceProcs = 0;
1229    int mNewNumAServiceProcs = 0;
1230    int mNewNumServiceProcs = 0;
1231
1232    /**
1233     * Allow the current computed overall memory level of the system to go down?
1234     * This is set to false when we are killing processes for reasons other than
1235     * memory management, so that the now smaller process list will not be taken as
1236     * an indication that memory is tighter.
1237     */
1238    boolean mAllowLowerMemLevel = false;
1239
1240    /**
1241     * The last computed memory level, for holding when we are in a state that
1242     * processes are going away for other reasons.
1243     */
1244    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1245
1246    /**
1247     * The last total number of process we have, to determine if changes actually look
1248     * like a shrinking number of process due to lower RAM.
1249     */
1250    int mLastNumProcesses;
1251
1252    /**
1253     * The uptime of the last time we performed idle maintenance.
1254     */
1255    long mLastIdleTime = SystemClock.uptimeMillis();
1256
1257    /**
1258     * Total time spent with RAM that has been added in the past since the last idle time.
1259     */
1260    long mLowRamTimeSinceLastIdle = 0;
1261
1262    /**
1263     * If RAM is currently low, when that horrible situation started.
1264     */
1265    long mLowRamStartTime = 0;
1266
1267    /**
1268     * For reporting to battery stats the current top application.
1269     */
1270    private String mCurResumedPackage = null;
1271    private int mCurResumedUid = -1;
1272
1273    /**
1274     * For reporting to battery stats the apps currently running foreground
1275     * service.  The ProcessMap is package/uid tuples; each of these contain
1276     * an array of the currently foreground processes.
1277     */
1278    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1279            = new ProcessMap<ArrayList<ProcessRecord>>();
1280
1281    /**
1282     * This is set if we had to do a delayed dexopt of an app before launching
1283     * it, to increase the ANR timeouts in that case.
1284     */
1285    boolean mDidDexOpt;
1286
1287    /**
1288     * Set if the systemServer made a call to enterSafeMode.
1289     */
1290    boolean mSafeMode;
1291
1292    /**
1293     * If true, we are running under a test environment so will sample PSS from processes
1294     * much more rapidly to try to collect better data when the tests are rapidly
1295     * running through apps.
1296     */
1297    boolean mTestPssMode = false;
1298
1299    String mDebugApp = null;
1300    boolean mWaitForDebugger = false;
1301    boolean mDebugTransient = false;
1302    String mOrigDebugApp = null;
1303    boolean mOrigWaitForDebugger = false;
1304    boolean mAlwaysFinishActivities = false;
1305    boolean mLenientBackgroundCheck = false;
1306    boolean mForceResizableActivities;
1307    boolean mSupportsMultiWindow;
1308    boolean mSupportsFreeformWindowManagement;
1309    boolean mSupportsPictureInPicture;
1310    Rect mDefaultPinnedStackBounds;
1311    IActivityController mController = null;
1312    boolean mControllerIsAMonkey = false;
1313    String mProfileApp = null;
1314    ProcessRecord mProfileProc = null;
1315    String mProfileFile;
1316    ParcelFileDescriptor mProfileFd;
1317    int mSamplingInterval = 0;
1318    boolean mAutoStopProfiler = false;
1319    int mProfileType = 0;
1320    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1321    String mMemWatchDumpProcName;
1322    String mMemWatchDumpFile;
1323    int mMemWatchDumpPid;
1324    int mMemWatchDumpUid;
1325    String mTrackAllocationApp = null;
1326    String mNativeDebuggingApp = null;
1327
1328    final long[] mTmpLong = new long[2];
1329
1330    static final class ProcessChangeItem {
1331        static final int CHANGE_ACTIVITIES = 1<<0;
1332        static final int CHANGE_PROCESS_STATE = 1<<1;
1333        int changes;
1334        int uid;
1335        int pid;
1336        int processState;
1337        boolean foregroundActivities;
1338    }
1339
1340    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1341    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1342
1343    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1344    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1345
1346    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1347    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1348
1349    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1350    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1351
1352    /**
1353     * Runtime CPU use collection thread.  This object's lock is used to
1354     * perform synchronization with the thread (notifying it to run).
1355     */
1356    final Thread mProcessCpuThread;
1357
1358    /**
1359     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1360     * Must acquire this object's lock when accessing it.
1361     * NOTE: this lock will be held while doing long operations (trawling
1362     * through all processes in /proc), so it should never be acquired by
1363     * any critical paths such as when holding the main activity manager lock.
1364     */
1365    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1366            MONITOR_THREAD_CPU_USAGE);
1367    final AtomicLong mLastCpuTime = new AtomicLong(0);
1368    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1369
1370    long mLastWriteTime = 0;
1371
1372    /**
1373     * Used to retain an update lock when the foreground activity is in
1374     * immersive mode.
1375     */
1376    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1377
1378    /**
1379     * Set to true after the system has finished booting.
1380     */
1381    boolean mBooted = false;
1382
1383    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1384    int mProcessLimitOverride = -1;
1385
1386    WindowManagerService mWindowManager;
1387    final ActivityThread mSystemThread;
1388
1389    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1390        final ProcessRecord mApp;
1391        final int mPid;
1392        final IApplicationThread mAppThread;
1393
1394        AppDeathRecipient(ProcessRecord app, int pid,
1395                IApplicationThread thread) {
1396            if (DEBUG_ALL) Slog.v(
1397                TAG, "New death recipient " + this
1398                + " for thread " + thread.asBinder());
1399            mApp = app;
1400            mPid = pid;
1401            mAppThread = thread;
1402        }
1403
1404        @Override
1405        public void binderDied() {
1406            if (DEBUG_ALL) Slog.v(
1407                TAG, "Death received in " + this
1408                + " for thread " + mAppThread.asBinder());
1409            synchronized(ActivityManagerService.this) {
1410                appDiedLocked(mApp, mPid, mAppThread, true);
1411            }
1412        }
1413    }
1414
1415    static final int SHOW_ERROR_UI_MSG = 1;
1416    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1417    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1418    static final int UPDATE_CONFIGURATION_MSG = 4;
1419    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1420    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1421    static final int SERVICE_TIMEOUT_MSG = 12;
1422    static final int UPDATE_TIME_ZONE = 13;
1423    static final int SHOW_UID_ERROR_UI_MSG = 14;
1424    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1425    static final int PROC_START_TIMEOUT_MSG = 20;
1426    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1427    static final int KILL_APPLICATION_MSG = 22;
1428    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1429    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1430    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1431    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1432    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1433    static final int CLEAR_DNS_CACHE_MSG = 28;
1434    static final int UPDATE_HTTP_PROXY_MSG = 29;
1435    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1436    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1437    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1438    static final int REPORT_MEM_USAGE_MSG = 33;
1439    static final int REPORT_USER_SWITCH_MSG = 34;
1440    static final int CONTINUE_USER_SWITCH_MSG = 35;
1441    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1442    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1443    static final int PERSIST_URI_GRANTS_MSG = 38;
1444    static final int REQUEST_ALL_PSS_MSG = 39;
1445    static final int START_PROFILES_MSG = 40;
1446    static final int UPDATE_TIME = 41;
1447    static final int SYSTEM_USER_START_MSG = 42;
1448    static final int SYSTEM_USER_CURRENT_MSG = 43;
1449    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1450    static final int FINISH_BOOTING_MSG = 45;
1451    static final int START_USER_SWITCH_UI_MSG = 46;
1452    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1453    static final int DISMISS_DIALOG_UI_MSG = 48;
1454    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1455    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1456    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1457    static final int DELETE_DUMPHEAP_MSG = 52;
1458    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1459    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1460    static final int REPORT_TIME_TRACKER_MSG = 55;
1461    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1462    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1463    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1464    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1465    static final int IDLE_UIDS_MSG = 60;
1466    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1467    static final int LOG_STACK_STATE = 62;
1468    static final int VR_MODE_CHANGE_MSG = 63;
1469    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1470    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1471    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1472    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1473    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1474
1475    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1476    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1477    static final int FIRST_COMPAT_MODE_MSG = 300;
1478    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1479
1480    static ServiceThread sKillThread = null;
1481    static KillHandler sKillHandler = null;
1482
1483    CompatModeDialog mCompatModeDialog;
1484    long mLastMemUsageReportTime = 0;
1485
1486    /**
1487     * Flag whether the current user is a "monkey", i.e. whether
1488     * the UI is driven by a UI automation tool.
1489     */
1490    private boolean mUserIsMonkey;
1491
1492    /** Flag whether the device has a Recents UI */
1493    boolean mHasRecents;
1494
1495    /** The dimensions of the thumbnails in the Recents UI. */
1496    int mThumbnailWidth;
1497    int mThumbnailHeight;
1498    float mFullscreenThumbnailScale;
1499
1500    final ServiceThread mHandlerThread;
1501    final MainHandler mHandler;
1502    final UiHandler mUiHandler;
1503
1504    PackageManagerInternal mPackageManagerInt;
1505
1506    final class KillHandler extends Handler {
1507        static final int KILL_PROCESS_GROUP_MSG = 4000;
1508
1509        public KillHandler(Looper looper) {
1510            super(looper, null, true);
1511        }
1512
1513        @Override
1514        public void handleMessage(Message msg) {
1515            switch (msg.what) {
1516                case KILL_PROCESS_GROUP_MSG:
1517                {
1518                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1519                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1520                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1521                }
1522                break;
1523
1524                default:
1525                    super.handleMessage(msg);
1526            }
1527        }
1528    }
1529
1530    final class UiHandler extends Handler {
1531        public UiHandler() {
1532            super(com.android.server.UiThread.get().getLooper(), null, true);
1533        }
1534
1535        @Override
1536        public void handleMessage(Message msg) {
1537            switch (msg.what) {
1538            case SHOW_ERROR_UI_MSG: {
1539                mAppErrors.handleShowAppErrorUi(msg);
1540                ensureBootCompleted();
1541            } break;
1542            case SHOW_NOT_RESPONDING_UI_MSG: {
1543                mAppErrors.handleShowAnrUi(msg);
1544                ensureBootCompleted();
1545            } break;
1546            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1547                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1548                synchronized (ActivityManagerService.this) {
1549                    ProcessRecord proc = (ProcessRecord) data.get("app");
1550                    if (proc == null) {
1551                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1552                        break;
1553                    }
1554                    if (proc.crashDialog != null) {
1555                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1556                        return;
1557                    }
1558                    AppErrorResult res = (AppErrorResult) data.get("result");
1559                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1560                        Dialog d = new StrictModeViolationDialog(mContext,
1561                                ActivityManagerService.this, res, proc);
1562                        d.show();
1563                        proc.crashDialog = d;
1564                    } else {
1565                        // The device is asleep, so just pretend that the user
1566                        // saw a crash dialog and hit "force quit".
1567                        res.set(0);
1568                    }
1569                }
1570                ensureBootCompleted();
1571            } break;
1572            case SHOW_FACTORY_ERROR_UI_MSG: {
1573                Dialog d = new FactoryErrorDialog(
1574                    mContext, msg.getData().getCharSequence("msg"));
1575                d.show();
1576                ensureBootCompleted();
1577            } break;
1578            case WAIT_FOR_DEBUGGER_UI_MSG: {
1579                synchronized (ActivityManagerService.this) {
1580                    ProcessRecord app = (ProcessRecord)msg.obj;
1581                    if (msg.arg1 != 0) {
1582                        if (!app.waitedForDebugger) {
1583                            Dialog d = new AppWaitingForDebuggerDialog(
1584                                    ActivityManagerService.this,
1585                                    mContext, app);
1586                            app.waitDialog = d;
1587                            app.waitedForDebugger = true;
1588                            d.show();
1589                        }
1590                    } else {
1591                        if (app.waitDialog != null) {
1592                            app.waitDialog.dismiss();
1593                            app.waitDialog = null;
1594                        }
1595                    }
1596                }
1597            } break;
1598            case SHOW_UID_ERROR_UI_MSG: {
1599                if (mShowDialogs) {
1600                    AlertDialog d = new BaseErrorDialog(mContext);
1601                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1602                    d.setCancelable(false);
1603                    d.setTitle(mContext.getText(R.string.android_system_label));
1604                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1605                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1606                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1607                    d.show();
1608                }
1609            } break;
1610            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1611                if (mShowDialogs) {
1612                    AlertDialog d = new BaseErrorDialog(mContext);
1613                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1614                    d.setCancelable(false);
1615                    d.setTitle(mContext.getText(R.string.android_system_label));
1616                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1617                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1618                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1619                    d.show();
1620                }
1621            } break;
1622            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1623                synchronized (ActivityManagerService.this) {
1624                    ActivityRecord ar = (ActivityRecord) msg.obj;
1625                    if (mCompatModeDialog != null) {
1626                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1627                                ar.info.applicationInfo.packageName)) {
1628                            return;
1629                        }
1630                        mCompatModeDialog.dismiss();
1631                        mCompatModeDialog = null;
1632                    }
1633                    if (ar != null && false) {
1634                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1635                                ar.packageName)) {
1636                            int mode = mCompatModePackages.computeCompatModeLocked(
1637                                    ar.info.applicationInfo);
1638                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1639                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1640                                mCompatModeDialog = new CompatModeDialog(
1641                                        ActivityManagerService.this, mContext,
1642                                        ar.info.applicationInfo);
1643                                mCompatModeDialog.show();
1644                            }
1645                        }
1646                    }
1647                }
1648                break;
1649            }
1650            case START_USER_SWITCH_UI_MSG: {
1651                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1652                break;
1653            }
1654            case DISMISS_DIALOG_UI_MSG: {
1655                final Dialog d = (Dialog) msg.obj;
1656                d.dismiss();
1657                break;
1658            }
1659            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1660                dispatchProcessesChanged();
1661                break;
1662            }
1663            case DISPATCH_PROCESS_DIED_UI_MSG: {
1664                final int pid = msg.arg1;
1665                final int uid = msg.arg2;
1666                dispatchProcessDied(pid, uid);
1667                break;
1668            }
1669            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1670                dispatchUidsChanged();
1671            } break;
1672            }
1673        }
1674    }
1675
1676    final class MainHandler extends Handler {
1677        public MainHandler(Looper looper) {
1678            super(looper, null, true);
1679        }
1680
1681        @Override
1682        public void handleMessage(Message msg) {
1683            switch (msg.what) {
1684            case UPDATE_CONFIGURATION_MSG: {
1685                final ContentResolver resolver = mContext.getContentResolver();
1686                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1687                        msg.arg1);
1688            } break;
1689            case GC_BACKGROUND_PROCESSES_MSG: {
1690                synchronized (ActivityManagerService.this) {
1691                    performAppGcsIfAppropriateLocked();
1692                }
1693            } break;
1694            case SERVICE_TIMEOUT_MSG: {
1695                if (mDidDexOpt) {
1696                    mDidDexOpt = false;
1697                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1698                    nmsg.obj = msg.obj;
1699                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1700                    return;
1701                }
1702                mServices.serviceTimeout((ProcessRecord)msg.obj);
1703            } break;
1704            case UPDATE_TIME_ZONE: {
1705                synchronized (ActivityManagerService.this) {
1706                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1707                        ProcessRecord r = mLruProcesses.get(i);
1708                        if (r.thread != null) {
1709                            try {
1710                                r.thread.updateTimeZone();
1711                            } catch (RemoteException ex) {
1712                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1713                            }
1714                        }
1715                    }
1716                }
1717            } break;
1718            case CLEAR_DNS_CACHE_MSG: {
1719                synchronized (ActivityManagerService.this) {
1720                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1721                        ProcessRecord r = mLruProcesses.get(i);
1722                        if (r.thread != null) {
1723                            try {
1724                                r.thread.clearDnsCache();
1725                            } catch (RemoteException ex) {
1726                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1727                            }
1728                        }
1729                    }
1730                }
1731            } break;
1732            case UPDATE_HTTP_PROXY_MSG: {
1733                ProxyInfo proxy = (ProxyInfo)msg.obj;
1734                String host = "";
1735                String port = "";
1736                String exclList = "";
1737                Uri pacFileUrl = Uri.EMPTY;
1738                if (proxy != null) {
1739                    host = proxy.getHost();
1740                    port = Integer.toString(proxy.getPort());
1741                    exclList = proxy.getExclusionListAsString();
1742                    pacFileUrl = proxy.getPacFileUrl();
1743                }
1744                synchronized (ActivityManagerService.this) {
1745                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1746                        ProcessRecord r = mLruProcesses.get(i);
1747                        if (r.thread != null) {
1748                            try {
1749                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1750                            } catch (RemoteException ex) {
1751                                Slog.w(TAG, "Failed to update http proxy for: " +
1752                                        r.info.processName);
1753                            }
1754                        }
1755                    }
1756                }
1757            } break;
1758            case PROC_START_TIMEOUT_MSG: {
1759                if (mDidDexOpt) {
1760                    mDidDexOpt = false;
1761                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1762                    nmsg.obj = msg.obj;
1763                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1764                    return;
1765                }
1766                ProcessRecord app = (ProcessRecord)msg.obj;
1767                synchronized (ActivityManagerService.this) {
1768                    processStartTimedOutLocked(app);
1769                }
1770            } break;
1771            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1772                ProcessRecord app = (ProcessRecord)msg.obj;
1773                synchronized (ActivityManagerService.this) {
1774                    processContentProviderPublishTimedOutLocked(app);
1775                }
1776            } break;
1777            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1778                synchronized (ActivityManagerService.this) {
1779                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1780                }
1781            } break;
1782            case KILL_APPLICATION_MSG: {
1783                synchronized (ActivityManagerService.this) {
1784                    int appid = msg.arg1;
1785                    boolean restart = (msg.arg2 == 1);
1786                    Bundle bundle = (Bundle)msg.obj;
1787                    String pkg = bundle.getString("pkg");
1788                    String reason = bundle.getString("reason");
1789                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1790                            false, UserHandle.USER_ALL, reason);
1791                }
1792            } break;
1793            case FINALIZE_PENDING_INTENT_MSG: {
1794                ((PendingIntentRecord)msg.obj).completeFinalize();
1795            } break;
1796            case POST_HEAVY_NOTIFICATION_MSG: {
1797                INotificationManager inm = NotificationManager.getService();
1798                if (inm == null) {
1799                    return;
1800                }
1801
1802                ActivityRecord root = (ActivityRecord)msg.obj;
1803                ProcessRecord process = root.app;
1804                if (process == null) {
1805                    return;
1806                }
1807
1808                try {
1809                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1810                    String text = mContext.getString(R.string.heavy_weight_notification,
1811                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1812                    Notification notification = new Notification.Builder(context)
1813                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1814                            .setWhen(0)
1815                            .setOngoing(true)
1816                            .setTicker(text)
1817                            .setColor(mContext.getColor(
1818                                    com.android.internal.R.color.system_notification_accent_color))
1819                            .setContentTitle(text)
1820                            .setContentText(
1821                                    mContext.getText(R.string.heavy_weight_notification_detail))
1822                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1823                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1824                                    new UserHandle(root.userId)))
1825                            .build();
1826                    try {
1827                        int[] outId = new int[1];
1828                        inm.enqueueNotificationWithTag("android", "android", null,
1829                                R.string.heavy_weight_notification,
1830                                notification, outId, root.userId);
1831                    } catch (RuntimeException e) {
1832                        Slog.w(ActivityManagerService.TAG,
1833                                "Error showing notification for heavy-weight app", e);
1834                    } catch (RemoteException e) {
1835                    }
1836                } catch (NameNotFoundException e) {
1837                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1838                }
1839            } break;
1840            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1841                INotificationManager inm = NotificationManager.getService();
1842                if (inm == null) {
1843                    return;
1844                }
1845                try {
1846                    inm.cancelNotificationWithTag("android", null,
1847                            R.string.heavy_weight_notification,  msg.arg1);
1848                } catch (RuntimeException e) {
1849                    Slog.w(ActivityManagerService.TAG,
1850                            "Error canceling notification for service", e);
1851                } catch (RemoteException e) {
1852                }
1853            } break;
1854            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1855                synchronized (ActivityManagerService.this) {
1856                    checkExcessivePowerUsageLocked(true);
1857                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1858                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1859                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1860                }
1861            } break;
1862            case REPORT_MEM_USAGE_MSG: {
1863                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1864                Thread thread = new Thread() {
1865                    @Override public void run() {
1866                        reportMemUsage(memInfos);
1867                    }
1868                };
1869                thread.start();
1870                break;
1871            }
1872            case REPORT_USER_SWITCH_MSG: {
1873                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1874                break;
1875            }
1876            case CONTINUE_USER_SWITCH_MSG: {
1877                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1878                break;
1879            }
1880            case USER_SWITCH_TIMEOUT_MSG: {
1881                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1882                break;
1883            }
1884            case IMMERSIVE_MODE_LOCK_MSG: {
1885                final boolean nextState = (msg.arg1 != 0);
1886                if (mUpdateLock.isHeld() != nextState) {
1887                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1888                            "Applying new update lock state '" + nextState
1889                            + "' for " + (ActivityRecord)msg.obj);
1890                    if (nextState) {
1891                        mUpdateLock.acquire();
1892                    } else {
1893                        mUpdateLock.release();
1894                    }
1895                }
1896                break;
1897            }
1898            case PERSIST_URI_GRANTS_MSG: {
1899                writeGrantedUriPermissions();
1900                break;
1901            }
1902            case REQUEST_ALL_PSS_MSG: {
1903                synchronized (ActivityManagerService.this) {
1904                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1905                }
1906                break;
1907            }
1908            case START_PROFILES_MSG: {
1909                synchronized (ActivityManagerService.this) {
1910                    mUserController.startProfilesLocked();
1911                }
1912                break;
1913            }
1914            case UPDATE_TIME: {
1915                synchronized (ActivityManagerService.this) {
1916                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1917                        ProcessRecord r = mLruProcesses.get(i);
1918                        if (r.thread != null) {
1919                            try {
1920                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1921                            } catch (RemoteException ex) {
1922                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1923                            }
1924                        }
1925                    }
1926                }
1927                break;
1928            }
1929            case SYSTEM_USER_START_MSG: {
1930                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1931                        Integer.toString(msg.arg1), msg.arg1);
1932                mSystemServiceManager.startUser(msg.arg1);
1933                break;
1934            }
1935            case SYSTEM_USER_UNLOCK_MSG: {
1936                final int userId = msg.arg1;
1937                mSystemServiceManager.unlockUser(userId);
1938                synchronized (ActivityManagerService.this) {
1939                    mRecentTasks.loadUserRecentsLocked(userId);
1940                }
1941                if (userId == UserHandle.USER_SYSTEM) {
1942                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1943                }
1944                installEncryptionUnawareProviders(userId);
1945                break;
1946            }
1947            case SYSTEM_USER_CURRENT_MSG: {
1948                mBatteryStatsService.noteEvent(
1949                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1950                        Integer.toString(msg.arg2), msg.arg2);
1951                mBatteryStatsService.noteEvent(
1952                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1953                        Integer.toString(msg.arg1), msg.arg1);
1954                mSystemServiceManager.switchUser(msg.arg1);
1955                break;
1956            }
1957            case ENTER_ANIMATION_COMPLETE_MSG: {
1958                synchronized (ActivityManagerService.this) {
1959                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1960                    if (r != null && r.app != null && r.app.thread != null) {
1961                        try {
1962                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1963                        } catch (RemoteException e) {
1964                        }
1965                    }
1966                }
1967                break;
1968            }
1969            case FINISH_BOOTING_MSG: {
1970                if (msg.arg1 != 0) {
1971                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1972                    finishBooting();
1973                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1974                }
1975                if (msg.arg2 != 0) {
1976                    enableScreenAfterBoot();
1977                }
1978                break;
1979            }
1980            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1981                try {
1982                    Locale l = (Locale) msg.obj;
1983                    IBinder service = ServiceManager.getService("mount");
1984                    IMountService mountService = IMountService.Stub.asInterface(service);
1985                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1986                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1987                } catch (RemoteException e) {
1988                    Log.e(TAG, "Error storing locale for decryption UI", e);
1989                }
1990                break;
1991            }
1992            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1993                synchronized (ActivityManagerService.this) {
1994                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1995                        try {
1996                            // Make a one-way callback to the listener
1997                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1998                        } catch (RemoteException e){
1999                            // Handled by the RemoteCallbackList
2000                        }
2001                    }
2002                    mTaskStackListeners.finishBroadcast();
2003                }
2004                break;
2005            }
2006            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2007                synchronized (ActivityManagerService.this) {
2008                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2009                        try {
2010                            // Make a one-way callback to the listener
2011                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2012                        } catch (RemoteException e){
2013                            // Handled by the RemoteCallbackList
2014                        }
2015                    }
2016                    mTaskStackListeners.finishBroadcast();
2017                }
2018                break;
2019            }
2020            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2021                synchronized (ActivityManagerService.this) {
2022                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2023                        try {
2024                            // Make a one-way callback to the listener
2025                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2026                        } catch (RemoteException e){
2027                            // Handled by the RemoteCallbackList
2028                        }
2029                    }
2030                    mTaskStackListeners.finishBroadcast();
2031                }
2032                break;
2033            }
2034            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2035                synchronized (ActivityManagerService.this) {
2036                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2037                        try {
2038                            // Make a one-way callback to the listener
2039                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2040                        } catch (RemoteException e){
2041                            // Handled by the RemoteCallbackList
2042                        }
2043                    }
2044                    mTaskStackListeners.finishBroadcast();
2045                }
2046                break;
2047            }
2048            case NOTIFY_FORCED_RESIZABLE_MSG: {
2049                synchronized (ActivityManagerService.this) {
2050                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2051                        try {
2052                            // Make a one-way callback to the listener
2053                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2054                                    (String) msg.obj, msg.arg1);
2055                        } catch (RemoteException e){
2056                            // Handled by the RemoteCallbackList
2057                        }
2058                    }
2059                    mTaskStackListeners.finishBroadcast();
2060                }
2061                break;
2062            }
2063                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2064                    synchronized (ActivityManagerService.this) {
2065                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2066                            try {
2067                                // Make a one-way callback to the listener
2068                                mTaskStackListeners.getBroadcastItem(i)
2069                                        .onActivityDismissingDockedStack();
2070                            } catch (RemoteException e){
2071                                // Handled by the RemoteCallbackList
2072                            }
2073                        }
2074                        mTaskStackListeners.finishBroadcast();
2075                    }
2076                    break;
2077                }
2078            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2079                final int uid = msg.arg1;
2080                final byte[] firstPacket = (byte[]) msg.obj;
2081
2082                synchronized (mPidsSelfLocked) {
2083                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2084                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2085                        if (p.uid == uid) {
2086                            try {
2087                                p.thread.notifyCleartextNetwork(firstPacket);
2088                            } catch (RemoteException ignored) {
2089                            }
2090                        }
2091                    }
2092                }
2093                break;
2094            }
2095            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2096                final String procName;
2097                final int uid;
2098                final long memLimit;
2099                final String reportPackage;
2100                synchronized (ActivityManagerService.this) {
2101                    procName = mMemWatchDumpProcName;
2102                    uid = mMemWatchDumpUid;
2103                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2104                    if (val == null) {
2105                        val = mMemWatchProcesses.get(procName, 0);
2106                    }
2107                    if (val != null) {
2108                        memLimit = val.first;
2109                        reportPackage = val.second;
2110                    } else {
2111                        memLimit = 0;
2112                        reportPackage = null;
2113                    }
2114                }
2115                if (procName == null) {
2116                    return;
2117                }
2118
2119                if (DEBUG_PSS) Slog.d(TAG_PSS,
2120                        "Showing dump heap notification from " + procName + "/" + uid);
2121
2122                INotificationManager inm = NotificationManager.getService();
2123                if (inm == null) {
2124                    return;
2125                }
2126
2127                String text = mContext.getString(R.string.dump_heap_notification, procName);
2128
2129
2130                Intent deleteIntent = new Intent();
2131                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2132                Intent intent = new Intent();
2133                intent.setClassName("android", DumpHeapActivity.class.getName());
2134                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2135                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2136                if (reportPackage != null) {
2137                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2138                }
2139                int userId = UserHandle.getUserId(uid);
2140                Notification notification = new Notification.Builder(mContext)
2141                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2142                        .setWhen(0)
2143                        .setOngoing(true)
2144                        .setAutoCancel(true)
2145                        .setTicker(text)
2146                        .setColor(mContext.getColor(
2147                                com.android.internal.R.color.system_notification_accent_color))
2148                        .setContentTitle(text)
2149                        .setContentText(
2150                                mContext.getText(R.string.dump_heap_notification_detail))
2151                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2152                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2153                                new UserHandle(userId)))
2154                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2155                                deleteIntent, 0, UserHandle.SYSTEM))
2156                        .build();
2157
2158                try {
2159                    int[] outId = new int[1];
2160                    inm.enqueueNotificationWithTag("android", "android", null,
2161                            R.string.dump_heap_notification,
2162                            notification, outId, userId);
2163                } catch (RuntimeException e) {
2164                    Slog.w(ActivityManagerService.TAG,
2165                            "Error showing notification for dump heap", e);
2166                } catch (RemoteException e) {
2167                }
2168            } break;
2169            case DELETE_DUMPHEAP_MSG: {
2170                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2171                        DumpHeapActivity.JAVA_URI,
2172                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2173                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2174                        UserHandle.myUserId());
2175                synchronized (ActivityManagerService.this) {
2176                    mMemWatchDumpFile = null;
2177                    mMemWatchDumpProcName = null;
2178                    mMemWatchDumpPid = -1;
2179                    mMemWatchDumpUid = -1;
2180                }
2181            } break;
2182            case FOREGROUND_PROFILE_CHANGED_MSG: {
2183                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2184            } break;
2185            case REPORT_TIME_TRACKER_MSG: {
2186                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2187                tracker.deliverResult(mContext);
2188            } break;
2189            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2190                mUserController.dispatchUserSwitchComplete(msg.arg1);
2191            } break;
2192            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2193                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2194                try {
2195                    connection.shutdown();
2196                } catch (RemoteException e) {
2197                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2198                }
2199                // Only a UiAutomation can set this flag and now that
2200                // it is finished we make sure it is reset to its default.
2201                mUserIsMonkey = false;
2202            } break;
2203            case APP_BOOST_DEACTIVATE_MSG: {
2204                synchronized(ActivityManagerService.this) {
2205                    if (mIsBoosted) {
2206                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2207                            nativeMigrateFromBoost();
2208                            mIsBoosted = false;
2209                            mBoostStartTime = 0;
2210                        } else {
2211                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2212                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2213                        }
2214                    }
2215                }
2216            } break;
2217            case IDLE_UIDS_MSG: {
2218                idleUids();
2219            } break;
2220            case LOG_STACK_STATE: {
2221                synchronized (ActivityManagerService.this) {
2222                    mStackSupervisor.logStackState();
2223                }
2224            } break;
2225            case VR_MODE_CHANGE_MSG: {
2226                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2227                final ActivityRecord r = (ActivityRecord) msg.obj;
2228                boolean vrMode;
2229                ComponentName requestedPackage;
2230                ComponentName callingPackage;
2231                int userId;
2232                synchronized (ActivityManagerService.this) {
2233                    vrMode = r.requestedVrComponent != null;
2234                    requestedPackage = r.requestedVrComponent;
2235                    userId = r.userId;
2236                    callingPackage = r.info.getComponentName();
2237                    if (mInVrMode != vrMode) {
2238                        mInVrMode = vrMode;
2239                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2240                    }
2241                }
2242                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2243            } break;
2244            }
2245        }
2246    };
2247
2248    static final int COLLECT_PSS_BG_MSG = 1;
2249
2250    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2251        @Override
2252        public void handleMessage(Message msg) {
2253            switch (msg.what) {
2254            case COLLECT_PSS_BG_MSG: {
2255                long start = SystemClock.uptimeMillis();
2256                MemInfoReader memInfo = null;
2257                synchronized (ActivityManagerService.this) {
2258                    if (mFullPssPending) {
2259                        mFullPssPending = false;
2260                        memInfo = new MemInfoReader();
2261                    }
2262                }
2263                if (memInfo != null) {
2264                    updateCpuStatsNow();
2265                    long nativeTotalPss = 0;
2266                    synchronized (mProcessCpuTracker) {
2267                        final int N = mProcessCpuTracker.countStats();
2268                        for (int j=0; j<N; j++) {
2269                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2270                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2271                                // This is definitely an application process; skip it.
2272                                continue;
2273                            }
2274                            synchronized (mPidsSelfLocked) {
2275                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2276                                    // This is one of our own processes; skip it.
2277                                    continue;
2278                                }
2279                            }
2280                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2281                        }
2282                    }
2283                    memInfo.readMemInfo();
2284                    synchronized (ActivityManagerService.this) {
2285                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2286                                + (SystemClock.uptimeMillis()-start) + "ms");
2287                        final long cachedKb = memInfo.getCachedSizeKb();
2288                        final long freeKb = memInfo.getFreeSizeKb();
2289                        final long zramKb = memInfo.getZramTotalSizeKb();
2290                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2291                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2292                                kernelKb*1024, nativeTotalPss*1024);
2293                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2294                                nativeTotalPss);
2295                    }
2296                }
2297
2298                int num = 0;
2299                long[] tmp = new long[2];
2300                do {
2301                    ProcessRecord proc;
2302                    int procState;
2303                    int pid;
2304                    long lastPssTime;
2305                    synchronized (ActivityManagerService.this) {
2306                        if (mPendingPssProcesses.size() <= 0) {
2307                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2308                                    "Collected PSS of " + num + " processes in "
2309                                    + (SystemClock.uptimeMillis() - start) + "ms");
2310                            mPendingPssProcesses.clear();
2311                            return;
2312                        }
2313                        proc = mPendingPssProcesses.remove(0);
2314                        procState = proc.pssProcState;
2315                        lastPssTime = proc.lastPssTime;
2316                        if (proc.thread != null && procState == proc.setProcState
2317                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2318                                        < SystemClock.uptimeMillis()) {
2319                            pid = proc.pid;
2320                        } else {
2321                            proc = null;
2322                            pid = 0;
2323                        }
2324                    }
2325                    if (proc != null) {
2326                        long pss = Debug.getPss(pid, tmp, null);
2327                        synchronized (ActivityManagerService.this) {
2328                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2329                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2330                                num++;
2331                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2332                                        SystemClock.uptimeMillis());
2333                            }
2334                        }
2335                    }
2336                } while (true);
2337            }
2338            }
2339        }
2340    };
2341
2342    public void setSystemProcess() {
2343        try {
2344            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2345            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2346            ServiceManager.addService("meminfo", new MemBinder(this));
2347            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2348            ServiceManager.addService("dbinfo", new DbBinder(this));
2349            if (MONITOR_CPU_USAGE) {
2350                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2351            }
2352            ServiceManager.addService("permission", new PermissionController(this));
2353            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2354
2355            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2356                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2357            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2358
2359            synchronized (this) {
2360                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2361                app.persistent = true;
2362                app.pid = MY_PID;
2363                app.maxAdj = ProcessList.SYSTEM_ADJ;
2364                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2365                synchronized (mPidsSelfLocked) {
2366                    mPidsSelfLocked.put(app.pid, app);
2367                }
2368                updateLruProcessLocked(app, false, null);
2369                updateOomAdjLocked();
2370            }
2371        } catch (PackageManager.NameNotFoundException e) {
2372            throw new RuntimeException(
2373                    "Unable to find android system package", e);
2374        }
2375    }
2376
2377    public void setWindowManager(WindowManagerService wm) {
2378        mWindowManager = wm;
2379        mStackSupervisor.setWindowManager(wm);
2380        mActivityStarter.setWindowManager(wm);
2381    }
2382
2383    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2384        mUsageStatsService = usageStatsManager;
2385    }
2386
2387    public void startObservingNativeCrashes() {
2388        final NativeCrashListener ncl = new NativeCrashListener(this);
2389        ncl.start();
2390    }
2391
2392    public IAppOpsService getAppOpsService() {
2393        return mAppOpsService;
2394    }
2395
2396    static class MemBinder extends Binder {
2397        ActivityManagerService mActivityManagerService;
2398        MemBinder(ActivityManagerService activityManagerService) {
2399            mActivityManagerService = activityManagerService;
2400        }
2401
2402        @Override
2403        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2404            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2405                    != PackageManager.PERMISSION_GRANTED) {
2406                pw.println("Permission Denial: can't dump meminfo from from pid="
2407                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2408                        + " without permission " + android.Manifest.permission.DUMP);
2409                return;
2410            }
2411
2412            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2413        }
2414    }
2415
2416    static class GraphicsBinder extends Binder {
2417        ActivityManagerService mActivityManagerService;
2418        GraphicsBinder(ActivityManagerService activityManagerService) {
2419            mActivityManagerService = activityManagerService;
2420        }
2421
2422        @Override
2423        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2424            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2425                    != PackageManager.PERMISSION_GRANTED) {
2426                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2427                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2428                        + " without permission " + android.Manifest.permission.DUMP);
2429                return;
2430            }
2431
2432            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2433        }
2434    }
2435
2436    static class DbBinder extends Binder {
2437        ActivityManagerService mActivityManagerService;
2438        DbBinder(ActivityManagerService activityManagerService) {
2439            mActivityManagerService = activityManagerService;
2440        }
2441
2442        @Override
2443        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2444            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2445                    != PackageManager.PERMISSION_GRANTED) {
2446                pw.println("Permission Denial: can't dump dbinfo from from pid="
2447                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2448                        + " without permission " + android.Manifest.permission.DUMP);
2449                return;
2450            }
2451
2452            mActivityManagerService.dumpDbInfo(fd, pw, args);
2453        }
2454    }
2455
2456    static class CpuBinder extends Binder {
2457        ActivityManagerService mActivityManagerService;
2458        CpuBinder(ActivityManagerService activityManagerService) {
2459            mActivityManagerService = activityManagerService;
2460        }
2461
2462        @Override
2463        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2464            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2465                    != PackageManager.PERMISSION_GRANTED) {
2466                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2467                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2468                        + " without permission " + android.Manifest.permission.DUMP);
2469                return;
2470            }
2471
2472            synchronized (mActivityManagerService.mProcessCpuTracker) {
2473                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2474                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2475                        SystemClock.uptimeMillis()));
2476            }
2477        }
2478    }
2479
2480    public static final class Lifecycle extends SystemService {
2481        private final ActivityManagerService mService;
2482
2483        public Lifecycle(Context context) {
2484            super(context);
2485            mService = new ActivityManagerService(context);
2486        }
2487
2488        @Override
2489        public void onStart() {
2490            mService.start();
2491        }
2492
2493        public ActivityManagerService getService() {
2494            return mService;
2495        }
2496    }
2497
2498    // Note: This method is invoked on the main thread but may need to attach various
2499    // handlers to other threads.  So take care to be explicit about the looper.
2500    public ActivityManagerService(Context systemContext) {
2501        mContext = systemContext;
2502        mFactoryTest = FactoryTest.getMode();
2503        mSystemThread = ActivityThread.currentActivityThread();
2504
2505        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2506
2507        mHandlerThread = new ServiceThread(TAG,
2508                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2509        mHandlerThread.start();
2510        mHandler = new MainHandler(mHandlerThread.getLooper());
2511        mUiHandler = new UiHandler();
2512
2513        /* static; one-time init here */
2514        if (sKillHandler == null) {
2515            sKillThread = new ServiceThread(TAG + ":kill",
2516                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2517            sKillThread.start();
2518            sKillHandler = new KillHandler(sKillThread.getLooper());
2519        }
2520
2521        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2522                "foreground", BROADCAST_FG_TIMEOUT, false);
2523        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2524                "background", BROADCAST_BG_TIMEOUT, true);
2525        mBroadcastQueues[0] = mFgBroadcastQueue;
2526        mBroadcastQueues[1] = mBgBroadcastQueue;
2527
2528        mServices = new ActiveServices(this);
2529        mProviderMap = new ProviderMap(this);
2530        mAppErrors = new AppErrors(mContext, this);
2531
2532        // TODO: Move creation of battery stats service outside of activity manager service.
2533        File dataDir = Environment.getDataDirectory();
2534        File systemDir = new File(dataDir, "system");
2535        systemDir.mkdirs();
2536        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2537        mBatteryStatsService.getActiveStatistics().readLocked();
2538        mBatteryStatsService.scheduleWriteToDisk();
2539        mOnBattery = DEBUG_POWER ? true
2540                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2541        mBatteryStatsService.getActiveStatistics().setCallback(this);
2542
2543        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2544
2545        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2546        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2547                new IAppOpsCallback.Stub() {
2548                    @Override public void opChanged(int op, int uid, String packageName) {
2549                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2550                            if (mAppOpsService.checkOperation(op, uid, packageName)
2551                                    != AppOpsManager.MODE_ALLOWED) {
2552                                runInBackgroundDisabled(uid);
2553                            }
2554                        }
2555                    }
2556                });
2557
2558        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2559
2560        mUserController = new UserController(this);
2561
2562        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2563            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2564
2565        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2566
2567        mConfiguration.setToDefaults();
2568        mConfiguration.setLocales(LocaleList.getDefault());
2569
2570        mConfigurationSeq = mConfiguration.seq = 1;
2571        mProcessCpuTracker.init();
2572
2573        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2574        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2575        mStackSupervisor = new ActivityStackSupervisor(this);
2576        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2577        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2578
2579        mProcessCpuThread = new Thread("CpuTracker") {
2580            @Override
2581            public void run() {
2582                while (true) {
2583                    try {
2584                        try {
2585                            synchronized(this) {
2586                                final long now = SystemClock.uptimeMillis();
2587                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2588                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2589                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2590                                //        + ", write delay=" + nextWriteDelay);
2591                                if (nextWriteDelay < nextCpuDelay) {
2592                                    nextCpuDelay = nextWriteDelay;
2593                                }
2594                                if (nextCpuDelay > 0) {
2595                                    mProcessCpuMutexFree.set(true);
2596                                    this.wait(nextCpuDelay);
2597                                }
2598                            }
2599                        } catch (InterruptedException e) {
2600                        }
2601                        updateCpuStatsNow();
2602                    } catch (Exception e) {
2603                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2604                    }
2605                }
2606            }
2607        };
2608
2609        Watchdog.getInstance().addMonitor(this);
2610        Watchdog.getInstance().addThread(mHandler);
2611    }
2612
2613    public void setSystemServiceManager(SystemServiceManager mgr) {
2614        mSystemServiceManager = mgr;
2615    }
2616
2617    public void setInstaller(Installer installer) {
2618        mInstaller = installer;
2619    }
2620
2621    private void start() {
2622        Process.removeAllProcessGroups();
2623        mProcessCpuThread.start();
2624
2625        mBatteryStatsService.publish(mContext);
2626        mAppOpsService.publish(mContext);
2627        Slog.d("AppOps", "AppOpsService published");
2628        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2629    }
2630
2631    void onUserStoppedLocked(int userId) {
2632        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2633    }
2634
2635    public void initPowerManagement() {
2636        mStackSupervisor.initPowerManagement();
2637        mBatteryStatsService.initPowerManagement();
2638        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2639        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2640        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2641        mVoiceWakeLock.setReferenceCounted(false);
2642    }
2643
2644    @Override
2645    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2646            throws RemoteException {
2647        if (code == SYSPROPS_TRANSACTION) {
2648            // We need to tell all apps about the system property change.
2649            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2650            synchronized(this) {
2651                final int NP = mProcessNames.getMap().size();
2652                for (int ip=0; ip<NP; ip++) {
2653                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2654                    final int NA = apps.size();
2655                    for (int ia=0; ia<NA; ia++) {
2656                        ProcessRecord app = apps.valueAt(ia);
2657                        if (app.thread != null) {
2658                            procs.add(app.thread.asBinder());
2659                        }
2660                    }
2661                }
2662            }
2663
2664            int N = procs.size();
2665            for (int i=0; i<N; i++) {
2666                Parcel data2 = Parcel.obtain();
2667                try {
2668                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2669                } catch (RemoteException e) {
2670                }
2671                data2.recycle();
2672            }
2673        }
2674        try {
2675            return super.onTransact(code, data, reply, flags);
2676        } catch (RuntimeException e) {
2677            // The activity manager only throws security exceptions, so let's
2678            // log all others.
2679            if (!(e instanceof SecurityException)) {
2680                Slog.wtf(TAG, "Activity Manager Crash", e);
2681            }
2682            throw e;
2683        }
2684    }
2685
2686    void updateCpuStats() {
2687        final long now = SystemClock.uptimeMillis();
2688        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2689            return;
2690        }
2691        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2692            synchronized (mProcessCpuThread) {
2693                mProcessCpuThread.notify();
2694            }
2695        }
2696    }
2697
2698    void updateCpuStatsNow() {
2699        synchronized (mProcessCpuTracker) {
2700            mProcessCpuMutexFree.set(false);
2701            final long now = SystemClock.uptimeMillis();
2702            boolean haveNewCpuStats = false;
2703
2704            if (MONITOR_CPU_USAGE &&
2705                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2706                mLastCpuTime.set(now);
2707                mProcessCpuTracker.update();
2708                if (mProcessCpuTracker.hasGoodLastStats()) {
2709                    haveNewCpuStats = true;
2710                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2711                    //Slog.i(TAG, "Total CPU usage: "
2712                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2713
2714                    // Slog the cpu usage if the property is set.
2715                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2716                        int user = mProcessCpuTracker.getLastUserTime();
2717                        int system = mProcessCpuTracker.getLastSystemTime();
2718                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2719                        int irq = mProcessCpuTracker.getLastIrqTime();
2720                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2721                        int idle = mProcessCpuTracker.getLastIdleTime();
2722
2723                        int total = user + system + iowait + irq + softIrq + idle;
2724                        if (total == 0) total = 1;
2725
2726                        EventLog.writeEvent(EventLogTags.CPU,
2727                                ((user+system+iowait+irq+softIrq) * 100) / total,
2728                                (user * 100) / total,
2729                                (system * 100) / total,
2730                                (iowait * 100) / total,
2731                                (irq * 100) / total,
2732                                (softIrq * 100) / total);
2733                    }
2734                }
2735            }
2736
2737            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2738            synchronized(bstats) {
2739                synchronized(mPidsSelfLocked) {
2740                    if (haveNewCpuStats) {
2741                        if (bstats.startAddingCpuLocked()) {
2742                            int totalUTime = 0;
2743                            int totalSTime = 0;
2744                            final int N = mProcessCpuTracker.countStats();
2745                            for (int i=0; i<N; i++) {
2746                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2747                                if (!st.working) {
2748                                    continue;
2749                                }
2750                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2751                                totalUTime += st.rel_utime;
2752                                totalSTime += st.rel_stime;
2753                                if (pr != null) {
2754                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2755                                    if (ps == null || !ps.isActive()) {
2756                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2757                                                pr.info.uid, pr.processName);
2758                                    }
2759                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2760                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2761                                } else {
2762                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2763                                    if (ps == null || !ps.isActive()) {
2764                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2765                                                bstats.mapUid(st.uid), st.name);
2766                                    }
2767                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2768                                }
2769                            }
2770                            final int userTime = mProcessCpuTracker.getLastUserTime();
2771                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2772                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2773                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2774                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2775                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2776                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2777                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2778                        }
2779                    }
2780                }
2781
2782                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2783                    mLastWriteTime = now;
2784                    mBatteryStatsService.scheduleWriteToDisk();
2785                }
2786            }
2787        }
2788    }
2789
2790    @Override
2791    public void batteryNeedsCpuUpdate() {
2792        updateCpuStatsNow();
2793    }
2794
2795    @Override
2796    public void batteryPowerChanged(boolean onBattery) {
2797        // When plugging in, update the CPU stats first before changing
2798        // the plug state.
2799        updateCpuStatsNow();
2800        synchronized (this) {
2801            synchronized(mPidsSelfLocked) {
2802                mOnBattery = DEBUG_POWER ? true : onBattery;
2803            }
2804        }
2805    }
2806
2807    @Override
2808    public void batterySendBroadcast(Intent intent) {
2809        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2810                AppOpsManager.OP_NONE, null, false, false,
2811                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2812    }
2813
2814    /**
2815     * Initialize the application bind args. These are passed to each
2816     * process when the bindApplication() IPC is sent to the process. They're
2817     * lazily setup to make sure the services are running when they're asked for.
2818     */
2819    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2820        if (mAppBindArgs == null) {
2821            mAppBindArgs = new HashMap<>();
2822
2823            // Isolated processes won't get this optimization, so that we don't
2824            // violate the rules about which services they have access to.
2825            if (!isolated) {
2826                // Setup the application init args
2827                mAppBindArgs.put("package", ServiceManager.getService("package"));
2828                mAppBindArgs.put("window", ServiceManager.getService("window"));
2829                mAppBindArgs.put(Context.ALARM_SERVICE,
2830                        ServiceManager.getService(Context.ALARM_SERVICE));
2831            }
2832        }
2833        return mAppBindArgs;
2834    }
2835
2836    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2837        if (r == null || mFocusedActivity == r) {
2838            return false;
2839        }
2840
2841        if (!r.isFocusable()) {
2842            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2843            return false;
2844        }
2845
2846        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2847
2848        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2849        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2850                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2851        mDoingSetFocusedActivity = true;
2852
2853        final ActivityRecord last = mFocusedActivity;
2854        mFocusedActivity = r;
2855        if (r.task.isApplicationTask()) {
2856            if (mCurAppTimeTracker != r.appTimeTracker) {
2857                // We are switching app tracking.  Complete the current one.
2858                if (mCurAppTimeTracker != null) {
2859                    mCurAppTimeTracker.stop();
2860                    mHandler.obtainMessage(
2861                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2862                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2863                    mCurAppTimeTracker = null;
2864                }
2865                if (r.appTimeTracker != null) {
2866                    mCurAppTimeTracker = r.appTimeTracker;
2867                    startTimeTrackingFocusedActivityLocked();
2868                }
2869            } else {
2870                startTimeTrackingFocusedActivityLocked();
2871            }
2872        } else {
2873            r.appTimeTracker = null;
2874        }
2875        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2876        // TODO: Probably not, because we don't want to resume voice on switching
2877        // back to this activity
2878        if (r.task.voiceInteractor != null) {
2879            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2880        } else {
2881            finishRunningVoiceLocked();
2882            IVoiceInteractionSession session;
2883            if (last != null && ((session = last.task.voiceSession) != null
2884                    || (session = last.voiceSession) != null)) {
2885                // We had been in a voice interaction session, but now focused has
2886                // move to something different.  Just finish the session, we can't
2887                // return to it and retain the proper state and synchronization with
2888                // the voice interaction service.
2889                finishVoiceTask(session);
2890            }
2891        }
2892        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2893            mWindowManager.setFocusedApp(r.appToken, true);
2894        }
2895        applyUpdateLockStateLocked(r);
2896        applyUpdateVrModeLocked(r);
2897        if (mFocusedActivity.userId != mLastFocusedUserId) {
2898            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2899            mHandler.obtainMessage(
2900                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2901            mLastFocusedUserId = mFocusedActivity.userId;
2902        }
2903
2904        // Log a warning if the focused app is changed during the process. This could
2905        // indicate a problem of the focus setting logic!
2906        if (mFocusedActivity != r) Slog.w(TAG,
2907                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2908        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2909
2910        EventLogTags.writeAmFocusedActivity(
2911                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2912                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2913                reason);
2914        return true;
2915    }
2916
2917    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2918        if (mFocusedActivity != goingAway) {
2919            return;
2920        }
2921
2922        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2923        if (focusedStack != null) {
2924            final ActivityRecord top = focusedStack.topActivity();
2925            if (top != null && top.userId != mLastFocusedUserId) {
2926                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2927                mHandler.sendMessage(
2928                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2929                mLastFocusedUserId = top.userId;
2930            }
2931        }
2932
2933        // Try to move focus to another activity if possible.
2934        if (setFocusedActivityLocked(
2935                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2936            return;
2937        }
2938
2939        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2940                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2941        mFocusedActivity = null;
2942        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2943    }
2944
2945    @Override
2946    public void setFocusedStack(int stackId) {
2947        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2948        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2949        final long callingId = Binder.clearCallingIdentity();
2950        try {
2951            synchronized (this) {
2952                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2953                if (stack == null) {
2954                    return;
2955                }
2956                final ActivityRecord r = stack.topRunningActivityLocked();
2957                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2958                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2959                }
2960            }
2961        } finally {
2962            Binder.restoreCallingIdentity(callingId);
2963        }
2964    }
2965
2966    @Override
2967    public void setFocusedTask(int taskId) {
2968        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2969        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2970        final long callingId = Binder.clearCallingIdentity();
2971        try {
2972            synchronized (this) {
2973                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2974                if (task == null) {
2975                    return;
2976                }
2977                final ActivityRecord r = task.topRunningActivityLocked();
2978                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2979                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2980                }
2981            }
2982        } finally {
2983            Binder.restoreCallingIdentity(callingId);
2984        }
2985    }
2986
2987    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2988    @Override
2989    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2990        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2991        synchronized (this) {
2992            if (listener != null) {
2993                mTaskStackListeners.register(listener);
2994            }
2995        }
2996    }
2997
2998    @Override
2999    public void notifyActivityDrawn(IBinder token) {
3000        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3001        synchronized (this) {
3002            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3003            if (r != null) {
3004                r.task.stack.notifyActivityDrawnLocked(r);
3005            }
3006        }
3007    }
3008
3009    final void applyUpdateLockStateLocked(ActivityRecord r) {
3010        // Modifications to the UpdateLock state are done on our handler, outside
3011        // the activity manager's locks.  The new state is determined based on the
3012        // state *now* of the relevant activity record.  The object is passed to
3013        // the handler solely for logging detail, not to be consulted/modified.
3014        final boolean nextState = r != null && r.immersive;
3015        mHandler.sendMessage(
3016                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3017    }
3018
3019    final void applyUpdateVrModeLocked(ActivityRecord r) {
3020        mHandler.sendMessage(
3021                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3022    }
3023
3024    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3025        Message msg = Message.obtain();
3026        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3027        msg.obj = r.task.askedCompatMode ? null : r;
3028        mUiHandler.sendMessage(msg);
3029    }
3030
3031    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3032            String what, Object obj, ProcessRecord srcApp) {
3033        app.lastActivityTime = now;
3034
3035        if (app.activities.size() > 0) {
3036            // Don't want to touch dependent processes that are hosting activities.
3037            return index;
3038        }
3039
3040        int lrui = mLruProcesses.lastIndexOf(app);
3041        if (lrui < 0) {
3042            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3043                    + what + " " + obj + " from " + srcApp);
3044            return index;
3045        }
3046
3047        if (lrui >= index) {
3048            // Don't want to cause this to move dependent processes *back* in the
3049            // list as if they were less frequently used.
3050            return index;
3051        }
3052
3053        if (lrui >= mLruProcessActivityStart) {
3054            // Don't want to touch dependent processes that are hosting activities.
3055            return index;
3056        }
3057
3058        mLruProcesses.remove(lrui);
3059        if (index > 0) {
3060            index--;
3061        }
3062        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3063                + " in LRU list: " + app);
3064        mLruProcesses.add(index, app);
3065        return index;
3066    }
3067
3068    static void killProcessGroup(int uid, int pid) {
3069        if (sKillHandler != null) {
3070            sKillHandler.sendMessage(
3071                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3072        } else {
3073            Slog.w(TAG, "Asked to kill process group before system bringup!");
3074            Process.killProcessGroup(uid, pid);
3075        }
3076    }
3077
3078    final void removeLruProcessLocked(ProcessRecord app) {
3079        int lrui = mLruProcesses.lastIndexOf(app);
3080        if (lrui >= 0) {
3081            if (!app.killed) {
3082                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3083                Process.killProcessQuiet(app.pid);
3084                killProcessGroup(app.uid, app.pid);
3085            }
3086            if (lrui <= mLruProcessActivityStart) {
3087                mLruProcessActivityStart--;
3088            }
3089            if (lrui <= mLruProcessServiceStart) {
3090                mLruProcessServiceStart--;
3091            }
3092            mLruProcesses.remove(lrui);
3093        }
3094    }
3095
3096    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3097            ProcessRecord client) {
3098        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3099                || app.treatLikeActivity;
3100        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3101        if (!activityChange && hasActivity) {
3102            // The process has activities, so we are only allowing activity-based adjustments
3103            // to move it.  It should be kept in the front of the list with other
3104            // processes that have activities, and we don't want those to change their
3105            // order except due to activity operations.
3106            return;
3107        }
3108
3109        mLruSeq++;
3110        final long now = SystemClock.uptimeMillis();
3111        app.lastActivityTime = now;
3112
3113        // First a quick reject: if the app is already at the position we will
3114        // put it, then there is nothing to do.
3115        if (hasActivity) {
3116            final int N = mLruProcesses.size();
3117            if (N > 0 && mLruProcesses.get(N-1) == app) {
3118                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3119                return;
3120            }
3121        } else {
3122            if (mLruProcessServiceStart > 0
3123                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3124                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3125                return;
3126            }
3127        }
3128
3129        int lrui = mLruProcesses.lastIndexOf(app);
3130
3131        if (app.persistent && lrui >= 0) {
3132            // We don't care about the position of persistent processes, as long as
3133            // they are in the list.
3134            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3135            return;
3136        }
3137
3138        /* In progress: compute new position first, so we can avoid doing work
3139           if the process is not actually going to move.  Not yet working.
3140        int addIndex;
3141        int nextIndex;
3142        boolean inActivity = false, inService = false;
3143        if (hasActivity) {
3144            // Process has activities, put it at the very tipsy-top.
3145            addIndex = mLruProcesses.size();
3146            nextIndex = mLruProcessServiceStart;
3147            inActivity = true;
3148        } else if (hasService) {
3149            // Process has services, put it at the top of the service list.
3150            addIndex = mLruProcessActivityStart;
3151            nextIndex = mLruProcessServiceStart;
3152            inActivity = true;
3153            inService = true;
3154        } else  {
3155            // Process not otherwise of interest, it goes to the top of the non-service area.
3156            addIndex = mLruProcessServiceStart;
3157            if (client != null) {
3158                int clientIndex = mLruProcesses.lastIndexOf(client);
3159                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3160                        + app);
3161                if (clientIndex >= 0 && addIndex > clientIndex) {
3162                    addIndex = clientIndex;
3163                }
3164            }
3165            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3166        }
3167
3168        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3169                + mLruProcessActivityStart + "): " + app);
3170        */
3171
3172        if (lrui >= 0) {
3173            if (lrui < mLruProcessActivityStart) {
3174                mLruProcessActivityStart--;
3175            }
3176            if (lrui < mLruProcessServiceStart) {
3177                mLruProcessServiceStart--;
3178            }
3179            /*
3180            if (addIndex > lrui) {
3181                addIndex--;
3182            }
3183            if (nextIndex > lrui) {
3184                nextIndex--;
3185            }
3186            */
3187            mLruProcesses.remove(lrui);
3188        }
3189
3190        /*
3191        mLruProcesses.add(addIndex, app);
3192        if (inActivity) {
3193            mLruProcessActivityStart++;
3194        }
3195        if (inService) {
3196            mLruProcessActivityStart++;
3197        }
3198        */
3199
3200        int nextIndex;
3201        if (hasActivity) {
3202            final int N = mLruProcesses.size();
3203            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3204                // Process doesn't have activities, but has clients with
3205                // activities...  move it up, but one below the top (the top
3206                // should always have a real activity).
3207                if (DEBUG_LRU) Slog.d(TAG_LRU,
3208                        "Adding to second-top of LRU activity list: " + app);
3209                mLruProcesses.add(N - 1, app);
3210                // To keep it from spamming the LRU list (by making a bunch of clients),
3211                // we will push down any other entries owned by the app.
3212                final int uid = app.info.uid;
3213                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3214                    ProcessRecord subProc = mLruProcesses.get(i);
3215                    if (subProc.info.uid == uid) {
3216                        // We want to push this one down the list.  If the process after
3217                        // it is for the same uid, however, don't do so, because we don't
3218                        // want them internally to be re-ordered.
3219                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3220                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3221                                    "Pushing uid " + uid + " swapping at " + i + ": "
3222                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3223                            ProcessRecord tmp = mLruProcesses.get(i);
3224                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3225                            mLruProcesses.set(i - 1, tmp);
3226                            i--;
3227                        }
3228                    } else {
3229                        // A gap, we can stop here.
3230                        break;
3231                    }
3232                }
3233            } else {
3234                // Process has activities, put it at the very tipsy-top.
3235                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3236                mLruProcesses.add(app);
3237            }
3238            nextIndex = mLruProcessServiceStart;
3239        } else if (hasService) {
3240            // Process has services, put it at the top of the service list.
3241            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3242            mLruProcesses.add(mLruProcessActivityStart, app);
3243            nextIndex = mLruProcessServiceStart;
3244            mLruProcessActivityStart++;
3245        } else  {
3246            // Process not otherwise of interest, it goes to the top of the non-service area.
3247            int index = mLruProcessServiceStart;
3248            if (client != null) {
3249                // If there is a client, don't allow the process to be moved up higher
3250                // in the list than that client.
3251                int clientIndex = mLruProcesses.lastIndexOf(client);
3252                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3253                        + " when updating " + app);
3254                if (clientIndex <= lrui) {
3255                    // Don't allow the client index restriction to push it down farther in the
3256                    // list than it already is.
3257                    clientIndex = lrui;
3258                }
3259                if (clientIndex >= 0 && index > clientIndex) {
3260                    index = clientIndex;
3261                }
3262            }
3263            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3264            mLruProcesses.add(index, app);
3265            nextIndex = index-1;
3266            mLruProcessActivityStart++;
3267            mLruProcessServiceStart++;
3268        }
3269
3270        // If the app is currently using a content provider or service,
3271        // bump those processes as well.
3272        for (int j=app.connections.size()-1; j>=0; j--) {
3273            ConnectionRecord cr = app.connections.valueAt(j);
3274            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3275                    && cr.binding.service.app != null
3276                    && cr.binding.service.app.lruSeq != mLruSeq
3277                    && !cr.binding.service.app.persistent) {
3278                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3279                        "service connection", cr, app);
3280            }
3281        }
3282        for (int j=app.conProviders.size()-1; j>=0; j--) {
3283            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3284            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3285                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3286                        "provider reference", cpr, app);
3287            }
3288        }
3289    }
3290
3291    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3292        if (uid == Process.SYSTEM_UID) {
3293            // The system gets to run in any process.  If there are multiple
3294            // processes with the same uid, just pick the first (this
3295            // should never happen).
3296            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3297            if (procs == null) return null;
3298            final int procCount = procs.size();
3299            for (int i = 0; i < procCount; i++) {
3300                final int procUid = procs.keyAt(i);
3301                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3302                    // Don't use an app process or different user process for system component.
3303                    continue;
3304                }
3305                return procs.valueAt(i);
3306            }
3307        }
3308        ProcessRecord proc = mProcessNames.get(processName, uid);
3309        if (false && proc != null && !keepIfLarge
3310                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3311                && proc.lastCachedPss >= 4000) {
3312            // Turn this condition on to cause killing to happen regularly, for testing.
3313            if (proc.baseProcessTracker != null) {
3314                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3315            }
3316            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3317        } else if (proc != null && !keepIfLarge
3318                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3319                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3320            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3321            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3322                if (proc.baseProcessTracker != null) {
3323                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3324                }
3325                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3326            }
3327        }
3328        return proc;
3329    }
3330
3331    void notifyPackageUse(String packageName) {
3332        IPackageManager pm = AppGlobals.getPackageManager();
3333        try {
3334            pm.notifyPackageUse(packageName);
3335        } catch (RemoteException e) {
3336        }
3337    }
3338
3339    boolean isNextTransitionForward() {
3340        int transit = mWindowManager.getPendingAppTransition();
3341        return transit == TRANSIT_ACTIVITY_OPEN
3342                || transit == TRANSIT_TASK_OPEN
3343                || transit == TRANSIT_TASK_TO_FRONT;
3344    }
3345
3346    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3347            String processName, String abiOverride, int uid, Runnable crashHandler) {
3348        synchronized(this) {
3349            ApplicationInfo info = new ApplicationInfo();
3350            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3351            // For isolated processes, the former contains the parent's uid and the latter the
3352            // actual uid of the isolated process.
3353            // In the special case introduced by this method (which is, starting an isolated
3354            // process directly from the SystemServer without an actual parent app process) the
3355            // closest thing to a parent's uid is SYSTEM_UID.
3356            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3357            // the |isolated| logic in the ProcessRecord constructor.
3358            info.uid = Process.SYSTEM_UID;
3359            info.processName = processName;
3360            info.className = entryPoint;
3361            info.packageName = "android";
3362            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3363                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3364                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3365                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3366                    crashHandler);
3367            return proc != null ? proc.pid : 0;
3368        }
3369    }
3370
3371    final ProcessRecord startProcessLocked(String processName,
3372            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3373            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3374            boolean isolated, boolean keepIfLarge) {
3375        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3376                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3377                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3378                null /* crashHandler */);
3379    }
3380
3381    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3382            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3383            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3384            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3385        long startTime = SystemClock.elapsedRealtime();
3386        ProcessRecord app;
3387        if (!isolated) {
3388            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3389            checkTime(startTime, "startProcess: after getProcessRecord");
3390
3391            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3392                // If we are in the background, then check to see if this process
3393                // is bad.  If so, we will just silently fail.
3394                if (mAppErrors.isBadProcessLocked(info)) {
3395                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3396                            + "/" + info.processName);
3397                    return null;
3398                }
3399            } else {
3400                // When the user is explicitly starting a process, then clear its
3401                // crash count so that we won't make it bad until they see at
3402                // least one crash dialog again, and make the process good again
3403                // if it had been bad.
3404                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3405                        + "/" + info.processName);
3406                mAppErrors.resetProcessCrashTimeLocked(info);
3407                if (mAppErrors.isBadProcessLocked(info)) {
3408                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3409                            UserHandle.getUserId(info.uid), info.uid,
3410                            info.processName);
3411                    mAppErrors.clearBadProcessLocked(info);
3412                    if (app != null) {
3413                        app.bad = false;
3414                    }
3415                }
3416            }
3417        } else {
3418            // If this is an isolated process, it can't re-use an existing process.
3419            app = null;
3420        }
3421
3422        // app launch boost for big.little configurations
3423        // use cpusets to migrate freshly launched tasks to big cores
3424        synchronized(ActivityManagerService.this) {
3425            nativeMigrateToBoost();
3426            mIsBoosted = true;
3427            mBoostStartTime = SystemClock.uptimeMillis();
3428            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3429            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3430        }
3431
3432        // We don't have to do anything more if:
3433        // (1) There is an existing application record; and
3434        // (2) The caller doesn't think it is dead, OR there is no thread
3435        //     object attached to it so we know it couldn't have crashed; and
3436        // (3) There is a pid assigned to it, so it is either starting or
3437        //     already running.
3438        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3439                + " app=" + app + " knownToBeDead=" + knownToBeDead
3440                + " thread=" + (app != null ? app.thread : null)
3441                + " pid=" + (app != null ? app.pid : -1));
3442        if (app != null && app.pid > 0) {
3443            if (!knownToBeDead || app.thread == null) {
3444                // We already have the app running, or are waiting for it to
3445                // come up (we have a pid but not yet its thread), so keep it.
3446                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3447                // If this is a new package in the process, add the package to the list
3448                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3449                checkTime(startTime, "startProcess: done, added package to proc");
3450                return app;
3451            }
3452
3453            // An application record is attached to a previous process,
3454            // clean it up now.
3455            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3456            checkTime(startTime, "startProcess: bad proc running, killing");
3457            killProcessGroup(app.uid, app.pid);
3458            handleAppDiedLocked(app, true, true);
3459            checkTime(startTime, "startProcess: done killing old proc");
3460        }
3461
3462        String hostingNameStr = hostingName != null
3463                ? hostingName.flattenToShortString() : null;
3464
3465        if (app == null) {
3466            checkTime(startTime, "startProcess: creating new process record");
3467            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3468            if (app == null) {
3469                Slog.w(TAG, "Failed making new process record for "
3470                        + processName + "/" + info.uid + " isolated=" + isolated);
3471                return null;
3472            }
3473            app.crashHandler = crashHandler;
3474            checkTime(startTime, "startProcess: done creating new process record");
3475        } else {
3476            // If this is a new package in the process, add the package to the list
3477            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3478            checkTime(startTime, "startProcess: added package to existing proc");
3479        }
3480
3481        // If the system is not ready yet, then hold off on starting this
3482        // process until it is.
3483        if (!mProcessesReady
3484                && !isAllowedWhileBooting(info)
3485                && !allowWhileBooting) {
3486            if (!mProcessesOnHold.contains(app)) {
3487                mProcessesOnHold.add(app);
3488            }
3489            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3490                    "System not ready, putting on hold: " + app);
3491            checkTime(startTime, "startProcess: returning with proc on hold");
3492            return app;
3493        }
3494
3495        checkTime(startTime, "startProcess: stepping in to startProcess");
3496        startProcessLocked(
3497                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3498        checkTime(startTime, "startProcess: done starting proc!");
3499        return (app.pid != 0) ? app : null;
3500    }
3501
3502    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3503        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3504    }
3505
3506    private final void startProcessLocked(ProcessRecord app,
3507            String hostingType, String hostingNameStr) {
3508        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3509                null /* entryPoint */, null /* entryPointArgs */);
3510    }
3511
3512    private final void startProcessLocked(ProcessRecord app, String hostingType,
3513            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3514        long startTime = SystemClock.elapsedRealtime();
3515        if (app.pid > 0 && app.pid != MY_PID) {
3516            checkTime(startTime, "startProcess: removing from pids map");
3517            synchronized (mPidsSelfLocked) {
3518                mPidsSelfLocked.remove(app.pid);
3519                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3520            }
3521            checkTime(startTime, "startProcess: done removing from pids map");
3522            app.setPid(0);
3523        }
3524
3525        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3526                "startProcessLocked removing on hold: " + app);
3527        mProcessesOnHold.remove(app);
3528
3529        checkTime(startTime, "startProcess: starting to update cpu stats");
3530        updateCpuStats();
3531        checkTime(startTime, "startProcess: done updating cpu stats");
3532
3533        try {
3534            try {
3535                final int userId = UserHandle.getUserId(app.uid);
3536                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3537            } catch (RemoteException e) {
3538                throw e.rethrowAsRuntimeException();
3539            }
3540
3541            int uid = app.uid;
3542            int[] gids = null;
3543            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3544            if (!app.isolated) {
3545                int[] permGids = null;
3546                try {
3547                    checkTime(startTime, "startProcess: getting gids from package manager");
3548                    final IPackageManager pm = AppGlobals.getPackageManager();
3549                    permGids = pm.getPackageGids(app.info.packageName,
3550                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3551                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3552                            MountServiceInternal.class);
3553                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3554                            app.info.packageName);
3555                } catch (RemoteException e) {
3556                    throw e.rethrowAsRuntimeException();
3557                }
3558
3559                /*
3560                 * Add shared application and profile GIDs so applications can share some
3561                 * resources like shared libraries and access user-wide resources
3562                 */
3563                if (ArrayUtils.isEmpty(permGids)) {
3564                    gids = new int[2];
3565                } else {
3566                    gids = new int[permGids.length + 2];
3567                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3568                }
3569                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3570                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3571            }
3572            checkTime(startTime, "startProcess: building args");
3573            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3574                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3575                        && mTopComponent != null
3576                        && app.processName.equals(mTopComponent.getPackageName())) {
3577                    uid = 0;
3578                }
3579                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3580                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3581                    uid = 0;
3582                }
3583            }
3584            int debugFlags = 0;
3585            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3586                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3587                // Also turn on CheckJNI for debuggable apps. It's quite
3588                // awkward to turn on otherwise.
3589                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3590            }
3591            // Run the app in safe mode if its manifest requests so or the
3592            // system is booted in safe mode.
3593            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3594                mSafeMode == true) {
3595                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3596            }
3597            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3598                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3599            }
3600            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3601            if ("true".equals(genDebugInfoProperty)) {
3602                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3603            }
3604            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3605                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3606            }
3607            if ("1".equals(SystemProperties.get("debug.assert"))) {
3608                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3609            }
3610            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3611                // Enable all debug flags required by the native debugger.
3612                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3613                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3614                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3615                mNativeDebuggingApp = null;
3616            }
3617
3618            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3619            if (requiredAbi == null) {
3620                requiredAbi = Build.SUPPORTED_ABIS[0];
3621            }
3622
3623            String instructionSet = null;
3624            if (app.info.primaryCpuAbi != null) {
3625                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3626            }
3627
3628            app.gids = gids;
3629            app.requiredAbi = requiredAbi;
3630            app.instructionSet = instructionSet;
3631
3632            // Start the process.  It will either succeed and return a result containing
3633            // the PID of the new process, or else throw a RuntimeException.
3634            boolean isActivityProcess = (entryPoint == null);
3635            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3636            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3637                    app.processName);
3638            checkTime(startTime, "startProcess: asking zygote to start proc");
3639            Process.ProcessStartResult startResult = Process.start(entryPoint,
3640                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3641                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3642                    app.info.dataDir, entryPointArgs);
3643            checkTime(startTime, "startProcess: returned from zygote!");
3644            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3645
3646            if (app.isolated) {
3647                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3648            }
3649            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3650            checkTime(startTime, "startProcess: done updating battery stats");
3651
3652            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3653                    UserHandle.getUserId(uid), startResult.pid, uid,
3654                    app.processName, hostingType,
3655                    hostingNameStr != null ? hostingNameStr : "");
3656
3657            try {
3658                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3659                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3660            } catch (RemoteException ex) {
3661                // Ignore
3662            }
3663
3664            if (app.persistent) {
3665                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3666            }
3667
3668            if (DEBUG_PROCESSES) {
3669                checkTime(startTime, "startProcess: building log message");
3670                StringBuilder buf = mStringBuilder;
3671                buf.setLength(0);
3672                buf.append("Start proc ");
3673                buf.append(startResult.pid);
3674                buf.append(':');
3675                buf.append(app.processName);
3676                buf.append('/');
3677                UserHandle.formatUid(buf, uid);
3678                if (!isActivityProcess) {
3679                    buf.append(" [");
3680                    buf.append(entryPoint);
3681                    buf.append("]");
3682                }
3683                buf.append(" for ");
3684                buf.append(hostingType);
3685                if (hostingNameStr != null) {
3686                    buf.append(" ");
3687                    buf.append(hostingNameStr);
3688                }
3689                Slog.i(TAG, buf.toString());
3690            }
3691            app.setPid(startResult.pid);
3692            app.usingWrapper = startResult.usingWrapper;
3693            app.removed = false;
3694            app.killed = false;
3695            app.killedByAm = false;
3696            checkTime(startTime, "startProcess: starting to update pids map");
3697            synchronized (mPidsSelfLocked) {
3698                this.mPidsSelfLocked.put(startResult.pid, app);
3699                if (isActivityProcess) {
3700                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3701                    msg.obj = app;
3702                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3703                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3704                }
3705            }
3706            checkTime(startTime, "startProcess: done updating pids map");
3707        } catch (RuntimeException e) {
3708            // XXX do better error recovery.
3709            app.setPid(0);
3710            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3711            if (app.isolated) {
3712                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3713            }
3714            Slog.e(TAG, "Failure starting process " + app.processName, e);
3715        }
3716    }
3717
3718    void updateUsageStats(ActivityRecord component, boolean resumed) {
3719        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3720                "updateUsageStats: comp=" + component + "res=" + resumed);
3721        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3722        if (resumed) {
3723            if (mUsageStatsService != null) {
3724                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3725                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3726            }
3727            synchronized (stats) {
3728                stats.noteActivityResumedLocked(component.app.uid);
3729            }
3730        } else {
3731            if (mUsageStatsService != null) {
3732                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3733                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3734            }
3735            synchronized (stats) {
3736                stats.noteActivityPausedLocked(component.app.uid);
3737            }
3738        }
3739    }
3740
3741    Intent getHomeIntent() {
3742        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3743        intent.setComponent(mTopComponent);
3744        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3745        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3746            intent.addCategory(Intent.CATEGORY_HOME);
3747        }
3748        return intent;
3749    }
3750
3751    boolean startHomeActivityLocked(int userId, String reason) {
3752        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3753                && mTopAction == null) {
3754            // We are running in factory test mode, but unable to find
3755            // the factory test app, so just sit around displaying the
3756            // error message and don't try to start anything.
3757            return false;
3758        }
3759        Intent intent = getHomeIntent();
3760        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3761        if (aInfo != null) {
3762            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3763            // Don't do this if the home app is currently being
3764            // instrumented.
3765            aInfo = new ActivityInfo(aInfo);
3766            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3767            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3768                    aInfo.applicationInfo.uid, true);
3769            if (app == null || app.instrumentationClass == null) {
3770                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3771                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3772            }
3773        }
3774
3775        return true;
3776    }
3777
3778    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3779        ActivityInfo ai = null;
3780        ComponentName comp = intent.getComponent();
3781        try {
3782            if (comp != null) {
3783                // Factory test.
3784                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3785            } else {
3786                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3787                        intent,
3788                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3789                        flags, userId);
3790
3791                if (info != null) {
3792                    ai = info.activityInfo;
3793                }
3794            }
3795        } catch (RemoteException e) {
3796            // ignore
3797        }
3798
3799        return ai;
3800    }
3801
3802    /**
3803     * Starts the "new version setup screen" if appropriate.
3804     */
3805    void startSetupActivityLocked() {
3806        // Only do this once per boot.
3807        if (mCheckedForSetup) {
3808            return;
3809        }
3810
3811        // We will show this screen if the current one is a different
3812        // version than the last one shown, and we are not running in
3813        // low-level factory test mode.
3814        final ContentResolver resolver = mContext.getContentResolver();
3815        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3816                Settings.Global.getInt(resolver,
3817                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3818            mCheckedForSetup = true;
3819
3820            // See if we should be showing the platform update setup UI.
3821            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3822            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3823                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3824            if (!ris.isEmpty()) {
3825                final ResolveInfo ri = ris.get(0);
3826                String vers = ri.activityInfo.metaData != null
3827                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3828                        : null;
3829                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3830                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3831                            Intent.METADATA_SETUP_VERSION);
3832                }
3833                String lastVers = Settings.Secure.getString(
3834                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3835                if (vers != null && !vers.equals(lastVers)) {
3836                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3837                    intent.setComponent(new ComponentName(
3838                            ri.activityInfo.packageName, ri.activityInfo.name));
3839                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3840                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3841                            null, 0, 0, 0, null, false, false, null, null, null);
3842                }
3843            }
3844        }
3845    }
3846
3847    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3848        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3849    }
3850
3851    void enforceNotIsolatedCaller(String caller) {
3852        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3853            throw new SecurityException("Isolated process not allowed to call " + caller);
3854        }
3855    }
3856
3857    void enforceShellRestriction(String restriction, int userHandle) {
3858        if (Binder.getCallingUid() == Process.SHELL_UID) {
3859            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3860                throw new SecurityException("Shell does not have permission to access user "
3861                        + userHandle);
3862            }
3863        }
3864    }
3865
3866    @Override
3867    public int getFrontActivityScreenCompatMode() {
3868        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3869        synchronized (this) {
3870            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3871        }
3872    }
3873
3874    @Override
3875    public void setFrontActivityScreenCompatMode(int mode) {
3876        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3877                "setFrontActivityScreenCompatMode");
3878        synchronized (this) {
3879            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3880        }
3881    }
3882
3883    @Override
3884    public int getPackageScreenCompatMode(String packageName) {
3885        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3886        synchronized (this) {
3887            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3888        }
3889    }
3890
3891    @Override
3892    public void setPackageScreenCompatMode(String packageName, int mode) {
3893        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3894                "setPackageScreenCompatMode");
3895        synchronized (this) {
3896            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3897        }
3898    }
3899
3900    @Override
3901    public boolean getPackageAskScreenCompat(String packageName) {
3902        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3903        synchronized (this) {
3904            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3905        }
3906    }
3907
3908    @Override
3909    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3910        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3911                "setPackageAskScreenCompat");
3912        synchronized (this) {
3913            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3914        }
3915    }
3916
3917    private boolean hasUsageStatsPermission(String callingPackage) {
3918        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3919                Binder.getCallingUid(), callingPackage);
3920        if (mode == AppOpsManager.MODE_DEFAULT) {
3921            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3922                    == PackageManager.PERMISSION_GRANTED;
3923        }
3924        return mode == AppOpsManager.MODE_ALLOWED;
3925    }
3926
3927    @Override
3928    public int getPackageProcessState(String packageName, String callingPackage) {
3929        if (!hasUsageStatsPermission(callingPackage)) {
3930            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3931                    "getPackageProcessState");
3932        }
3933
3934        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3935        synchronized (this) {
3936            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3937                final ProcessRecord proc = mLruProcesses.get(i);
3938                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3939                        || procState > proc.setProcState) {
3940                    boolean found = false;
3941                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3942                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3943                            procState = proc.setProcState;
3944                            found = true;
3945                        }
3946                    }
3947                    if (proc.pkgDeps != null && !found) {
3948                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3949                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3950                                procState = proc.setProcState;
3951                                break;
3952                            }
3953                        }
3954                    }
3955                }
3956            }
3957        }
3958        return procState;
3959    }
3960
3961    @Override
3962    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3963        synchronized (this) {
3964            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3965            if (app == null) {
3966                return false;
3967            }
3968            if (app.trimMemoryLevel < level && app.thread != null &&
3969                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3970                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3971                try {
3972                    app.thread.scheduleTrimMemory(level);
3973                    app.trimMemoryLevel = level;
3974                    return true;
3975                } catch (RemoteException e) {
3976                    // Fallthrough to failure case.
3977                }
3978            }
3979        }
3980        return false;
3981    }
3982
3983    private void dispatchProcessesChanged() {
3984        int N;
3985        synchronized (this) {
3986            N = mPendingProcessChanges.size();
3987            if (mActiveProcessChanges.length < N) {
3988                mActiveProcessChanges = new ProcessChangeItem[N];
3989            }
3990            mPendingProcessChanges.toArray(mActiveProcessChanges);
3991            mPendingProcessChanges.clear();
3992            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3993                    "*** Delivering " + N + " process changes");
3994        }
3995
3996        int i = mProcessObservers.beginBroadcast();
3997        while (i > 0) {
3998            i--;
3999            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4000            if (observer != null) {
4001                try {
4002                    for (int j=0; j<N; j++) {
4003                        ProcessChangeItem item = mActiveProcessChanges[j];
4004                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4005                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4006                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4007                                    + item.uid + ": " + item.foregroundActivities);
4008                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4009                                    item.foregroundActivities);
4010                        }
4011                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4012                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4013                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4014                                    + ": " + item.processState);
4015                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4016                        }
4017                    }
4018                } catch (RemoteException e) {
4019                }
4020            }
4021        }
4022        mProcessObservers.finishBroadcast();
4023
4024        synchronized (this) {
4025            for (int j=0; j<N; j++) {
4026                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4027            }
4028        }
4029    }
4030
4031    private void dispatchProcessDied(int pid, int uid) {
4032        int i = mProcessObservers.beginBroadcast();
4033        while (i > 0) {
4034            i--;
4035            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4036            if (observer != null) {
4037                try {
4038                    observer.onProcessDied(pid, uid);
4039                } catch (RemoteException e) {
4040                }
4041            }
4042        }
4043        mProcessObservers.finishBroadcast();
4044    }
4045
4046    private void dispatchUidsChanged() {
4047        int N;
4048        synchronized (this) {
4049            N = mPendingUidChanges.size();
4050            if (mActiveUidChanges.length < N) {
4051                mActiveUidChanges = new UidRecord.ChangeItem[N];
4052            }
4053            for (int i=0; i<N; i++) {
4054                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4055                mActiveUidChanges[i] = change;
4056                if (change.uidRecord != null) {
4057                    change.uidRecord.pendingChange = null;
4058                    change.uidRecord = null;
4059                }
4060            }
4061            mPendingUidChanges.clear();
4062            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4063                    "*** Delivering " + N + " uid changes");
4064        }
4065
4066        if (mLocalPowerManager != null) {
4067            for (int j=0; j<N; j++) {
4068                UidRecord.ChangeItem item = mActiveUidChanges[j];
4069                if (item.change == UidRecord.CHANGE_GONE
4070                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4071                    mLocalPowerManager.uidGone(item.uid);
4072                } else {
4073                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4074                }
4075            }
4076        }
4077
4078        int i = mUidObservers.beginBroadcast();
4079        while (i > 0) {
4080            i--;
4081            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4082            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4083            if (observer != null) {
4084                try {
4085                    for (int j=0; j<N; j++) {
4086                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4087                        final int change = item.change;
4088                        UidRecord validateUid = null;
4089                        if (VALIDATE_UID_STATES && i == 0) {
4090                            validateUid = mValidateUids.get(item.uid);
4091                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4092                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4093                                validateUid = new UidRecord(item.uid);
4094                                mValidateUids.put(item.uid, validateUid);
4095                            }
4096                        }
4097                        if (change == UidRecord.CHANGE_IDLE
4098                                || change == UidRecord.CHANGE_GONE_IDLE) {
4099                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4100                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4101                                        "UID idle uid=" + item.uid);
4102                                observer.onUidIdle(item.uid);
4103                            }
4104                            if (VALIDATE_UID_STATES && i == 0) {
4105                                if (validateUid != null) {
4106                                    validateUid.idle = true;
4107                                }
4108                            }
4109                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4110                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4111                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4112                                        "UID active uid=" + item.uid);
4113                                observer.onUidActive(item.uid);
4114                            }
4115                            if (VALIDATE_UID_STATES && i == 0) {
4116                                validateUid.idle = false;
4117                            }
4118                        }
4119                        if (change == UidRecord.CHANGE_GONE
4120                                || change == UidRecord.CHANGE_GONE_IDLE) {
4121                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4122                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4123                                        "UID gone uid=" + item.uid);
4124                                observer.onUidGone(item.uid);
4125                            }
4126                            if (VALIDATE_UID_STATES && i == 0) {
4127                                if (validateUid != null) {
4128                                    mValidateUids.remove(item.uid);
4129                                }
4130                            }
4131                        } else {
4132                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4133                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4134                                        "UID CHANGED uid=" + item.uid
4135                                                + ": " + item.processState);
4136                                observer.onUidStateChanged(item.uid, item.processState);
4137                            }
4138                            if (VALIDATE_UID_STATES && i == 0) {
4139                                validateUid.curProcState = validateUid.setProcState
4140                                        = item.processState;
4141                            }
4142                        }
4143                    }
4144                } catch (RemoteException e) {
4145                }
4146            }
4147        }
4148        mUidObservers.finishBroadcast();
4149
4150        synchronized (this) {
4151            for (int j=0; j<N; j++) {
4152                mAvailUidChanges.add(mActiveUidChanges[j]);
4153            }
4154        }
4155    }
4156
4157    @Override
4158    public final int startActivity(IApplicationThread caller, String callingPackage,
4159            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4160            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4161        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4162                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4163                UserHandle.getCallingUserId());
4164    }
4165
4166    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4167        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4168        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4169                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4170                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4171
4172        // TODO: Switch to user app stacks here.
4173        String mimeType = intent.getType();
4174        final Uri data = intent.getData();
4175        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4176            mimeType = getProviderMimeType(data, userId);
4177        }
4178        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4179
4180        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4181        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4182                null, 0, 0, null, null, null, null, false, userId, container, null);
4183    }
4184
4185    @Override
4186    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4187            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4188            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4189        enforceNotIsolatedCaller("startActivity");
4190        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4191                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4192        // TODO: Switch to user app stacks here.
4193        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4194                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4195                profilerInfo, null, null, bOptions, false, userId, null, null);
4196    }
4197
4198    @Override
4199    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4200            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4201            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4202            int userId) {
4203
4204        // This is very dangerous -- it allows you to perform a start activity (including
4205        // permission grants) as any app that may launch one of your own activities.  So
4206        // we will only allow this to be done from activities that are part of the core framework,
4207        // and then only when they are running as the system.
4208        final ActivityRecord sourceRecord;
4209        final int targetUid;
4210        final String targetPackage;
4211        synchronized (this) {
4212            if (resultTo == null) {
4213                throw new SecurityException("Must be called from an activity");
4214            }
4215            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4216            if (sourceRecord == null) {
4217                throw new SecurityException("Called with bad activity token: " + resultTo);
4218            }
4219            if (!sourceRecord.info.packageName.equals("android")) {
4220                throw new SecurityException(
4221                        "Must be called from an activity that is declared in the android package");
4222            }
4223            if (sourceRecord.app == null) {
4224                throw new SecurityException("Called without a process attached to activity");
4225            }
4226            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4227                // This is still okay, as long as this activity is running under the
4228                // uid of the original calling activity.
4229                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4230                    throw new SecurityException(
4231                            "Calling activity in uid " + sourceRecord.app.uid
4232                                    + " must be system uid or original calling uid "
4233                                    + sourceRecord.launchedFromUid);
4234                }
4235            }
4236            if (ignoreTargetSecurity) {
4237                if (intent.getComponent() == null) {
4238                    throw new SecurityException(
4239                            "Component must be specified with ignoreTargetSecurity");
4240                }
4241                if (intent.getSelector() != null) {
4242                    throw new SecurityException(
4243                            "Selector not allowed with ignoreTargetSecurity");
4244                }
4245            }
4246            targetUid = sourceRecord.launchedFromUid;
4247            targetPackage = sourceRecord.launchedFromPackage;
4248        }
4249
4250        if (userId == UserHandle.USER_NULL) {
4251            userId = UserHandle.getUserId(sourceRecord.app.uid);
4252        }
4253
4254        // TODO: Switch to user app stacks here.
4255        try {
4256            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4257                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4258                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4259            return ret;
4260        } catch (SecurityException e) {
4261            // XXX need to figure out how to propagate to original app.
4262            // A SecurityException here is generally actually a fault of the original
4263            // calling activity (such as a fairly granting permissions), so propagate it
4264            // back to them.
4265            /*
4266            StringBuilder msg = new StringBuilder();
4267            msg.append("While launching");
4268            msg.append(intent.toString());
4269            msg.append(": ");
4270            msg.append(e.getMessage());
4271            */
4272            throw e;
4273        }
4274    }
4275
4276    @Override
4277    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4278            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4279            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4280        enforceNotIsolatedCaller("startActivityAndWait");
4281        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4282                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4283        WaitResult res = new WaitResult();
4284        // TODO: Switch to user app stacks here.
4285        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4286                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4287                bOptions, false, userId, null, null);
4288        return res;
4289    }
4290
4291    @Override
4292    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4293            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4294            int startFlags, Configuration config, Bundle bOptions, int userId) {
4295        enforceNotIsolatedCaller("startActivityWithConfig");
4296        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4297                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4298        // TODO: Switch to user app stacks here.
4299        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4300                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4301                null, null, config, bOptions, false, userId, null, null);
4302        return ret;
4303    }
4304
4305    @Override
4306    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4307            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4308            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4309            throws TransactionTooLargeException {
4310        enforceNotIsolatedCaller("startActivityIntentSender");
4311        // Refuse possible leaked file descriptors
4312        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4313            throw new IllegalArgumentException("File descriptors passed in Intent");
4314        }
4315
4316        IIntentSender sender = intent.getTarget();
4317        if (!(sender instanceof PendingIntentRecord)) {
4318            throw new IllegalArgumentException("Bad PendingIntent object");
4319        }
4320
4321        PendingIntentRecord pir = (PendingIntentRecord)sender;
4322
4323        synchronized (this) {
4324            // If this is coming from the currently resumed activity, it is
4325            // effectively saying that app switches are allowed at this point.
4326            final ActivityStack stack = getFocusedStack();
4327            if (stack.mResumedActivity != null &&
4328                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4329                mAppSwitchesAllowedTime = 0;
4330            }
4331        }
4332        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4333                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4334        return ret;
4335    }
4336
4337    @Override
4338    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4339            Intent intent, String resolvedType, IVoiceInteractionSession session,
4340            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4341            Bundle bOptions, int userId) {
4342        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4343                != PackageManager.PERMISSION_GRANTED) {
4344            String msg = "Permission Denial: startVoiceActivity() from pid="
4345                    + Binder.getCallingPid()
4346                    + ", uid=" + Binder.getCallingUid()
4347                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4348            Slog.w(TAG, msg);
4349            throw new SecurityException(msg);
4350        }
4351        if (session == null || interactor == null) {
4352            throw new NullPointerException("null session or interactor");
4353        }
4354        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4355                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4356        // TODO: Switch to user app stacks here.
4357        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4358                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4359                null, bOptions, false, userId, null, null);
4360    }
4361
4362    @Override
4363    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4364            throws RemoteException {
4365        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4366        synchronized (this) {
4367            ActivityRecord activity = getFocusedStack().topActivity();
4368            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4369                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4370            }
4371            if (mRunningVoice != null || activity.task.voiceSession != null
4372                    || activity.voiceSession != null) {
4373                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4374                return;
4375            }
4376            if (activity.pendingVoiceInteractionStart) {
4377                Slog.w(TAG, "Pending start of voice interaction already.");
4378                return;
4379            }
4380            activity.pendingVoiceInteractionStart = true;
4381        }
4382        LocalServices.getService(VoiceInteractionManagerInternal.class)
4383                .startLocalVoiceInteraction(callingActivity, options);
4384    }
4385
4386    @Override
4387    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4388        LocalServices.getService(VoiceInteractionManagerInternal.class)
4389                .stopLocalVoiceInteraction(callingActivity);
4390    }
4391
4392    @Override
4393    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4394        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4395                .supportsLocalVoiceInteraction();
4396    }
4397
4398    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4399            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4400        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4401        if (activityToCallback == null) return;
4402        activityToCallback.setVoiceSessionLocked(voiceSession);
4403
4404        // Inform the activity
4405        try {
4406            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4407                    voiceInteractor);
4408            long token = Binder.clearCallingIdentity();
4409            try {
4410                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4411            } finally {
4412                Binder.restoreCallingIdentity(token);
4413            }
4414            // TODO: VI Should we cache the activity so that it's easier to find later
4415            // rather than scan through all the stacks and activities?
4416        } catch (RemoteException re) {
4417            activityToCallback.clearVoiceSessionLocked();
4418            // TODO: VI Should this terminate the voice session?
4419        }
4420    }
4421
4422    @Override
4423    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4424        synchronized (this) {
4425            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4426                if (keepAwake) {
4427                    mVoiceWakeLock.acquire();
4428                } else {
4429                    mVoiceWakeLock.release();
4430                }
4431            }
4432        }
4433    }
4434
4435    @Override
4436    public boolean startNextMatchingActivity(IBinder callingActivity,
4437            Intent intent, Bundle bOptions) {
4438        // Refuse possible leaked file descriptors
4439        if (intent != null && intent.hasFileDescriptors() == true) {
4440            throw new IllegalArgumentException("File descriptors passed in Intent");
4441        }
4442        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4443
4444        synchronized (this) {
4445            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4446            if (r == null) {
4447                ActivityOptions.abort(options);
4448                return false;
4449            }
4450            if (r.app == null || r.app.thread == null) {
4451                // The caller is not running...  d'oh!
4452                ActivityOptions.abort(options);
4453                return false;
4454            }
4455            intent = new Intent(intent);
4456            // The caller is not allowed to change the data.
4457            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4458            // And we are resetting to find the next component...
4459            intent.setComponent(null);
4460
4461            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4462
4463            ActivityInfo aInfo = null;
4464            try {
4465                List<ResolveInfo> resolves =
4466                    AppGlobals.getPackageManager().queryIntentActivities(
4467                            intent, r.resolvedType,
4468                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4469                            UserHandle.getCallingUserId()).getList();
4470
4471                // Look for the original activity in the list...
4472                final int N = resolves != null ? resolves.size() : 0;
4473                for (int i=0; i<N; i++) {
4474                    ResolveInfo rInfo = resolves.get(i);
4475                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4476                            && rInfo.activityInfo.name.equals(r.info.name)) {
4477                        // We found the current one...  the next matching is
4478                        // after it.
4479                        i++;
4480                        if (i<N) {
4481                            aInfo = resolves.get(i).activityInfo;
4482                        }
4483                        if (debug) {
4484                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4485                                    + "/" + r.info.name);
4486                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4487                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4488                        }
4489                        break;
4490                    }
4491                }
4492            } catch (RemoteException e) {
4493            }
4494
4495            if (aInfo == null) {
4496                // Nobody who is next!
4497                ActivityOptions.abort(options);
4498                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4499                return false;
4500            }
4501
4502            intent.setComponent(new ComponentName(
4503                    aInfo.applicationInfo.packageName, aInfo.name));
4504            intent.setFlags(intent.getFlags()&~(
4505                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4506                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4507                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4508                    Intent.FLAG_ACTIVITY_NEW_TASK));
4509
4510            // Okay now we need to start the new activity, replacing the
4511            // currently running activity.  This is a little tricky because
4512            // we want to start the new one as if the current one is finished,
4513            // but not finish the current one first so that there is no flicker.
4514            // And thus...
4515            final boolean wasFinishing = r.finishing;
4516            r.finishing = true;
4517
4518            // Propagate reply information over to the new activity.
4519            final ActivityRecord resultTo = r.resultTo;
4520            final String resultWho = r.resultWho;
4521            final int requestCode = r.requestCode;
4522            r.resultTo = null;
4523            if (resultTo != null) {
4524                resultTo.removeResultsLocked(r, resultWho, requestCode);
4525            }
4526
4527            final long origId = Binder.clearCallingIdentity();
4528            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4529                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4530                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4531                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4532                    false, false, null, null, null);
4533            Binder.restoreCallingIdentity(origId);
4534
4535            r.finishing = wasFinishing;
4536            if (res != ActivityManager.START_SUCCESS) {
4537                return false;
4538            }
4539            return true;
4540        }
4541    }
4542
4543    @Override
4544    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4545        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4546            String msg = "Permission Denial: startActivityFromRecents called without " +
4547                    START_TASKS_FROM_RECENTS;
4548            Slog.w(TAG, msg);
4549            throw new SecurityException(msg);
4550        }
4551        final long origId = Binder.clearCallingIdentity();
4552        try {
4553            synchronized (this) {
4554                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4555            }
4556        } finally {
4557            Binder.restoreCallingIdentity(origId);
4558        }
4559    }
4560
4561    final int startActivityInPackage(int uid, String callingPackage,
4562            Intent intent, String resolvedType, IBinder resultTo,
4563            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4564            IActivityContainer container, TaskRecord inTask) {
4565
4566        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4567                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4568
4569        // TODO: Switch to user app stacks here.
4570        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4571                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4572                null, null, null, bOptions, false, userId, container, inTask);
4573        return ret;
4574    }
4575
4576    @Override
4577    public final int startActivities(IApplicationThread caller, String callingPackage,
4578            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4579            int userId) {
4580        enforceNotIsolatedCaller("startActivities");
4581        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4582                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4583        // TODO: Switch to user app stacks here.
4584        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4585                resolvedTypes, resultTo, bOptions, userId);
4586        return ret;
4587    }
4588
4589    final int startActivitiesInPackage(int uid, String callingPackage,
4590            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4591            Bundle bOptions, int userId) {
4592
4593        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4594                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4595        // TODO: Switch to user app stacks here.
4596        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4597                resultTo, bOptions, userId);
4598        return ret;
4599    }
4600
4601    @Override
4602    public void reportActivityFullyDrawn(IBinder token) {
4603        synchronized (this) {
4604            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4605            if (r == null) {
4606                return;
4607            }
4608            r.reportFullyDrawnLocked();
4609        }
4610    }
4611
4612    @Override
4613    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4614        synchronized (this) {
4615            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4616            if (r == null) {
4617                return;
4618            }
4619            TaskRecord task = r.task;
4620            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4621                // Fixed screen orientation isn't supported when activities aren't in full screen
4622                // mode.
4623                return;
4624            }
4625            final long origId = Binder.clearCallingIdentity();
4626            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4627            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4628                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4629            if (config != null) {
4630                r.frozenBeforeDestroy = true;
4631                if (!updateConfigurationLocked(config, r, false)) {
4632                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4633                }
4634            }
4635            Binder.restoreCallingIdentity(origId);
4636        }
4637    }
4638
4639    @Override
4640    public int getRequestedOrientation(IBinder token) {
4641        synchronized (this) {
4642            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4643            if (r == null) {
4644                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4645            }
4646            return mWindowManager.getAppOrientation(r.appToken);
4647        }
4648    }
4649
4650    /**
4651     * This is the internal entry point for handling Activity.finish().
4652     *
4653     * @param token The Binder token referencing the Activity we want to finish.
4654     * @param resultCode Result code, if any, from this Activity.
4655     * @param resultData Result data (Intent), if any, from this Activity.
4656     * @param finishTask Whether to finish the task associated with this Activity.
4657     *
4658     * @return Returns true if the activity successfully finished, or false if it is still running.
4659     */
4660    @Override
4661    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4662            int finishTask) {
4663        // Refuse possible leaked file descriptors
4664        if (resultData != null && resultData.hasFileDescriptors() == true) {
4665            throw new IllegalArgumentException("File descriptors passed in Intent");
4666        }
4667
4668        synchronized(this) {
4669            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4670            if (r == null) {
4671                return true;
4672            }
4673            // Keep track of the root activity of the task before we finish it
4674            TaskRecord tr = r.task;
4675            ActivityRecord rootR = tr.getRootActivity();
4676            if (rootR == null) {
4677                Slog.w(TAG, "Finishing task with all activities already finished");
4678            }
4679            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4680            // finish.
4681            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4682                    mStackSupervisor.isLastLockedTask(tr)) {
4683                Slog.i(TAG, "Not finishing task in lock task mode");
4684                mStackSupervisor.showLockTaskToast();
4685                return false;
4686            }
4687            if (mController != null) {
4688                // Find the first activity that is not finishing.
4689                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4690                if (next != null) {
4691                    // ask watcher if this is allowed
4692                    boolean resumeOK = true;
4693                    try {
4694                        resumeOK = mController.activityResuming(next.packageName);
4695                    } catch (RemoteException e) {
4696                        mController = null;
4697                        Watchdog.getInstance().setActivityController(null);
4698                    }
4699
4700                    if (!resumeOK) {
4701                        Slog.i(TAG, "Not finishing activity because controller resumed");
4702                        return false;
4703                    }
4704                }
4705            }
4706            final long origId = Binder.clearCallingIdentity();
4707            try {
4708                boolean res;
4709                final boolean finishWithRootActivity =
4710                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4711                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4712                        || (finishWithRootActivity && r == rootR)) {
4713                    // If requested, remove the task that is associated to this activity only if it
4714                    // was the root activity in the task. The result code and data is ignored
4715                    // because we don't support returning them across task boundaries. Also, to
4716                    // keep backwards compatibility we remove the task from recents when finishing
4717                    // task with root activity.
4718                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4719                    if (!res) {
4720                        Slog.i(TAG, "Removing task failed to finish activity");
4721                    }
4722                } else {
4723                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4724                            resultData, "app-request", true);
4725                    if (!res) {
4726                        Slog.i(TAG, "Failed to finish by app-request");
4727                    }
4728                }
4729                return res;
4730            } finally {
4731                Binder.restoreCallingIdentity(origId);
4732            }
4733        }
4734    }
4735
4736    @Override
4737    public final void finishHeavyWeightApp() {
4738        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4739                != PackageManager.PERMISSION_GRANTED) {
4740            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4741                    + Binder.getCallingPid()
4742                    + ", uid=" + Binder.getCallingUid()
4743                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4744            Slog.w(TAG, msg);
4745            throw new SecurityException(msg);
4746        }
4747
4748        synchronized(this) {
4749            if (mHeavyWeightProcess == null) {
4750                return;
4751            }
4752
4753            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4754            for (int i = 0; i < activities.size(); i++) {
4755                ActivityRecord r = activities.get(i);
4756                if (!r.finishing && r.isInStackLocked()) {
4757                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4758                            null, "finish-heavy", true);
4759                }
4760            }
4761
4762            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4763                    mHeavyWeightProcess.userId, 0));
4764            mHeavyWeightProcess = null;
4765        }
4766    }
4767
4768    @Override
4769    public void crashApplication(int uid, int initialPid, String packageName,
4770            String message) {
4771        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4772                != PackageManager.PERMISSION_GRANTED) {
4773            String msg = "Permission Denial: crashApplication() from pid="
4774                    + Binder.getCallingPid()
4775                    + ", uid=" + Binder.getCallingUid()
4776                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4777            Slog.w(TAG, msg);
4778            throw new SecurityException(msg);
4779        }
4780
4781        synchronized(this) {
4782            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4783        }
4784    }
4785
4786    @Override
4787    public final void finishSubActivity(IBinder token, String resultWho,
4788            int requestCode) {
4789        synchronized(this) {
4790            final long origId = Binder.clearCallingIdentity();
4791            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4792            if (r != null) {
4793                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4794            }
4795            Binder.restoreCallingIdentity(origId);
4796        }
4797    }
4798
4799    @Override
4800    public boolean finishActivityAffinity(IBinder token) {
4801        synchronized(this) {
4802            final long origId = Binder.clearCallingIdentity();
4803            try {
4804                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4805                if (r == null) {
4806                    return false;
4807                }
4808
4809                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4810                // can finish.
4811                final TaskRecord task = r.task;
4812                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4813                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4814                    mStackSupervisor.showLockTaskToast();
4815                    return false;
4816                }
4817                return task.stack.finishActivityAffinityLocked(r);
4818            } finally {
4819                Binder.restoreCallingIdentity(origId);
4820            }
4821        }
4822    }
4823
4824    @Override
4825    public void finishVoiceTask(IVoiceInteractionSession session) {
4826        synchronized (this) {
4827            final long origId = Binder.clearCallingIdentity();
4828            try {
4829                // TODO: VI Consider treating local voice interactions and voice tasks
4830                // differently here
4831                mStackSupervisor.finishVoiceTask(session);
4832            } finally {
4833                Binder.restoreCallingIdentity(origId);
4834            }
4835        }
4836
4837    }
4838
4839    @Override
4840    public boolean releaseActivityInstance(IBinder token) {
4841        synchronized(this) {
4842            final long origId = Binder.clearCallingIdentity();
4843            try {
4844                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4845                if (r == null) {
4846                    return false;
4847                }
4848                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4849            } finally {
4850                Binder.restoreCallingIdentity(origId);
4851            }
4852        }
4853    }
4854
4855    @Override
4856    public void releaseSomeActivities(IApplicationThread appInt) {
4857        synchronized(this) {
4858            final long origId = Binder.clearCallingIdentity();
4859            try {
4860                ProcessRecord app = getRecordForAppLocked(appInt);
4861                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4862            } finally {
4863                Binder.restoreCallingIdentity(origId);
4864            }
4865        }
4866    }
4867
4868    @Override
4869    public boolean willActivityBeVisible(IBinder token) {
4870        synchronized(this) {
4871            ActivityStack stack = ActivityRecord.getStackLocked(token);
4872            if (stack != null) {
4873                return stack.willActivityBeVisibleLocked(token);
4874            }
4875            return false;
4876        }
4877    }
4878
4879    @Override
4880    public void overridePendingTransition(IBinder token, String packageName,
4881            int enterAnim, int exitAnim) {
4882        synchronized(this) {
4883            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4884            if (self == null) {
4885                return;
4886            }
4887
4888            final long origId = Binder.clearCallingIdentity();
4889
4890            if (self.state == ActivityState.RESUMED
4891                    || self.state == ActivityState.PAUSING) {
4892                mWindowManager.overridePendingAppTransition(packageName,
4893                        enterAnim, exitAnim, null);
4894            }
4895
4896            Binder.restoreCallingIdentity(origId);
4897        }
4898    }
4899
4900    /**
4901     * Main function for removing an existing process from the activity manager
4902     * as a result of that process going away.  Clears out all connections
4903     * to the process.
4904     */
4905    private final void handleAppDiedLocked(ProcessRecord app,
4906            boolean restarting, boolean allowRestart) {
4907        int pid = app.pid;
4908        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4909        if (!kept && !restarting) {
4910            removeLruProcessLocked(app);
4911            if (pid > 0) {
4912                ProcessList.remove(pid);
4913            }
4914        }
4915
4916        if (mProfileProc == app) {
4917            clearProfilerLocked();
4918        }
4919
4920        // Remove this application's activities from active lists.
4921        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4922
4923        app.activities.clear();
4924
4925        if (app.instrumentationClass != null) {
4926            Slog.w(TAG, "Crash of app " + app.processName
4927                  + " running instrumentation " + app.instrumentationClass);
4928            Bundle info = new Bundle();
4929            info.putString("shortMsg", "Process crashed.");
4930            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4931        }
4932
4933        if (!restarting && hasVisibleActivities
4934                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4935            // If there was nothing to resume, and we are not already restarting this process, but
4936            // there is a visible activity that is hosted by the process...  then make sure all
4937            // visible activities are running, taking care of restarting this process.
4938            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4939        }
4940    }
4941
4942    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4943        IBinder threadBinder = thread.asBinder();
4944        // Find the application record.
4945        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4946            ProcessRecord rec = mLruProcesses.get(i);
4947            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4948                return i;
4949            }
4950        }
4951        return -1;
4952    }
4953
4954    final ProcessRecord getRecordForAppLocked(
4955            IApplicationThread thread) {
4956        if (thread == null) {
4957            return null;
4958        }
4959
4960        int appIndex = getLRURecordIndexForAppLocked(thread);
4961        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4962    }
4963
4964    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4965        // If there are no longer any background processes running,
4966        // and the app that died was not running instrumentation,
4967        // then tell everyone we are now low on memory.
4968        boolean haveBg = false;
4969        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4970            ProcessRecord rec = mLruProcesses.get(i);
4971            if (rec.thread != null
4972                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4973                haveBg = true;
4974                break;
4975            }
4976        }
4977
4978        if (!haveBg) {
4979            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4980            if (doReport) {
4981                long now = SystemClock.uptimeMillis();
4982                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4983                    doReport = false;
4984                } else {
4985                    mLastMemUsageReportTime = now;
4986                }
4987            }
4988            final ArrayList<ProcessMemInfo> memInfos
4989                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4990            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4991            long now = SystemClock.uptimeMillis();
4992            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4993                ProcessRecord rec = mLruProcesses.get(i);
4994                if (rec == dyingProc || rec.thread == null) {
4995                    continue;
4996                }
4997                if (doReport) {
4998                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4999                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5000                }
5001                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5002                    // The low memory report is overriding any current
5003                    // state for a GC request.  Make sure to do
5004                    // heavy/important/visible/foreground processes first.
5005                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5006                        rec.lastRequestedGc = 0;
5007                    } else {
5008                        rec.lastRequestedGc = rec.lastLowMemory;
5009                    }
5010                    rec.reportLowMemory = true;
5011                    rec.lastLowMemory = now;
5012                    mProcessesToGc.remove(rec);
5013                    addProcessToGcListLocked(rec);
5014                }
5015            }
5016            if (doReport) {
5017                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5018                mHandler.sendMessage(msg);
5019            }
5020            scheduleAppGcsLocked();
5021        }
5022    }
5023
5024    final void appDiedLocked(ProcessRecord app) {
5025       appDiedLocked(app, app.pid, app.thread, false);
5026    }
5027
5028    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5029            boolean fromBinderDied) {
5030        // First check if this ProcessRecord is actually active for the pid.
5031        synchronized (mPidsSelfLocked) {
5032            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5033            if (curProc != app) {
5034                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5035                return;
5036            }
5037        }
5038
5039        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5040        synchronized (stats) {
5041            stats.noteProcessDiedLocked(app.info.uid, pid);
5042        }
5043
5044        if (!app.killed) {
5045            if (!fromBinderDied) {
5046                Process.killProcessQuiet(pid);
5047            }
5048            killProcessGroup(app.uid, pid);
5049            app.killed = true;
5050        }
5051
5052        // Clean up already done if the process has been re-started.
5053        if (app.pid == pid && app.thread != null &&
5054                app.thread.asBinder() == thread.asBinder()) {
5055            boolean doLowMem = app.instrumentationClass == null;
5056            boolean doOomAdj = doLowMem;
5057            if (!app.killedByAm) {
5058                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5059                        + ") has died");
5060                mAllowLowerMemLevel = true;
5061            } else {
5062                // Note that we always want to do oom adj to update our state with the
5063                // new number of procs.
5064                mAllowLowerMemLevel = false;
5065                doLowMem = false;
5066            }
5067            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5068            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5069                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5070            handleAppDiedLocked(app, false, true);
5071
5072            if (doOomAdj) {
5073                updateOomAdjLocked();
5074            }
5075            if (doLowMem) {
5076                doLowMemReportIfNeededLocked(app);
5077            }
5078        } else if (app.pid != pid) {
5079            // A new process has already been started.
5080            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5081                    + ") has died and restarted (pid " + app.pid + ").");
5082            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5083        } else if (DEBUG_PROCESSES) {
5084            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5085                    + thread.asBinder());
5086        }
5087    }
5088
5089    /**
5090     * If a stack trace dump file is configured, dump process stack traces.
5091     * @param clearTraces causes the dump file to be erased prior to the new
5092     *    traces being written, if true; when false, the new traces will be
5093     *    appended to any existing file content.
5094     * @param firstPids of dalvik VM processes to dump stack traces for first
5095     * @param lastPids of dalvik VM processes to dump stack traces for last
5096     * @param nativeProcs optional list of native process names to dump stack crawls
5097     * @return file containing stack traces, or null if no dump file is configured
5098     */
5099    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5100            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5101        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5102        if (tracesPath == null || tracesPath.length() == 0) {
5103            return null;
5104        }
5105
5106        File tracesFile = new File(tracesPath);
5107        try {
5108            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5109            tracesFile.createNewFile();
5110            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5111        } catch (IOException e) {
5112            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5113            return null;
5114        }
5115
5116        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5117        return tracesFile;
5118    }
5119
5120    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5121            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5122        // Use a FileObserver to detect when traces finish writing.
5123        // The order of traces is considered important to maintain for legibility.
5124        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5125            @Override
5126            public synchronized void onEvent(int event, String path) { notify(); }
5127        };
5128
5129        try {
5130            observer.startWatching();
5131
5132            // First collect all of the stacks of the most important pids.
5133            if (firstPids != null) {
5134                try {
5135                    int num = firstPids.size();
5136                    for (int i = 0; i < num; i++) {
5137                        synchronized (observer) {
5138                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5139                                    + firstPids.get(i));
5140                            final long sime = SystemClock.elapsedRealtime();
5141                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5142                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5143                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5144                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5145                        }
5146                    }
5147                } catch (InterruptedException e) {
5148                    Slog.wtf(TAG, e);
5149                }
5150            }
5151
5152            // Next collect the stacks of the native pids
5153            if (nativeProcs != null) {
5154                int[] pids = Process.getPidsForCommands(nativeProcs);
5155                if (pids != null) {
5156                    for (int pid : pids) {
5157                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5158                        final long sime = SystemClock.elapsedRealtime();
5159                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5160                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5161                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5162                    }
5163                }
5164            }
5165
5166            // Lastly, measure CPU usage.
5167            if (processCpuTracker != null) {
5168                processCpuTracker.init();
5169                System.gc();
5170                processCpuTracker.update();
5171                try {
5172                    synchronized (processCpuTracker) {
5173                        processCpuTracker.wait(500); // measure over 1/2 second.
5174                    }
5175                } catch (InterruptedException e) {
5176                }
5177                processCpuTracker.update();
5178
5179                // We'll take the stack crawls of just the top apps using CPU.
5180                final int N = processCpuTracker.countWorkingStats();
5181                int numProcs = 0;
5182                for (int i=0; i<N && numProcs<5; i++) {
5183                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5184                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5185                        numProcs++;
5186                        try {
5187                            synchronized (observer) {
5188                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5189                                        + stats.pid);
5190                                final long stime = SystemClock.elapsedRealtime();
5191                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5192                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5193                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5194                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5195                            }
5196                        } catch (InterruptedException e) {
5197                            Slog.wtf(TAG, e);
5198                        }
5199                    } else if (DEBUG_ANR) {
5200                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5201                                + stats.pid);
5202                    }
5203                }
5204            }
5205        } finally {
5206            observer.stopWatching();
5207        }
5208    }
5209
5210    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5211        if (true || IS_USER_BUILD) {
5212            return;
5213        }
5214        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5215        if (tracesPath == null || tracesPath.length() == 0) {
5216            return;
5217        }
5218
5219        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5220        StrictMode.allowThreadDiskWrites();
5221        try {
5222            final File tracesFile = new File(tracesPath);
5223            final File tracesDir = tracesFile.getParentFile();
5224            final File tracesTmp = new File(tracesDir, "__tmp__");
5225            try {
5226                if (tracesFile.exists()) {
5227                    tracesTmp.delete();
5228                    tracesFile.renameTo(tracesTmp);
5229                }
5230                StringBuilder sb = new StringBuilder();
5231                Time tobj = new Time();
5232                tobj.set(System.currentTimeMillis());
5233                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5234                sb.append(": ");
5235                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5236                sb.append(" since ");
5237                sb.append(msg);
5238                FileOutputStream fos = new FileOutputStream(tracesFile);
5239                fos.write(sb.toString().getBytes());
5240                if (app == null) {
5241                    fos.write("\n*** No application process!".getBytes());
5242                }
5243                fos.close();
5244                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5245            } catch (IOException e) {
5246                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5247                return;
5248            }
5249
5250            if (app != null) {
5251                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5252                firstPids.add(app.pid);
5253                dumpStackTraces(tracesPath, firstPids, null, null, null);
5254            }
5255
5256            File lastTracesFile = null;
5257            File curTracesFile = null;
5258            for (int i=9; i>=0; i--) {
5259                String name = String.format(Locale.US, "slow%02d.txt", i);
5260                curTracesFile = new File(tracesDir, name);
5261                if (curTracesFile.exists()) {
5262                    if (lastTracesFile != null) {
5263                        curTracesFile.renameTo(lastTracesFile);
5264                    } else {
5265                        curTracesFile.delete();
5266                    }
5267                }
5268                lastTracesFile = curTracesFile;
5269            }
5270            tracesFile.renameTo(curTracesFile);
5271            if (tracesTmp.exists()) {
5272                tracesTmp.renameTo(tracesFile);
5273            }
5274        } finally {
5275            StrictMode.setThreadPolicy(oldPolicy);
5276        }
5277    }
5278
5279    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5280        if (!mLaunchWarningShown) {
5281            mLaunchWarningShown = true;
5282            mUiHandler.post(new Runnable() {
5283                @Override
5284                public void run() {
5285                    synchronized (ActivityManagerService.this) {
5286                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5287                        d.show();
5288                        mUiHandler.postDelayed(new Runnable() {
5289                            @Override
5290                            public void run() {
5291                                synchronized (ActivityManagerService.this) {
5292                                    d.dismiss();
5293                                    mLaunchWarningShown = false;
5294                                }
5295                            }
5296                        }, 4000);
5297                    }
5298                }
5299            });
5300        }
5301    }
5302
5303    @Override
5304    public boolean clearApplicationUserData(final String packageName,
5305            final IPackageDataObserver observer, int userId) {
5306        enforceNotIsolatedCaller("clearApplicationUserData");
5307        int uid = Binder.getCallingUid();
5308        int pid = Binder.getCallingPid();
5309        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5310                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5311
5312        final DevicePolicyManagerInternal dpmi = LocalServices
5313                .getService(DevicePolicyManagerInternal.class);
5314        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5315            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5316        }
5317
5318        long callingId = Binder.clearCallingIdentity();
5319        try {
5320            IPackageManager pm = AppGlobals.getPackageManager();
5321            int pkgUid = -1;
5322            synchronized(this) {
5323                try {
5324                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5325                } catch (RemoteException e) {
5326                }
5327                if (pkgUid == -1) {
5328                    Slog.w(TAG, "Invalid packageName: " + packageName);
5329                    if (observer != null) {
5330                        try {
5331                            observer.onRemoveCompleted(packageName, false);
5332                        } catch (RemoteException e) {
5333                            Slog.i(TAG, "Observer no longer exists.");
5334                        }
5335                    }
5336                    return false;
5337                }
5338                if (uid == pkgUid || checkComponentPermission(
5339                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5340                        pid, uid, -1, true)
5341                        == PackageManager.PERMISSION_GRANTED) {
5342                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5343                } else {
5344                    throw new SecurityException("PID " + pid + " does not have permission "
5345                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5346                                    + " of package " + packageName);
5347                }
5348
5349                // Remove all tasks match the cleared application package and user
5350                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5351                    final TaskRecord tr = mRecentTasks.get(i);
5352                    final String taskPackageName =
5353                            tr.getBaseIntent().getComponent().getPackageName();
5354                    if (tr.userId != userId) continue;
5355                    if (!taskPackageName.equals(packageName)) continue;
5356                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5357                }
5358            }
5359
5360            try {
5361                // Clear application user data
5362                pm.clearApplicationUserData(packageName, observer, userId);
5363
5364                synchronized(this) {
5365                    // Remove all permissions granted from/to this package
5366                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5367                }
5368
5369                // Remove all zen rules created by this package; revoke it's zen access.
5370                INotificationManager inm = NotificationManager.getService();
5371                inm.removeAutomaticZenRules(packageName);
5372                inm.setNotificationPolicyAccessGranted(packageName, false);
5373
5374                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5375                        Uri.fromParts("package", packageName, null));
5376                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5377                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5378                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5379                        null, null, 0, null, null, null, null, false, false, userId);
5380            } catch (RemoteException e) {
5381            }
5382        } finally {
5383            Binder.restoreCallingIdentity(callingId);
5384        }
5385        return true;
5386    }
5387
5388    @Override
5389    public void killBackgroundProcesses(final String packageName, int userId) {
5390        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5391                != PackageManager.PERMISSION_GRANTED &&
5392                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5393                        != PackageManager.PERMISSION_GRANTED) {
5394            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5395                    + Binder.getCallingPid()
5396                    + ", uid=" + Binder.getCallingUid()
5397                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5398            Slog.w(TAG, msg);
5399            throw new SecurityException(msg);
5400        }
5401
5402        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5403                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5404        long callingId = Binder.clearCallingIdentity();
5405        try {
5406            IPackageManager pm = AppGlobals.getPackageManager();
5407            synchronized(this) {
5408                int appId = -1;
5409                try {
5410                    appId = UserHandle.getAppId(
5411                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5412                } catch (RemoteException e) {
5413                }
5414                if (appId == -1) {
5415                    Slog.w(TAG, "Invalid packageName: " + packageName);
5416                    return;
5417                }
5418                killPackageProcessesLocked(packageName, appId, userId,
5419                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5420            }
5421        } finally {
5422            Binder.restoreCallingIdentity(callingId);
5423        }
5424    }
5425
5426    @Override
5427    public void killAllBackgroundProcesses() {
5428        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5429                != PackageManager.PERMISSION_GRANTED) {
5430            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5431                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5432                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5433            Slog.w(TAG, msg);
5434            throw new SecurityException(msg);
5435        }
5436
5437        final long callingId = Binder.clearCallingIdentity();
5438        try {
5439            synchronized (this) {
5440                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5441                final int NP = mProcessNames.getMap().size();
5442                for (int ip = 0; ip < NP; ip++) {
5443                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5444                    final int NA = apps.size();
5445                    for (int ia = 0; ia < NA; ia++) {
5446                        final ProcessRecord app = apps.valueAt(ia);
5447                        if (app.persistent) {
5448                            // We don't kill persistent processes.
5449                            continue;
5450                        }
5451                        if (app.removed) {
5452                            procs.add(app);
5453                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5454                            app.removed = true;
5455                            procs.add(app);
5456                        }
5457                    }
5458                }
5459
5460                final int N = procs.size();
5461                for (int i = 0; i < N; i++) {
5462                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5463                }
5464
5465                mAllowLowerMemLevel = true;
5466
5467                updateOomAdjLocked();
5468                doLowMemReportIfNeededLocked(null);
5469            }
5470        } finally {
5471            Binder.restoreCallingIdentity(callingId);
5472        }
5473    }
5474
5475    /**
5476     * Kills all background processes, except those matching any of the
5477     * specified properties.
5478     *
5479     * @param minTargetSdk the target SDK version at or above which to preserve
5480     *                     processes, or {@code -1} to ignore the target SDK
5481     * @param maxProcState the process state at or below which to preserve
5482     *                     processes, or {@code -1} to ignore the process state
5483     */
5484    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5485        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5486                != PackageManager.PERMISSION_GRANTED) {
5487            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5488                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5489                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5490            Slog.w(TAG, msg);
5491            throw new SecurityException(msg);
5492        }
5493
5494        final long callingId = Binder.clearCallingIdentity();
5495        try {
5496            synchronized (this) {
5497                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5498                final int NP = mProcessNames.getMap().size();
5499                for (int ip = 0; ip < NP; ip++) {
5500                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5501                    final int NA = apps.size();
5502                    for (int ia = 0; ia < NA; ia++) {
5503                        final ProcessRecord app = apps.valueAt(ia);
5504                        if (app.removed) {
5505                            procs.add(app);
5506                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5507                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5508                            app.removed = true;
5509                            procs.add(app);
5510                        }
5511                    }
5512                }
5513
5514                final int N = procs.size();
5515                for (int i = 0; i < N; i++) {
5516                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5517                }
5518            }
5519        } finally {
5520            Binder.restoreCallingIdentity(callingId);
5521        }
5522    }
5523
5524    @Override
5525    public void forceStopPackage(final String packageName, int userId) {
5526        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5527                != PackageManager.PERMISSION_GRANTED) {
5528            String msg = "Permission Denial: forceStopPackage() from pid="
5529                    + Binder.getCallingPid()
5530                    + ", uid=" + Binder.getCallingUid()
5531                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5532            Slog.w(TAG, msg);
5533            throw new SecurityException(msg);
5534        }
5535        final int callingPid = Binder.getCallingPid();
5536        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5537                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5538        long callingId = Binder.clearCallingIdentity();
5539        try {
5540            IPackageManager pm = AppGlobals.getPackageManager();
5541            synchronized(this) {
5542                int[] users = userId == UserHandle.USER_ALL
5543                        ? mUserController.getUsers() : new int[] { userId };
5544                for (int user : users) {
5545                    int pkgUid = -1;
5546                    try {
5547                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5548                                user);
5549                    } catch (RemoteException e) {
5550                    }
5551                    if (pkgUid == -1) {
5552                        Slog.w(TAG, "Invalid packageName: " + packageName);
5553                        continue;
5554                    }
5555                    try {
5556                        pm.setPackageStoppedState(packageName, true, user);
5557                    } catch (RemoteException e) {
5558                    } catch (IllegalArgumentException e) {
5559                        Slog.w(TAG, "Failed trying to unstop package "
5560                                + packageName + ": " + e);
5561                    }
5562                    if (mUserController.isUserRunningLocked(user, 0)) {
5563                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5564                    }
5565                }
5566            }
5567        } finally {
5568            Binder.restoreCallingIdentity(callingId);
5569        }
5570    }
5571
5572    @Override
5573    public void addPackageDependency(String packageName) {
5574        synchronized (this) {
5575            int callingPid = Binder.getCallingPid();
5576            if (callingPid == Process.myPid()) {
5577                //  Yeah, um, no.
5578                return;
5579            }
5580            ProcessRecord proc;
5581            synchronized (mPidsSelfLocked) {
5582                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5583            }
5584            if (proc != null) {
5585                if (proc.pkgDeps == null) {
5586                    proc.pkgDeps = new ArraySet<String>(1);
5587                }
5588                proc.pkgDeps.add(packageName);
5589            }
5590        }
5591    }
5592
5593    /*
5594     * The pkg name and app id have to be specified.
5595     */
5596    @Override
5597    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5598        if (pkg == null) {
5599            return;
5600        }
5601        // Make sure the uid is valid.
5602        if (appid < 0) {
5603            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5604            return;
5605        }
5606        int callerUid = Binder.getCallingUid();
5607        // Only the system server can kill an application
5608        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5609            // Post an aysnc message to kill the application
5610            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5611            msg.arg1 = appid;
5612            msg.arg2 = 0;
5613            Bundle bundle = new Bundle();
5614            bundle.putString("pkg", pkg);
5615            bundle.putString("reason", reason);
5616            msg.obj = bundle;
5617            mHandler.sendMessage(msg);
5618        } else {
5619            throw new SecurityException(callerUid + " cannot kill pkg: " +
5620                    pkg);
5621        }
5622    }
5623
5624    @Override
5625    public void closeSystemDialogs(String reason) {
5626        enforceNotIsolatedCaller("closeSystemDialogs");
5627
5628        final int pid = Binder.getCallingPid();
5629        final int uid = Binder.getCallingUid();
5630        final long origId = Binder.clearCallingIdentity();
5631        try {
5632            synchronized (this) {
5633                // Only allow this from foreground processes, so that background
5634                // applications can't abuse it to prevent system UI from being shown.
5635                if (uid >= Process.FIRST_APPLICATION_UID) {
5636                    ProcessRecord proc;
5637                    synchronized (mPidsSelfLocked) {
5638                        proc = mPidsSelfLocked.get(pid);
5639                    }
5640                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5641                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5642                                + " from background process " + proc);
5643                        return;
5644                    }
5645                }
5646                closeSystemDialogsLocked(reason);
5647            }
5648        } finally {
5649            Binder.restoreCallingIdentity(origId);
5650        }
5651    }
5652
5653    void closeSystemDialogsLocked(String reason) {
5654        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5655        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5656                | Intent.FLAG_RECEIVER_FOREGROUND);
5657        if (reason != null) {
5658            intent.putExtra("reason", reason);
5659        }
5660        mWindowManager.closeSystemDialogs(reason);
5661
5662        mStackSupervisor.closeSystemDialogsLocked();
5663
5664        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5665                AppOpsManager.OP_NONE, null, false, false,
5666                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5667    }
5668
5669    @Override
5670    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5671        enforceNotIsolatedCaller("getProcessMemoryInfo");
5672        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5673        for (int i=pids.length-1; i>=0; i--) {
5674            ProcessRecord proc;
5675            int oomAdj;
5676            synchronized (this) {
5677                synchronized (mPidsSelfLocked) {
5678                    proc = mPidsSelfLocked.get(pids[i]);
5679                    oomAdj = proc != null ? proc.setAdj : 0;
5680                }
5681            }
5682            infos[i] = new Debug.MemoryInfo();
5683            Debug.getMemoryInfo(pids[i], infos[i]);
5684            if (proc != null) {
5685                synchronized (this) {
5686                    if (proc.thread != null && proc.setAdj == oomAdj) {
5687                        // Record this for posterity if the process has been stable.
5688                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5689                                infos[i].getTotalUss(), false, proc.pkgList);
5690                    }
5691                }
5692            }
5693        }
5694        return infos;
5695    }
5696
5697    @Override
5698    public long[] getProcessPss(int[] pids) {
5699        enforceNotIsolatedCaller("getProcessPss");
5700        long[] pss = new long[pids.length];
5701        for (int i=pids.length-1; i>=0; i--) {
5702            ProcessRecord proc;
5703            int oomAdj;
5704            synchronized (this) {
5705                synchronized (mPidsSelfLocked) {
5706                    proc = mPidsSelfLocked.get(pids[i]);
5707                    oomAdj = proc != null ? proc.setAdj : 0;
5708                }
5709            }
5710            long[] tmpUss = new long[1];
5711            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5712            if (proc != null) {
5713                synchronized (this) {
5714                    if (proc.thread != null && proc.setAdj == oomAdj) {
5715                        // Record this for posterity if the process has been stable.
5716                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5717                    }
5718                }
5719            }
5720        }
5721        return pss;
5722    }
5723
5724    @Override
5725    public void killApplicationProcess(String processName, int uid) {
5726        if (processName == null) {
5727            return;
5728        }
5729
5730        int callerUid = Binder.getCallingUid();
5731        // Only the system server can kill an application
5732        if (callerUid == Process.SYSTEM_UID) {
5733            synchronized (this) {
5734                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5735                if (app != null && app.thread != null) {
5736                    try {
5737                        app.thread.scheduleSuicide();
5738                    } catch (RemoteException e) {
5739                        // If the other end already died, then our work here is done.
5740                    }
5741                } else {
5742                    Slog.w(TAG, "Process/uid not found attempting kill of "
5743                            + processName + " / " + uid);
5744                }
5745            }
5746        } else {
5747            throw new SecurityException(callerUid + " cannot kill app process: " +
5748                    processName);
5749        }
5750    }
5751
5752    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5753        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5754                false, true, false, false, UserHandle.getUserId(uid), reason);
5755        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5756                Uri.fromParts("package", packageName, null));
5757        if (!mProcessesReady) {
5758            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5759                    | Intent.FLAG_RECEIVER_FOREGROUND);
5760        }
5761        intent.putExtra(Intent.EXTRA_UID, uid);
5762        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5763        broadcastIntentLocked(null, null, intent,
5764                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5765                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5766    }
5767
5768
5769    private final boolean killPackageProcessesLocked(String packageName, int appId,
5770            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5771            boolean doit, boolean evenPersistent, String reason) {
5772        ArrayList<ProcessRecord> procs = new ArrayList<>();
5773
5774        // Remove all processes this package may have touched: all with the
5775        // same UID (except for the system or root user), and all whose name
5776        // matches the package name.
5777        final int NP = mProcessNames.getMap().size();
5778        for (int ip=0; ip<NP; ip++) {
5779            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5780            final int NA = apps.size();
5781            for (int ia=0; ia<NA; ia++) {
5782                ProcessRecord app = apps.valueAt(ia);
5783                if (app.persistent && !evenPersistent) {
5784                    // we don't kill persistent processes
5785                    continue;
5786                }
5787                if (app.removed) {
5788                    if (doit) {
5789                        procs.add(app);
5790                    }
5791                    continue;
5792                }
5793
5794                // Skip process if it doesn't meet our oom adj requirement.
5795                if (app.setAdj < minOomAdj) {
5796                    continue;
5797                }
5798
5799                // If no package is specified, we call all processes under the
5800                // give user id.
5801                if (packageName == null) {
5802                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5803                        continue;
5804                    }
5805                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5806                        continue;
5807                    }
5808                // Package has been specified, we want to hit all processes
5809                // that match it.  We need to qualify this by the processes
5810                // that are running under the specified app and user ID.
5811                } else {
5812                    final boolean isDep = app.pkgDeps != null
5813                            && app.pkgDeps.contains(packageName);
5814                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5815                        continue;
5816                    }
5817                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5818                        continue;
5819                    }
5820                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5821                        continue;
5822                    }
5823                }
5824
5825                // Process has passed all conditions, kill it!
5826                if (!doit) {
5827                    return true;
5828                }
5829                app.removed = true;
5830                procs.add(app);
5831            }
5832        }
5833
5834        int N = procs.size();
5835        for (int i=0; i<N; i++) {
5836            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5837        }
5838        updateOomAdjLocked();
5839        return N > 0;
5840    }
5841
5842    private void cleanupDisabledPackageComponentsLocked(
5843            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5844
5845        Set<String> disabledClasses = null;
5846        boolean packageDisabled = false;
5847        IPackageManager pm = AppGlobals.getPackageManager();
5848
5849        if (changedClasses == null) {
5850            // Nothing changed...
5851            return;
5852        }
5853
5854        // Determine enable/disable state of the package and its components.
5855        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5856        for (int i = changedClasses.length - 1; i >= 0; i--) {
5857            final String changedClass = changedClasses[i];
5858
5859            if (changedClass.equals(packageName)) {
5860                try {
5861                    // Entire package setting changed
5862                    enabled = pm.getApplicationEnabledSetting(packageName,
5863                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5864                } catch (Exception e) {
5865                    // No such package/component; probably racing with uninstall.  In any
5866                    // event it means we have nothing further to do here.
5867                    return;
5868                }
5869                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5870                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5871                if (packageDisabled) {
5872                    // Entire package is disabled.
5873                    // No need to continue to check component states.
5874                    disabledClasses = null;
5875                    break;
5876                }
5877            } else {
5878                try {
5879                    enabled = pm.getComponentEnabledSetting(
5880                            new ComponentName(packageName, changedClass),
5881                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5882                } catch (Exception e) {
5883                    // As above, probably racing with uninstall.
5884                    return;
5885                }
5886                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5887                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5888                    if (disabledClasses == null) {
5889                        disabledClasses = new ArraySet<>(changedClasses.length);
5890                    }
5891                    disabledClasses.add(changedClass);
5892                }
5893            }
5894        }
5895
5896        if (!packageDisabled && disabledClasses == null) {
5897            // Nothing to do here...
5898            return;
5899        }
5900
5901        // Clean-up disabled activities.
5902        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5903                packageName, disabledClasses, true, false, userId) && mBooted) {
5904            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5905            mStackSupervisor.scheduleIdleLocked();
5906        }
5907
5908        // Clean-up disabled tasks
5909        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5910
5911        // Clean-up disabled services.
5912        mServices.bringDownDisabledPackageServicesLocked(
5913                packageName, disabledClasses, userId, false, killProcess, true);
5914
5915        // Clean-up disabled providers.
5916        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5917        mProviderMap.collectPackageProvidersLocked(
5918                packageName, disabledClasses, true, false, userId, providers);
5919        for (int i = providers.size() - 1; i >= 0; i--) {
5920            removeDyingProviderLocked(null, providers.get(i), true);
5921        }
5922
5923        // Clean-up disabled broadcast receivers.
5924        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5925            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5926                    packageName, disabledClasses, userId, true);
5927        }
5928
5929    }
5930
5931    final boolean forceStopPackageLocked(String packageName, int appId,
5932            boolean callerWillRestart, boolean purgeCache, boolean doit,
5933            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5934        int i;
5935
5936        if (userId == UserHandle.USER_ALL && packageName == null) {
5937            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5938        }
5939
5940        if (appId < 0 && packageName != null) {
5941            try {
5942                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5943                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5944            } catch (RemoteException e) {
5945            }
5946        }
5947
5948        if (doit) {
5949            if (packageName != null) {
5950                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5951                        + " user=" + userId + ": " + reason);
5952            } else {
5953                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5954            }
5955
5956            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5957        }
5958
5959        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5960                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5961                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5962
5963        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5964                packageName, null, doit, evenPersistent, userId)) {
5965            if (!doit) {
5966                return true;
5967            }
5968            didSomething = true;
5969        }
5970
5971        if (mServices.bringDownDisabledPackageServicesLocked(
5972                packageName, null, userId, evenPersistent, true, doit)) {
5973            if (!doit) {
5974                return true;
5975            }
5976            didSomething = true;
5977        }
5978
5979        if (packageName == null) {
5980            // Remove all sticky broadcasts from this user.
5981            mStickyBroadcasts.remove(userId);
5982        }
5983
5984        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5985        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5986                userId, providers)) {
5987            if (!doit) {
5988                return true;
5989            }
5990            didSomething = true;
5991        }
5992        for (i = providers.size() - 1; i >= 0; i--) {
5993            removeDyingProviderLocked(null, providers.get(i), true);
5994        }
5995
5996        // Remove transient permissions granted from/to this package/user
5997        removeUriPermissionsForPackageLocked(packageName, userId, false);
5998
5999        if (doit) {
6000            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6001                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6002                        packageName, null, userId, doit);
6003            }
6004        }
6005
6006        if (packageName == null || uninstalling) {
6007            // Remove pending intents.  For now we only do this when force
6008            // stopping users, because we have some problems when doing this
6009            // for packages -- app widgets are not currently cleaned up for
6010            // such packages, so they can be left with bad pending intents.
6011            if (mIntentSenderRecords.size() > 0) {
6012                Iterator<WeakReference<PendingIntentRecord>> it
6013                        = mIntentSenderRecords.values().iterator();
6014                while (it.hasNext()) {
6015                    WeakReference<PendingIntentRecord> wpir = it.next();
6016                    if (wpir == null) {
6017                        it.remove();
6018                        continue;
6019                    }
6020                    PendingIntentRecord pir = wpir.get();
6021                    if (pir == null) {
6022                        it.remove();
6023                        continue;
6024                    }
6025                    if (packageName == null) {
6026                        // Stopping user, remove all objects for the user.
6027                        if (pir.key.userId != userId) {
6028                            // Not the same user, skip it.
6029                            continue;
6030                        }
6031                    } else {
6032                        if (UserHandle.getAppId(pir.uid) != appId) {
6033                            // Different app id, skip it.
6034                            continue;
6035                        }
6036                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6037                            // Different user, skip it.
6038                            continue;
6039                        }
6040                        if (!pir.key.packageName.equals(packageName)) {
6041                            // Different package, skip it.
6042                            continue;
6043                        }
6044                    }
6045                    if (!doit) {
6046                        return true;
6047                    }
6048                    didSomething = true;
6049                    it.remove();
6050                    pir.canceled = true;
6051                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6052                        pir.key.activity.pendingResults.remove(pir.ref);
6053                    }
6054                }
6055            }
6056        }
6057
6058        if (doit) {
6059            if (purgeCache && packageName != null) {
6060                AttributeCache ac = AttributeCache.instance();
6061                if (ac != null) {
6062                    ac.removePackage(packageName);
6063                }
6064            }
6065            if (mBooted) {
6066                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6067                mStackSupervisor.scheduleIdleLocked();
6068            }
6069        }
6070
6071        return didSomething;
6072    }
6073
6074    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6075        ProcessRecord old = mProcessNames.remove(name, uid);
6076        if (old != null) {
6077            old.uidRecord.numProcs--;
6078            if (old.uidRecord.numProcs == 0) {
6079                // No more processes using this uid, tell clients it is gone.
6080                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6081                        "No more processes in " + old.uidRecord);
6082                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6083                mActiveUids.remove(uid);
6084                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6085            }
6086            old.uidRecord = null;
6087        }
6088        mIsolatedProcesses.remove(uid);
6089        return old;
6090    }
6091
6092    private final void addProcessNameLocked(ProcessRecord proc) {
6093        // We shouldn't already have a process under this name, but just in case we
6094        // need to clean up whatever may be there now.
6095        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6096        if (old == proc && proc.persistent) {
6097            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6098            Slog.w(TAG, "Re-adding persistent process " + proc);
6099        } else if (old != null) {
6100            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6101        }
6102        UidRecord uidRec = mActiveUids.get(proc.uid);
6103        if (uidRec == null) {
6104            uidRec = new UidRecord(proc.uid);
6105            // This is the first appearance of the uid, report it now!
6106            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6107                    "Creating new process uid: " + uidRec);
6108            mActiveUids.put(proc.uid, uidRec);
6109            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6110            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6111        }
6112        proc.uidRecord = uidRec;
6113        uidRec.numProcs++;
6114        mProcessNames.put(proc.processName, proc.uid, proc);
6115        if (proc.isolated) {
6116            mIsolatedProcesses.put(proc.uid, proc);
6117        }
6118    }
6119
6120    boolean removeProcessLocked(ProcessRecord app,
6121            boolean callerWillRestart, boolean allowRestart, String reason) {
6122        final String name = app.processName;
6123        final int uid = app.uid;
6124        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6125            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6126
6127        removeProcessNameLocked(name, uid);
6128        if (mHeavyWeightProcess == app) {
6129            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6130                    mHeavyWeightProcess.userId, 0));
6131            mHeavyWeightProcess = null;
6132        }
6133        boolean needRestart = false;
6134        if (app.pid > 0 && app.pid != MY_PID) {
6135            int pid = app.pid;
6136            synchronized (mPidsSelfLocked) {
6137                mPidsSelfLocked.remove(pid);
6138                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6139            }
6140            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6141            if (app.isolated) {
6142                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6143            }
6144            boolean willRestart = false;
6145            if (app.persistent && !app.isolated) {
6146                if (!callerWillRestart) {
6147                    willRestart = true;
6148                } else {
6149                    needRestart = true;
6150                }
6151            }
6152            app.kill(reason, true);
6153            handleAppDiedLocked(app, willRestart, allowRestart);
6154            if (willRestart) {
6155                removeLruProcessLocked(app);
6156                addAppLocked(app.info, false, null /* ABI override */);
6157            }
6158        } else {
6159            mRemovedProcesses.add(app);
6160        }
6161
6162        return needRestart;
6163    }
6164
6165    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6166        cleanupAppInLaunchingProvidersLocked(app, true);
6167        removeProcessLocked(app, false, true, "timeout publishing content providers");
6168    }
6169
6170    private final void processStartTimedOutLocked(ProcessRecord app) {
6171        final int pid = app.pid;
6172        boolean gone = false;
6173        synchronized (mPidsSelfLocked) {
6174            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6175            if (knownApp != null && knownApp.thread == null) {
6176                mPidsSelfLocked.remove(pid);
6177                gone = true;
6178            }
6179        }
6180
6181        if (gone) {
6182            Slog.w(TAG, "Process " + app + " failed to attach");
6183            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6184                    pid, app.uid, app.processName);
6185            removeProcessNameLocked(app.processName, app.uid);
6186            if (mHeavyWeightProcess == app) {
6187                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6188                        mHeavyWeightProcess.userId, 0));
6189                mHeavyWeightProcess = null;
6190            }
6191            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6192            if (app.isolated) {
6193                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6194            }
6195            // Take care of any launching providers waiting for this process.
6196            cleanupAppInLaunchingProvidersLocked(app, true);
6197            // Take care of any services that are waiting for the process.
6198            mServices.processStartTimedOutLocked(app);
6199            app.kill("start timeout", true);
6200            removeLruProcessLocked(app);
6201            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6202                Slog.w(TAG, "Unattached app died before backup, skipping");
6203                try {
6204                    IBackupManager bm = IBackupManager.Stub.asInterface(
6205                            ServiceManager.getService(Context.BACKUP_SERVICE));
6206                    bm.agentDisconnected(app.info.packageName);
6207                } catch (RemoteException e) {
6208                    // Can't happen; the backup manager is local
6209                }
6210            }
6211            if (isPendingBroadcastProcessLocked(pid)) {
6212                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6213                skipPendingBroadcastLocked(pid);
6214            }
6215        } else {
6216            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6217        }
6218    }
6219
6220    private final boolean attachApplicationLocked(IApplicationThread thread,
6221            int pid) {
6222
6223        // Find the application record that is being attached...  either via
6224        // the pid if we are running in multiple processes, or just pull the
6225        // next app record if we are emulating process with anonymous threads.
6226        ProcessRecord app;
6227        if (pid != MY_PID && pid >= 0) {
6228            synchronized (mPidsSelfLocked) {
6229                app = mPidsSelfLocked.get(pid);
6230            }
6231        } else {
6232            app = null;
6233        }
6234
6235        if (app == null) {
6236            Slog.w(TAG, "No pending application record for pid " + pid
6237                    + " (IApplicationThread " + thread + "); dropping process");
6238            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6239            if (pid > 0 && pid != MY_PID) {
6240                Process.killProcessQuiet(pid);
6241                //TODO: killProcessGroup(app.info.uid, pid);
6242            } else {
6243                try {
6244                    thread.scheduleExit();
6245                } catch (Exception e) {
6246                    // Ignore exceptions.
6247                }
6248            }
6249            return false;
6250        }
6251
6252        // If this application record is still attached to a previous
6253        // process, clean it up now.
6254        if (app.thread != null) {
6255            handleAppDiedLocked(app, true, true);
6256        }
6257
6258        // Tell the process all about itself.
6259
6260        if (DEBUG_ALL) Slog.v(
6261                TAG, "Binding process pid " + pid + " to record " + app);
6262
6263        final String processName = app.processName;
6264        try {
6265            AppDeathRecipient adr = new AppDeathRecipient(
6266                    app, pid, thread);
6267            thread.asBinder().linkToDeath(adr, 0);
6268            app.deathRecipient = adr;
6269        } catch (RemoteException e) {
6270            app.resetPackageList(mProcessStats);
6271            startProcessLocked(app, "link fail", processName);
6272            return false;
6273        }
6274
6275        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6276
6277        app.makeActive(thread, mProcessStats);
6278        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6279        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6280        app.forcingToForeground = null;
6281        updateProcessForegroundLocked(app, false, false);
6282        app.hasShownUi = false;
6283        app.debugging = false;
6284        app.cached = false;
6285        app.killedByAm = false;
6286        app.unlocked = mContext.getSystemService(UserManager.class).isUserUnlocked(app.userId);
6287
6288        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6289
6290        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6291        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6292
6293        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6294            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6295            msg.obj = app;
6296            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6297        }
6298
6299        if (!normalMode) {
6300            Slog.i(TAG, "Launching preboot mode app: " + app);
6301        }
6302
6303        if (DEBUG_ALL) Slog.v(
6304            TAG, "New app record " + app
6305            + " thread=" + thread.asBinder() + " pid=" + pid);
6306        try {
6307            int testMode = IApplicationThread.DEBUG_OFF;
6308            if (mDebugApp != null && mDebugApp.equals(processName)) {
6309                testMode = mWaitForDebugger
6310                    ? IApplicationThread.DEBUG_WAIT
6311                    : IApplicationThread.DEBUG_ON;
6312                app.debugging = true;
6313                if (mDebugTransient) {
6314                    mDebugApp = mOrigDebugApp;
6315                    mWaitForDebugger = mOrigWaitForDebugger;
6316                }
6317            }
6318            String profileFile = app.instrumentationProfileFile;
6319            ParcelFileDescriptor profileFd = null;
6320            int samplingInterval = 0;
6321            boolean profileAutoStop = false;
6322            if (mProfileApp != null && mProfileApp.equals(processName)) {
6323                mProfileProc = app;
6324                profileFile = mProfileFile;
6325                profileFd = mProfileFd;
6326                samplingInterval = mSamplingInterval;
6327                profileAutoStop = mAutoStopProfiler;
6328            }
6329            boolean enableTrackAllocation = false;
6330            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6331                enableTrackAllocation = true;
6332                mTrackAllocationApp = null;
6333            }
6334
6335            // If the app is being launched for restore or full backup, set it up specially
6336            boolean isRestrictedBackupMode = false;
6337            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6338                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6339                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6340                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6341                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6342            }
6343
6344            notifyPackageUse(app.instrumentationInfo != null
6345                    ? app.instrumentationInfo.packageName
6346                    : app.info.packageName);
6347            if (app.instrumentationClass != null) {
6348                notifyPackageUse(app.instrumentationClass.getPackageName());
6349            }
6350            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6351                    + processName + " with config " + mConfiguration);
6352            ApplicationInfo appInfo = app.instrumentationInfo != null
6353                    ? app.instrumentationInfo : app.info;
6354            app.compat = compatibilityInfoForPackageLocked(appInfo);
6355            if (profileFd != null) {
6356                profileFd = profileFd.dup();
6357            }
6358            ProfilerInfo profilerInfo = profileFile == null ? null
6359                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6360            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6361                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6362                    app.instrumentationUiAutomationConnection, testMode,
6363                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6364                    isRestrictedBackupMode || !normalMode, app.persistent,
6365                    new Configuration(mConfiguration), app.compat,
6366                    getCommonServicesLocked(app.isolated),
6367                    mCoreSettingsObserver.getCoreSettingsLocked());
6368            updateLruProcessLocked(app, false, null);
6369            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6370        } catch (Exception e) {
6371            // todo: Yikes!  What should we do?  For now we will try to
6372            // start another process, but that could easily get us in
6373            // an infinite loop of restarting processes...
6374            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6375
6376            app.resetPackageList(mProcessStats);
6377            app.unlinkDeathRecipient();
6378            startProcessLocked(app, "bind fail", processName);
6379            return false;
6380        }
6381
6382        // Remove this record from the list of starting applications.
6383        mPersistentStartingProcesses.remove(app);
6384        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6385                "Attach application locked removing on hold: " + app);
6386        mProcessesOnHold.remove(app);
6387
6388        boolean badApp = false;
6389        boolean didSomething = false;
6390
6391        // See if the top visible activity is waiting to run in this process...
6392        if (normalMode) {
6393            try {
6394                if (mStackSupervisor.attachApplicationLocked(app)) {
6395                    didSomething = true;
6396                }
6397            } catch (Exception e) {
6398                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6399                badApp = true;
6400            }
6401        }
6402
6403        // Find any services that should be running in this process...
6404        if (!badApp) {
6405            try {
6406                didSomething |= mServices.attachApplicationLocked(app, processName);
6407            } catch (Exception e) {
6408                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6409                badApp = true;
6410            }
6411        }
6412
6413        // Check if a next-broadcast receiver is in this process...
6414        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6415            try {
6416                didSomething |= sendPendingBroadcastsLocked(app);
6417            } catch (Exception e) {
6418                // If the app died trying to launch the receiver we declare it 'bad'
6419                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6420                badApp = true;
6421            }
6422        }
6423
6424        // Check whether the next backup agent is in this process...
6425        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6426            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6427                    "New app is backup target, launching agent for " + app);
6428            notifyPackageUse(mBackupTarget.appInfo.packageName);
6429            try {
6430                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6431                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6432                        mBackupTarget.backupMode);
6433            } catch (Exception e) {
6434                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6435                badApp = true;
6436            }
6437        }
6438
6439        if (badApp) {
6440            app.kill("error during init", true);
6441            handleAppDiedLocked(app, false, true);
6442            return false;
6443        }
6444
6445        if (!didSomething) {
6446            updateOomAdjLocked();
6447        }
6448
6449        return true;
6450    }
6451
6452    @Override
6453    public final void attachApplication(IApplicationThread thread) {
6454        synchronized (this) {
6455            int callingPid = Binder.getCallingPid();
6456            final long origId = Binder.clearCallingIdentity();
6457            attachApplicationLocked(thread, callingPid);
6458            Binder.restoreCallingIdentity(origId);
6459        }
6460    }
6461
6462    @Override
6463    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6464        final long origId = Binder.clearCallingIdentity();
6465        synchronized (this) {
6466            ActivityStack stack = ActivityRecord.getStackLocked(token);
6467            if (stack != null) {
6468                ActivityRecord r =
6469                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6470                if (stopProfiling) {
6471                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6472                        try {
6473                            mProfileFd.close();
6474                        } catch (IOException e) {
6475                        }
6476                        clearProfilerLocked();
6477                    }
6478                }
6479            }
6480        }
6481        Binder.restoreCallingIdentity(origId);
6482    }
6483
6484    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6485        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6486                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6487    }
6488
6489    void enableScreenAfterBoot() {
6490        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6491                SystemClock.uptimeMillis());
6492        mWindowManager.enableScreenAfterBoot();
6493
6494        synchronized (this) {
6495            updateEventDispatchingLocked();
6496        }
6497    }
6498
6499    @Override
6500    public void showBootMessage(final CharSequence msg, final boolean always) {
6501        if (Binder.getCallingUid() != Process.myUid()) {
6502            // These days only the core system can call this, so apps can't get in
6503            // the way of what we show about running them.
6504        }
6505        mWindowManager.showBootMessage(msg, always);
6506    }
6507
6508    @Override
6509    public void keyguardWaitingForActivityDrawn() {
6510        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6511        final long token = Binder.clearCallingIdentity();
6512        try {
6513            synchronized (this) {
6514                if (DEBUG_LOCKSCREEN) logLockScreen("");
6515                mWindowManager.keyguardWaitingForActivityDrawn();
6516                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6517                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6518                    updateSleepIfNeededLocked();
6519                }
6520            }
6521        } finally {
6522            Binder.restoreCallingIdentity(token);
6523        }
6524    }
6525
6526    @Override
6527    public void keyguardGoingAway(int flags) {
6528        enforceNotIsolatedCaller("keyguardGoingAway");
6529        final long token = Binder.clearCallingIdentity();
6530        try {
6531            synchronized (this) {
6532                if (DEBUG_LOCKSCREEN) logLockScreen("");
6533                mWindowManager.keyguardGoingAway(flags);
6534                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6535                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6536                    updateSleepIfNeededLocked();
6537
6538                    // Some stack visibility might change (e.g. docked stack)
6539                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6540                }
6541            }
6542        } finally {
6543            Binder.restoreCallingIdentity(token);
6544        }
6545    }
6546
6547    final void finishBooting() {
6548        synchronized (this) {
6549            if (!mBootAnimationComplete) {
6550                mCallFinishBooting = true;
6551                return;
6552            }
6553            mCallFinishBooting = false;
6554        }
6555
6556        ArraySet<String> completedIsas = new ArraySet<String>();
6557        for (String abi : Build.SUPPORTED_ABIS) {
6558            Process.establishZygoteConnectionForAbi(abi);
6559            final String instructionSet = VMRuntime.getInstructionSet(abi);
6560            if (!completedIsas.contains(instructionSet)) {
6561                try {
6562                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6563                } catch (InstallerException e) {
6564                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6565                }
6566                completedIsas.add(instructionSet);
6567            }
6568        }
6569
6570        IntentFilter pkgFilter = new IntentFilter();
6571        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6572        pkgFilter.addDataScheme("package");
6573        mContext.registerReceiver(new BroadcastReceiver() {
6574            @Override
6575            public void onReceive(Context context, Intent intent) {
6576                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6577                if (pkgs != null) {
6578                    for (String pkg : pkgs) {
6579                        synchronized (ActivityManagerService.this) {
6580                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6581                                    0, "query restart")) {
6582                                setResultCode(Activity.RESULT_OK);
6583                                return;
6584                            }
6585                        }
6586                    }
6587                }
6588            }
6589        }, pkgFilter);
6590
6591        IntentFilter dumpheapFilter = new IntentFilter();
6592        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6593        mContext.registerReceiver(new BroadcastReceiver() {
6594            @Override
6595            public void onReceive(Context context, Intent intent) {
6596                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6597                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6598                } else {
6599                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6600                }
6601            }
6602        }, dumpheapFilter);
6603
6604        // Let system services know.
6605        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6606
6607        synchronized (this) {
6608            // Ensure that any processes we had put on hold are now started
6609            // up.
6610            final int NP = mProcessesOnHold.size();
6611            if (NP > 0) {
6612                ArrayList<ProcessRecord> procs =
6613                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6614                for (int ip=0; ip<NP; ip++) {
6615                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6616                            + procs.get(ip));
6617                    startProcessLocked(procs.get(ip), "on-hold", null);
6618                }
6619            }
6620
6621            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6622                // Start looking for apps that are abusing wake locks.
6623                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6624                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6625                // Tell anyone interested that we are done booting!
6626                SystemProperties.set("sys.boot_completed", "1");
6627
6628                // And trigger dev.bootcomplete if we are not showing encryption progress
6629                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6630                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6631                    SystemProperties.set("dev.bootcomplete", "1");
6632                }
6633                mUserController.sendBootCompletedLocked(
6634                        new IIntentReceiver.Stub() {
6635                            @Override
6636                            public void performReceive(Intent intent, int resultCode,
6637                                    String data, Bundle extras, boolean ordered,
6638                                    boolean sticky, int sendingUser) {
6639                                synchronized (ActivityManagerService.this) {
6640                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6641                                            true, false);
6642                                }
6643                            }
6644                        });
6645                scheduleStartProfilesLocked();
6646            }
6647        }
6648    }
6649
6650    @Override
6651    public void bootAnimationComplete() {
6652        final boolean callFinishBooting;
6653        synchronized (this) {
6654            callFinishBooting = mCallFinishBooting;
6655            mBootAnimationComplete = true;
6656        }
6657        if (callFinishBooting) {
6658            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6659            finishBooting();
6660            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6661        }
6662    }
6663
6664    final void ensureBootCompleted() {
6665        boolean booting;
6666        boolean enableScreen;
6667        synchronized (this) {
6668            booting = mBooting;
6669            mBooting = false;
6670            enableScreen = !mBooted;
6671            mBooted = true;
6672        }
6673
6674        if (booting) {
6675            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6676            finishBooting();
6677            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6678        }
6679
6680        if (enableScreen) {
6681            enableScreenAfterBoot();
6682        }
6683    }
6684
6685    @Override
6686    public final void activityResumed(IBinder token) {
6687        final long origId = Binder.clearCallingIdentity();
6688        synchronized(this) {
6689            ActivityStack stack = ActivityRecord.getStackLocked(token);
6690            if (stack != null) {
6691                stack.activityResumedLocked(token);
6692            }
6693        }
6694        Binder.restoreCallingIdentity(origId);
6695    }
6696
6697    @Override
6698    public final void activityPaused(IBinder token) {
6699        final long origId = Binder.clearCallingIdentity();
6700        synchronized(this) {
6701            ActivityStack stack = ActivityRecord.getStackLocked(token);
6702            if (stack != null) {
6703                stack.activityPausedLocked(token, false);
6704            }
6705        }
6706        Binder.restoreCallingIdentity(origId);
6707    }
6708
6709    @Override
6710    public final void activityStopped(IBinder token, Bundle icicle,
6711            PersistableBundle persistentState, CharSequence description) {
6712        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6713
6714        // Refuse possible leaked file descriptors
6715        if (icicle != null && icicle.hasFileDescriptors()) {
6716            throw new IllegalArgumentException("File descriptors passed in Bundle");
6717        }
6718
6719        final long origId = Binder.clearCallingIdentity();
6720
6721        synchronized (this) {
6722            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6723            if (r != null) {
6724                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6725            }
6726        }
6727
6728        trimApplications();
6729
6730        Binder.restoreCallingIdentity(origId);
6731    }
6732
6733    @Override
6734    public final void activityDestroyed(IBinder token) {
6735        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6736        synchronized (this) {
6737            ActivityStack stack = ActivityRecord.getStackLocked(token);
6738            if (stack != null) {
6739                stack.activityDestroyedLocked(token, "activityDestroyed");
6740            }
6741        }
6742    }
6743
6744    @Override
6745    public final void activityRelaunched(IBinder token) {
6746        final long origId = Binder.clearCallingIdentity();
6747        synchronized (this) {
6748            mStackSupervisor.activityRelaunchedLocked(token);
6749        }
6750        Binder.restoreCallingIdentity(origId);
6751    }
6752
6753    @Override
6754    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6755            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6756        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6757                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6758        synchronized (this) {
6759            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6760            if (record == null) {
6761                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6762                        + "found for: " + token);
6763            }
6764            record.setSizeConfigurations(horizontalSizeConfiguration,
6765                    verticalSizeConfigurations, smallestSizeConfigurations);
6766        }
6767    }
6768
6769    @Override
6770    public final void backgroundResourcesReleased(IBinder token) {
6771        final long origId = Binder.clearCallingIdentity();
6772        try {
6773            synchronized (this) {
6774                ActivityStack stack = ActivityRecord.getStackLocked(token);
6775                if (stack != null) {
6776                    stack.backgroundResourcesReleased();
6777                }
6778            }
6779        } finally {
6780            Binder.restoreCallingIdentity(origId);
6781        }
6782    }
6783
6784    @Override
6785    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6786        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6787    }
6788
6789    @Override
6790    public final void notifyEnterAnimationComplete(IBinder token) {
6791        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6792    }
6793
6794    @Override
6795    public String getCallingPackage(IBinder token) {
6796        synchronized (this) {
6797            ActivityRecord r = getCallingRecordLocked(token);
6798            return r != null ? r.info.packageName : null;
6799        }
6800    }
6801
6802    @Override
6803    public ComponentName getCallingActivity(IBinder token) {
6804        synchronized (this) {
6805            ActivityRecord r = getCallingRecordLocked(token);
6806            return r != null ? r.intent.getComponent() : null;
6807        }
6808    }
6809
6810    private ActivityRecord getCallingRecordLocked(IBinder token) {
6811        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6812        if (r == null) {
6813            return null;
6814        }
6815        return r.resultTo;
6816    }
6817
6818    @Override
6819    public ComponentName getActivityClassForToken(IBinder token) {
6820        synchronized(this) {
6821            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6822            if (r == null) {
6823                return null;
6824            }
6825            return r.intent.getComponent();
6826        }
6827    }
6828
6829    @Override
6830    public String getPackageForToken(IBinder token) {
6831        synchronized(this) {
6832            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6833            if (r == null) {
6834                return null;
6835            }
6836            return r.packageName;
6837        }
6838    }
6839
6840    @Override
6841    public boolean isRootVoiceInteraction(IBinder token) {
6842        synchronized(this) {
6843            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6844            if (r == null) {
6845                return false;
6846            }
6847            return r.rootVoiceInteraction;
6848        }
6849    }
6850
6851    @Override
6852    public IIntentSender getIntentSender(int type,
6853            String packageName, IBinder token, String resultWho,
6854            int requestCode, Intent[] intents, String[] resolvedTypes,
6855            int flags, Bundle bOptions, int userId) {
6856        enforceNotIsolatedCaller("getIntentSender");
6857        // Refuse possible leaked file descriptors
6858        if (intents != null) {
6859            if (intents.length < 1) {
6860                throw new IllegalArgumentException("Intents array length must be >= 1");
6861            }
6862            for (int i=0; i<intents.length; i++) {
6863                Intent intent = intents[i];
6864                if (intent != null) {
6865                    if (intent.hasFileDescriptors()) {
6866                        throw new IllegalArgumentException("File descriptors passed in Intent");
6867                    }
6868                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6869                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6870                        throw new IllegalArgumentException(
6871                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6872                    }
6873                    intents[i] = new Intent(intent);
6874                }
6875            }
6876            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6877                throw new IllegalArgumentException(
6878                        "Intent array length does not match resolvedTypes length");
6879            }
6880        }
6881        if (bOptions != null) {
6882            if (bOptions.hasFileDescriptors()) {
6883                throw new IllegalArgumentException("File descriptors passed in options");
6884            }
6885        }
6886
6887        synchronized(this) {
6888            int callingUid = Binder.getCallingUid();
6889            int origUserId = userId;
6890            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6891                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6892                    ALLOW_NON_FULL, "getIntentSender", null);
6893            if (origUserId == UserHandle.USER_CURRENT) {
6894                // We don't want to evaluate this until the pending intent is
6895                // actually executed.  However, we do want to always do the
6896                // security checking for it above.
6897                userId = UserHandle.USER_CURRENT;
6898            }
6899            try {
6900                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6901                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6902                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6903                    if (!UserHandle.isSameApp(callingUid, uid)) {
6904                        String msg = "Permission Denial: getIntentSender() from pid="
6905                            + Binder.getCallingPid()
6906                            + ", uid=" + Binder.getCallingUid()
6907                            + ", (need uid=" + uid + ")"
6908                            + " is not allowed to send as package " + packageName;
6909                        Slog.w(TAG, msg);
6910                        throw new SecurityException(msg);
6911                    }
6912                }
6913
6914                return getIntentSenderLocked(type, packageName, callingUid, userId,
6915                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6916
6917            } catch (RemoteException e) {
6918                throw new SecurityException(e);
6919            }
6920        }
6921    }
6922
6923    IIntentSender getIntentSenderLocked(int type, String packageName,
6924            int callingUid, int userId, IBinder token, String resultWho,
6925            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6926            Bundle bOptions) {
6927        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6928        ActivityRecord activity = null;
6929        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6930            activity = ActivityRecord.isInStackLocked(token);
6931            if (activity == null) {
6932                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6933                return null;
6934            }
6935            if (activity.finishing) {
6936                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6937                return null;
6938            }
6939        }
6940
6941        // We're going to be splicing together extras before sending, so we're
6942        // okay poking into any contained extras.
6943        if (intents != null) {
6944            for (int i = 0; i < intents.length; i++) {
6945                intents[i].setDefusable(true);
6946            }
6947        }
6948        Bundle.setDefusable(bOptions, true);
6949
6950        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6951        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6952        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6953        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6954                |PendingIntent.FLAG_UPDATE_CURRENT);
6955
6956        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6957                type, packageName, activity, resultWho,
6958                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6959        WeakReference<PendingIntentRecord> ref;
6960        ref = mIntentSenderRecords.get(key);
6961        PendingIntentRecord rec = ref != null ? ref.get() : null;
6962        if (rec != null) {
6963            if (!cancelCurrent) {
6964                if (updateCurrent) {
6965                    if (rec.key.requestIntent != null) {
6966                        rec.key.requestIntent.replaceExtras(intents != null ?
6967                                intents[intents.length - 1] : null);
6968                    }
6969                    if (intents != null) {
6970                        intents[intents.length-1] = rec.key.requestIntent;
6971                        rec.key.allIntents = intents;
6972                        rec.key.allResolvedTypes = resolvedTypes;
6973                    } else {
6974                        rec.key.allIntents = null;
6975                        rec.key.allResolvedTypes = null;
6976                    }
6977                }
6978                return rec;
6979            }
6980            rec.canceled = true;
6981            mIntentSenderRecords.remove(key);
6982        }
6983        if (noCreate) {
6984            return rec;
6985        }
6986        rec = new PendingIntentRecord(this, key, callingUid);
6987        mIntentSenderRecords.put(key, rec.ref);
6988        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6989            if (activity.pendingResults == null) {
6990                activity.pendingResults
6991                        = new HashSet<WeakReference<PendingIntentRecord>>();
6992            }
6993            activity.pendingResults.add(rec.ref);
6994        }
6995        return rec;
6996    }
6997
6998    @Override
6999    public void cancelIntentSender(IIntentSender sender) {
7000        if (!(sender instanceof PendingIntentRecord)) {
7001            return;
7002        }
7003        synchronized(this) {
7004            PendingIntentRecord rec = (PendingIntentRecord)sender;
7005            try {
7006                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7007                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7008                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7009                    String msg = "Permission Denial: cancelIntentSender() from pid="
7010                        + Binder.getCallingPid()
7011                        + ", uid=" + Binder.getCallingUid()
7012                        + " is not allowed to cancel packges "
7013                        + rec.key.packageName;
7014                    Slog.w(TAG, msg);
7015                    throw new SecurityException(msg);
7016                }
7017            } catch (RemoteException e) {
7018                throw new SecurityException(e);
7019            }
7020            cancelIntentSenderLocked(rec, true);
7021        }
7022    }
7023
7024    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7025        rec.canceled = true;
7026        mIntentSenderRecords.remove(rec.key);
7027        if (cleanActivity && rec.key.activity != null) {
7028            rec.key.activity.pendingResults.remove(rec.ref);
7029        }
7030    }
7031
7032    @Override
7033    public String getPackageForIntentSender(IIntentSender pendingResult) {
7034        if (!(pendingResult instanceof PendingIntentRecord)) {
7035            return null;
7036        }
7037        try {
7038            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7039            return res.key.packageName;
7040        } catch (ClassCastException e) {
7041        }
7042        return null;
7043    }
7044
7045    @Override
7046    public int getUidForIntentSender(IIntentSender sender) {
7047        if (sender instanceof PendingIntentRecord) {
7048            try {
7049                PendingIntentRecord res = (PendingIntentRecord)sender;
7050                return res.uid;
7051            } catch (ClassCastException e) {
7052            }
7053        }
7054        return -1;
7055    }
7056
7057    @Override
7058    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7059        if (!(pendingResult instanceof PendingIntentRecord)) {
7060            return false;
7061        }
7062        try {
7063            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7064            if (res.key.allIntents == null) {
7065                return false;
7066            }
7067            for (int i=0; i<res.key.allIntents.length; i++) {
7068                Intent intent = res.key.allIntents[i];
7069                if (intent.getPackage() != null && intent.getComponent() != null) {
7070                    return false;
7071                }
7072            }
7073            return true;
7074        } catch (ClassCastException e) {
7075        }
7076        return false;
7077    }
7078
7079    @Override
7080    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7081        if (!(pendingResult instanceof PendingIntentRecord)) {
7082            return false;
7083        }
7084        try {
7085            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7086            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7087                return true;
7088            }
7089            return false;
7090        } catch (ClassCastException e) {
7091        }
7092        return false;
7093    }
7094
7095    @Override
7096    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7097        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7098                "getIntentForIntentSender()");
7099        if (!(pendingResult instanceof PendingIntentRecord)) {
7100            return null;
7101        }
7102        try {
7103            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7104            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7105        } catch (ClassCastException e) {
7106        }
7107        return null;
7108    }
7109
7110    @Override
7111    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7112        if (!(pendingResult instanceof PendingIntentRecord)) {
7113            return null;
7114        }
7115        try {
7116            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7117            synchronized (this) {
7118                return getTagForIntentSenderLocked(res, prefix);
7119            }
7120        } catch (ClassCastException e) {
7121        }
7122        return null;
7123    }
7124
7125    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7126        final Intent intent = res.key.requestIntent;
7127        if (intent != null) {
7128            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7129                    || res.lastTagPrefix.equals(prefix))) {
7130                return res.lastTag;
7131            }
7132            res.lastTagPrefix = prefix;
7133            final StringBuilder sb = new StringBuilder(128);
7134            if (prefix != null) {
7135                sb.append(prefix);
7136            }
7137            if (intent.getAction() != null) {
7138                sb.append(intent.getAction());
7139            } else if (intent.getComponent() != null) {
7140                intent.getComponent().appendShortString(sb);
7141            } else {
7142                sb.append("?");
7143            }
7144            return res.lastTag = sb.toString();
7145        }
7146        return null;
7147    }
7148
7149    @Override
7150    public void setProcessLimit(int max) {
7151        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7152                "setProcessLimit()");
7153        synchronized (this) {
7154            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7155            mProcessLimitOverride = max;
7156        }
7157        trimApplications();
7158    }
7159
7160    @Override
7161    public int getProcessLimit() {
7162        synchronized (this) {
7163            return mProcessLimitOverride;
7164        }
7165    }
7166
7167    void foregroundTokenDied(ForegroundToken token) {
7168        synchronized (ActivityManagerService.this) {
7169            synchronized (mPidsSelfLocked) {
7170                ForegroundToken cur
7171                    = mForegroundProcesses.get(token.pid);
7172                if (cur != token) {
7173                    return;
7174                }
7175                mForegroundProcesses.remove(token.pid);
7176                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7177                if (pr == null) {
7178                    return;
7179                }
7180                pr.forcingToForeground = null;
7181                updateProcessForegroundLocked(pr, false, false);
7182            }
7183            updateOomAdjLocked();
7184        }
7185    }
7186
7187    @Override
7188    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7189        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7190                "setProcessForeground()");
7191        synchronized(this) {
7192            boolean changed = false;
7193
7194            synchronized (mPidsSelfLocked) {
7195                ProcessRecord pr = mPidsSelfLocked.get(pid);
7196                if (pr == null && isForeground) {
7197                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7198                    return;
7199                }
7200                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7201                if (oldToken != null) {
7202                    oldToken.token.unlinkToDeath(oldToken, 0);
7203                    mForegroundProcesses.remove(pid);
7204                    if (pr != null) {
7205                        pr.forcingToForeground = null;
7206                    }
7207                    changed = true;
7208                }
7209                if (isForeground && token != null) {
7210                    ForegroundToken newToken = new ForegroundToken() {
7211                        @Override
7212                        public void binderDied() {
7213                            foregroundTokenDied(this);
7214                        }
7215                    };
7216                    newToken.pid = pid;
7217                    newToken.token = token;
7218                    try {
7219                        token.linkToDeath(newToken, 0);
7220                        mForegroundProcesses.put(pid, newToken);
7221                        pr.forcingToForeground = token;
7222                        changed = true;
7223                    } catch (RemoteException e) {
7224                        // If the process died while doing this, we will later
7225                        // do the cleanup with the process death link.
7226                    }
7227                }
7228            }
7229
7230            if (changed) {
7231                updateOomAdjLocked();
7232            }
7233        }
7234    }
7235
7236    @Override
7237    public boolean isAppForeground(int uid) throws RemoteException {
7238        synchronized (this) {
7239            UidRecord uidRec = mActiveUids.get(uid);
7240            if (uidRec == null || uidRec.idle) {
7241                return false;
7242            }
7243            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7244        }
7245    }
7246
7247    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7248    // be guarded by permission checking.
7249    int getUidState(int uid) {
7250        synchronized (this) {
7251            UidRecord uidRec = mActiveUids.get(uid);
7252            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7253        }
7254    }
7255
7256    @Override
7257    public boolean isInMultiWindowMode(IBinder token) {
7258        final long origId = Binder.clearCallingIdentity();
7259        try {
7260            synchronized(this) {
7261                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7262                if (r == null) {
7263                    return false;
7264                }
7265                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7266                return !r.task.mFullscreen;
7267            }
7268        } finally {
7269            Binder.restoreCallingIdentity(origId);
7270        }
7271    }
7272
7273    @Override
7274    public boolean isInPictureInPictureMode(IBinder token) {
7275        final long origId = Binder.clearCallingIdentity();
7276        try {
7277            synchronized(this) {
7278                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7279                if (stack == null) {
7280                    return false;
7281                }
7282                return stack.mStackId == PINNED_STACK_ID;
7283            }
7284        } finally {
7285            Binder.restoreCallingIdentity(origId);
7286        }
7287    }
7288
7289    @Override
7290    public void enterPictureInPictureMode(IBinder token) {
7291        final long origId = Binder.clearCallingIdentity();
7292        try {
7293            synchronized(this) {
7294                if (!mSupportsPictureInPicture) {
7295                    throw new IllegalStateException("enterPictureInPictureMode: "
7296                            + "Device doesn't support picture-in-picture mode.");
7297                }
7298
7299                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7300
7301                if (r == null) {
7302                    throw new IllegalStateException("enterPictureInPictureMode: "
7303                            + "Can't find activity for token=" + token);
7304                }
7305
7306                if (!r.supportsPictureInPicture()) {
7307                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7308                            + "Picture-In-Picture not supported for r=" + r);
7309                }
7310
7311                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7312                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7313                        ? mDefaultPinnedStackBounds : null;
7314
7315                mStackSupervisor.moveActivityToPinnedStackLocked(
7316                        r, "enterPictureInPictureMode", bounds);
7317            }
7318        } finally {
7319            Binder.restoreCallingIdentity(origId);
7320        }
7321    }
7322
7323    // =========================================================
7324    // PROCESS INFO
7325    // =========================================================
7326
7327    static class ProcessInfoService extends IProcessInfoService.Stub {
7328        final ActivityManagerService mActivityManagerService;
7329        ProcessInfoService(ActivityManagerService activityManagerService) {
7330            mActivityManagerService = activityManagerService;
7331        }
7332
7333        @Override
7334        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7335            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7336                    /*in*/ pids, /*out*/ states, null);
7337        }
7338
7339        @Override
7340        public void getProcessStatesAndOomScoresFromPids(
7341                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7342            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7343                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7344        }
7345    }
7346
7347    /**
7348     * For each PID in the given input array, write the current process state
7349     * for that process into the states array, or -1 to indicate that no
7350     * process with the given PID exists. If scores array is provided, write
7351     * the oom score for the process into the scores array, with INVALID_ADJ
7352     * indicating the PID doesn't exist.
7353     */
7354    public void getProcessStatesAndOomScoresForPIDs(
7355            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7356        if (scores != null) {
7357            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7358                    "getProcessStatesAndOomScoresForPIDs()");
7359        }
7360
7361        if (pids == null) {
7362            throw new NullPointerException("pids");
7363        } else if (states == null) {
7364            throw new NullPointerException("states");
7365        } else if (pids.length != states.length) {
7366            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7367        } else if (scores != null && pids.length != scores.length) {
7368            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7369        }
7370
7371        synchronized (mPidsSelfLocked) {
7372            for (int i = 0; i < pids.length; i++) {
7373                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7374                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7375                        pr.curProcState;
7376                if (scores != null) {
7377                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7378                }
7379            }
7380        }
7381    }
7382
7383    // =========================================================
7384    // PERMISSIONS
7385    // =========================================================
7386
7387    static class PermissionController extends IPermissionController.Stub {
7388        ActivityManagerService mActivityManagerService;
7389        PermissionController(ActivityManagerService activityManagerService) {
7390            mActivityManagerService = activityManagerService;
7391        }
7392
7393        @Override
7394        public boolean checkPermission(String permission, int pid, int uid) {
7395            return mActivityManagerService.checkPermission(permission, pid,
7396                    uid) == PackageManager.PERMISSION_GRANTED;
7397        }
7398
7399        @Override
7400        public String[] getPackagesForUid(int uid) {
7401            return mActivityManagerService.mContext.getPackageManager()
7402                    .getPackagesForUid(uid);
7403        }
7404
7405        @Override
7406        public boolean isRuntimePermission(String permission) {
7407            try {
7408                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7409                        .getPermissionInfo(permission, 0);
7410                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7411            } catch (NameNotFoundException nnfe) {
7412                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7413            }
7414            return false;
7415        }
7416    }
7417
7418    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7419        @Override
7420        public int checkComponentPermission(String permission, int pid, int uid,
7421                int owningUid, boolean exported) {
7422            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7423                    owningUid, exported);
7424        }
7425
7426        @Override
7427        public Object getAMSLock() {
7428            return ActivityManagerService.this;
7429        }
7430    }
7431
7432    /**
7433     * This can be called with or without the global lock held.
7434     */
7435    int checkComponentPermission(String permission, int pid, int uid,
7436            int owningUid, boolean exported) {
7437        if (pid == MY_PID) {
7438            return PackageManager.PERMISSION_GRANTED;
7439        }
7440        return ActivityManager.checkComponentPermission(permission, uid,
7441                owningUid, exported);
7442    }
7443
7444    /**
7445     * As the only public entry point for permissions checking, this method
7446     * can enforce the semantic that requesting a check on a null global
7447     * permission is automatically denied.  (Internally a null permission
7448     * string is used when calling {@link #checkComponentPermission} in cases
7449     * when only uid-based security is needed.)
7450     *
7451     * This can be called with or without the global lock held.
7452     */
7453    @Override
7454    public int checkPermission(String permission, int pid, int uid) {
7455        if (permission == null) {
7456            return PackageManager.PERMISSION_DENIED;
7457        }
7458        return checkComponentPermission(permission, pid, uid, -1, true);
7459    }
7460
7461    @Override
7462    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7463        if (permission == null) {
7464            return PackageManager.PERMISSION_DENIED;
7465        }
7466
7467        // We might be performing an operation on behalf of an indirect binder
7468        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7469        // client identity accordingly before proceeding.
7470        Identity tlsIdentity = sCallerIdentity.get();
7471        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7472            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7473                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7474            uid = tlsIdentity.uid;
7475            pid = tlsIdentity.pid;
7476        }
7477
7478        return checkComponentPermission(permission, pid, uid, -1, true);
7479    }
7480
7481    /**
7482     * Binder IPC calls go through the public entry point.
7483     * This can be called with or without the global lock held.
7484     */
7485    int checkCallingPermission(String permission) {
7486        return checkPermission(permission,
7487                Binder.getCallingPid(),
7488                UserHandle.getAppId(Binder.getCallingUid()));
7489    }
7490
7491    /**
7492     * This can be called with or without the global lock held.
7493     */
7494    void enforceCallingPermission(String permission, String func) {
7495        if (checkCallingPermission(permission)
7496                == PackageManager.PERMISSION_GRANTED) {
7497            return;
7498        }
7499
7500        String msg = "Permission Denial: " + func + " from pid="
7501                + Binder.getCallingPid()
7502                + ", uid=" + Binder.getCallingUid()
7503                + " requires " + permission;
7504        Slog.w(TAG, msg);
7505        throw new SecurityException(msg);
7506    }
7507
7508    /**
7509     * Determine if UID is holding permissions required to access {@link Uri} in
7510     * the given {@link ProviderInfo}. Final permission checking is always done
7511     * in {@link ContentProvider}.
7512     */
7513    private final boolean checkHoldingPermissionsLocked(
7514            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7515        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7516                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7517        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7518            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7519                    != PERMISSION_GRANTED) {
7520                return false;
7521            }
7522        }
7523        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7524    }
7525
7526    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7527            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7528        if (pi.applicationInfo.uid == uid) {
7529            return true;
7530        } else if (!pi.exported) {
7531            return false;
7532        }
7533
7534        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7535        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7536        try {
7537            // check if target holds top-level <provider> permissions
7538            if (!readMet && pi.readPermission != null && considerUidPermissions
7539                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7540                readMet = true;
7541            }
7542            if (!writeMet && pi.writePermission != null && considerUidPermissions
7543                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7544                writeMet = true;
7545            }
7546
7547            // track if unprotected read/write is allowed; any denied
7548            // <path-permission> below removes this ability
7549            boolean allowDefaultRead = pi.readPermission == null;
7550            boolean allowDefaultWrite = pi.writePermission == null;
7551
7552            // check if target holds any <path-permission> that match uri
7553            final PathPermission[] pps = pi.pathPermissions;
7554            if (pps != null) {
7555                final String path = grantUri.uri.getPath();
7556                int i = pps.length;
7557                while (i > 0 && (!readMet || !writeMet)) {
7558                    i--;
7559                    PathPermission pp = pps[i];
7560                    if (pp.match(path)) {
7561                        if (!readMet) {
7562                            final String pprperm = pp.getReadPermission();
7563                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7564                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7565                                    + ": match=" + pp.match(path)
7566                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7567                            if (pprperm != null) {
7568                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7569                                        == PERMISSION_GRANTED) {
7570                                    readMet = true;
7571                                } else {
7572                                    allowDefaultRead = false;
7573                                }
7574                            }
7575                        }
7576                        if (!writeMet) {
7577                            final String ppwperm = pp.getWritePermission();
7578                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7579                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7580                                    + ": match=" + pp.match(path)
7581                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7582                            if (ppwperm != null) {
7583                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7584                                        == PERMISSION_GRANTED) {
7585                                    writeMet = true;
7586                                } else {
7587                                    allowDefaultWrite = false;
7588                                }
7589                            }
7590                        }
7591                    }
7592                }
7593            }
7594
7595            // grant unprotected <provider> read/write, if not blocked by
7596            // <path-permission> above
7597            if (allowDefaultRead) readMet = true;
7598            if (allowDefaultWrite) writeMet = true;
7599
7600        } catch (RemoteException e) {
7601            return false;
7602        }
7603
7604        return readMet && writeMet;
7605    }
7606
7607    public int getAppStartMode(int uid, String packageName) {
7608        synchronized (this) {
7609            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7610        }
7611    }
7612
7613    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7614            boolean allowWhenForeground) {
7615        UidRecord uidRec = mActiveUids.get(uid);
7616        if (!mLenientBackgroundCheck) {
7617            if (!allowWhenForeground || uidRec == null
7618                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7619                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7620                        packageName) != AppOpsManager.MODE_ALLOWED) {
7621                    return ActivityManager.APP_START_MODE_DELAYED;
7622                }
7623            }
7624
7625        } else if (uidRec == null || uidRec.idle) {
7626            if (callingPid >= 0) {
7627                ProcessRecord proc;
7628                synchronized (mPidsSelfLocked) {
7629                    proc = mPidsSelfLocked.get(callingPid);
7630                }
7631                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7632                    // Whoever is instigating this is in the foreground, so we will allow it
7633                    // to go through.
7634                    return ActivityManager.APP_START_MODE_NORMAL;
7635                }
7636            }
7637            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7638                    != AppOpsManager.MODE_ALLOWED) {
7639                return ActivityManager.APP_START_MODE_DELAYED;
7640            }
7641        }
7642        return ActivityManager.APP_START_MODE_NORMAL;
7643    }
7644
7645    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7646        ProviderInfo pi = null;
7647        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7648        if (cpr != null) {
7649            pi = cpr.info;
7650        } else {
7651            try {
7652                pi = AppGlobals.getPackageManager().resolveContentProvider(
7653                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7654            } catch (RemoteException ex) {
7655            }
7656        }
7657        return pi;
7658    }
7659
7660    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7661        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7662        if (targetUris != null) {
7663            return targetUris.get(grantUri);
7664        }
7665        return null;
7666    }
7667
7668    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7669            String targetPkg, int targetUid, GrantUri grantUri) {
7670        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7671        if (targetUris == null) {
7672            targetUris = Maps.newArrayMap();
7673            mGrantedUriPermissions.put(targetUid, targetUris);
7674        }
7675
7676        UriPermission perm = targetUris.get(grantUri);
7677        if (perm == null) {
7678            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7679            targetUris.put(grantUri, perm);
7680        }
7681
7682        return perm;
7683    }
7684
7685    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7686            final int modeFlags) {
7687        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7688        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7689                : UriPermission.STRENGTH_OWNED;
7690
7691        // Root gets to do everything.
7692        if (uid == 0) {
7693            return true;
7694        }
7695
7696        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7697        if (perms == null) return false;
7698
7699        // First look for exact match
7700        final UriPermission exactPerm = perms.get(grantUri);
7701        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7702            return true;
7703        }
7704
7705        // No exact match, look for prefixes
7706        final int N = perms.size();
7707        for (int i = 0; i < N; i++) {
7708            final UriPermission perm = perms.valueAt(i);
7709            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7710                    && perm.getStrength(modeFlags) >= minStrength) {
7711                return true;
7712            }
7713        }
7714
7715        return false;
7716    }
7717
7718    /**
7719     * @param uri This uri must NOT contain an embedded userId.
7720     * @param userId The userId in which the uri is to be resolved.
7721     */
7722    @Override
7723    public int checkUriPermission(Uri uri, int pid, int uid,
7724            final int modeFlags, int userId, IBinder callerToken) {
7725        enforceNotIsolatedCaller("checkUriPermission");
7726
7727        // Another redirected-binder-call permissions check as in
7728        // {@link checkPermissionWithToken}.
7729        Identity tlsIdentity = sCallerIdentity.get();
7730        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7731            uid = tlsIdentity.uid;
7732            pid = tlsIdentity.pid;
7733        }
7734
7735        // Our own process gets to do everything.
7736        if (pid == MY_PID) {
7737            return PackageManager.PERMISSION_GRANTED;
7738        }
7739        synchronized (this) {
7740            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7741                    ? PackageManager.PERMISSION_GRANTED
7742                    : PackageManager.PERMISSION_DENIED;
7743        }
7744    }
7745
7746    /**
7747     * Check if the targetPkg can be granted permission to access uri by
7748     * the callingUid using the given modeFlags.  Throws a security exception
7749     * if callingUid is not allowed to do this.  Returns the uid of the target
7750     * if the URI permission grant should be performed; returns -1 if it is not
7751     * needed (for example targetPkg already has permission to access the URI).
7752     * If you already know the uid of the target, you can supply it in
7753     * lastTargetUid else set that to -1.
7754     */
7755    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7756            final int modeFlags, int lastTargetUid) {
7757        if (!Intent.isAccessUriMode(modeFlags)) {
7758            return -1;
7759        }
7760
7761        if (targetPkg != null) {
7762            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7763                    "Checking grant " + targetPkg + " permission to " + grantUri);
7764        }
7765
7766        final IPackageManager pm = AppGlobals.getPackageManager();
7767
7768        // If this is not a content: uri, we can't do anything with it.
7769        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7770            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7771                    "Can't grant URI permission for non-content URI: " + grantUri);
7772            return -1;
7773        }
7774
7775        final String authority = grantUri.uri.getAuthority();
7776        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7777        if (pi == null) {
7778            Slog.w(TAG, "No content provider found for permission check: " +
7779                    grantUri.uri.toSafeString());
7780            return -1;
7781        }
7782
7783        int targetUid = lastTargetUid;
7784        if (targetUid < 0 && targetPkg != null) {
7785            try {
7786                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7787                        UserHandle.getUserId(callingUid));
7788                if (targetUid < 0) {
7789                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7790                            "Can't grant URI permission no uid for: " + targetPkg);
7791                    return -1;
7792                }
7793            } catch (RemoteException ex) {
7794                return -1;
7795            }
7796        }
7797
7798        if (targetUid >= 0) {
7799            // First...  does the target actually need this permission?
7800            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7801                // No need to grant the target this permission.
7802                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7803                        "Target " + targetPkg + " already has full permission to " + grantUri);
7804                return -1;
7805            }
7806        } else {
7807            // First...  there is no target package, so can anyone access it?
7808            boolean allowed = pi.exported;
7809            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7810                if (pi.readPermission != null) {
7811                    allowed = false;
7812                }
7813            }
7814            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7815                if (pi.writePermission != null) {
7816                    allowed = false;
7817                }
7818            }
7819            if (allowed) {
7820                return -1;
7821            }
7822        }
7823
7824        /* There is a special cross user grant if:
7825         * - The target is on another user.
7826         * - Apps on the current user can access the uri without any uid permissions.
7827         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7828         * grant uri permissions.
7829         */
7830        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7831                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7832                modeFlags, false /*without considering the uid permissions*/);
7833
7834        // Second...  is the provider allowing granting of URI permissions?
7835        if (!specialCrossUserGrant) {
7836            if (!pi.grantUriPermissions) {
7837                throw new SecurityException("Provider " + pi.packageName
7838                        + "/" + pi.name
7839                        + " does not allow granting of Uri permissions (uri "
7840                        + grantUri + ")");
7841            }
7842            if (pi.uriPermissionPatterns != null) {
7843                final int N = pi.uriPermissionPatterns.length;
7844                boolean allowed = false;
7845                for (int i=0; i<N; i++) {
7846                    if (pi.uriPermissionPatterns[i] != null
7847                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7848                        allowed = true;
7849                        break;
7850                    }
7851                }
7852                if (!allowed) {
7853                    throw new SecurityException("Provider " + pi.packageName
7854                            + "/" + pi.name
7855                            + " does not allow granting of permission to path of Uri "
7856                            + grantUri);
7857                }
7858            }
7859        }
7860
7861        // Third...  does the caller itself have permission to access
7862        // this uri?
7863        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7864            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7865                // Require they hold a strong enough Uri permission
7866                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7867                    throw new SecurityException("Uid " + callingUid
7868                            + " does not have permission to uri " + grantUri);
7869                }
7870            }
7871        }
7872        return targetUid;
7873    }
7874
7875    /**
7876     * @param uri This uri must NOT contain an embedded userId.
7877     * @param userId The userId in which the uri is to be resolved.
7878     */
7879    @Override
7880    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7881            final int modeFlags, int userId) {
7882        enforceNotIsolatedCaller("checkGrantUriPermission");
7883        synchronized(this) {
7884            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7885                    new GrantUri(userId, uri, false), modeFlags, -1);
7886        }
7887    }
7888
7889    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7890            final int modeFlags, UriPermissionOwner owner) {
7891        if (!Intent.isAccessUriMode(modeFlags)) {
7892            return;
7893        }
7894
7895        // So here we are: the caller has the assumed permission
7896        // to the uri, and the target doesn't.  Let's now give this to
7897        // the target.
7898
7899        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7900                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7901
7902        final String authority = grantUri.uri.getAuthority();
7903        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7904        if (pi == null) {
7905            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7906            return;
7907        }
7908
7909        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7910            grantUri.prefix = true;
7911        }
7912        final UriPermission perm = findOrCreateUriPermissionLocked(
7913                pi.packageName, targetPkg, targetUid, grantUri);
7914        perm.grantModes(modeFlags, owner);
7915    }
7916
7917    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7918            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7919        if (targetPkg == null) {
7920            throw new NullPointerException("targetPkg");
7921        }
7922        int targetUid;
7923        final IPackageManager pm = AppGlobals.getPackageManager();
7924        try {
7925            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7926        } catch (RemoteException ex) {
7927            return;
7928        }
7929
7930        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7931                targetUid);
7932        if (targetUid < 0) {
7933            return;
7934        }
7935
7936        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7937                owner);
7938    }
7939
7940    static class NeededUriGrants extends ArrayList<GrantUri> {
7941        final String targetPkg;
7942        final int targetUid;
7943        final int flags;
7944
7945        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7946            this.targetPkg = targetPkg;
7947            this.targetUid = targetUid;
7948            this.flags = flags;
7949        }
7950    }
7951
7952    /**
7953     * Like checkGrantUriPermissionLocked, but takes an Intent.
7954     */
7955    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7956            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7957        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7958                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7959                + " clip=" + (intent != null ? intent.getClipData() : null)
7960                + " from " + intent + "; flags=0x"
7961                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7962
7963        if (targetPkg == null) {
7964            throw new NullPointerException("targetPkg");
7965        }
7966
7967        if (intent == null) {
7968            return null;
7969        }
7970        Uri data = intent.getData();
7971        ClipData clip = intent.getClipData();
7972        if (data == null && clip == null) {
7973            return null;
7974        }
7975        // Default userId for uris in the intent (if they don't specify it themselves)
7976        int contentUserHint = intent.getContentUserHint();
7977        if (contentUserHint == UserHandle.USER_CURRENT) {
7978            contentUserHint = UserHandle.getUserId(callingUid);
7979        }
7980        final IPackageManager pm = AppGlobals.getPackageManager();
7981        int targetUid;
7982        if (needed != null) {
7983            targetUid = needed.targetUid;
7984        } else {
7985            try {
7986                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7987                        targetUserId);
7988            } catch (RemoteException ex) {
7989                return null;
7990            }
7991            if (targetUid < 0) {
7992                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7993                        "Can't grant URI permission no uid for: " + targetPkg
7994                        + " on user " + targetUserId);
7995                return null;
7996            }
7997        }
7998        if (data != null) {
7999            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8000            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8001                    targetUid);
8002            if (targetUid > 0) {
8003                if (needed == null) {
8004                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8005                }
8006                needed.add(grantUri);
8007            }
8008        }
8009        if (clip != null) {
8010            for (int i=0; i<clip.getItemCount(); i++) {
8011                Uri uri = clip.getItemAt(i).getUri();
8012                if (uri != null) {
8013                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8014                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8015                            targetUid);
8016                    if (targetUid > 0) {
8017                        if (needed == null) {
8018                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8019                        }
8020                        needed.add(grantUri);
8021                    }
8022                } else {
8023                    Intent clipIntent = clip.getItemAt(i).getIntent();
8024                    if (clipIntent != null) {
8025                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8026                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8027                        if (newNeeded != null) {
8028                            needed = newNeeded;
8029                        }
8030                    }
8031                }
8032            }
8033        }
8034
8035        return needed;
8036    }
8037
8038    /**
8039     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8040     */
8041    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8042            UriPermissionOwner owner) {
8043        if (needed != null) {
8044            for (int i=0; i<needed.size(); i++) {
8045                GrantUri grantUri = needed.get(i);
8046                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8047                        grantUri, needed.flags, owner);
8048            }
8049        }
8050    }
8051
8052    void grantUriPermissionFromIntentLocked(int callingUid,
8053            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8054        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8055                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8056        if (needed == null) {
8057            return;
8058        }
8059
8060        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8061    }
8062
8063    /**
8064     * @param uri This uri must NOT contain an embedded userId.
8065     * @param userId The userId in which the uri is to be resolved.
8066     */
8067    @Override
8068    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8069            final int modeFlags, int userId) {
8070        enforceNotIsolatedCaller("grantUriPermission");
8071        GrantUri grantUri = new GrantUri(userId, uri, false);
8072        synchronized(this) {
8073            final ProcessRecord r = getRecordForAppLocked(caller);
8074            if (r == null) {
8075                throw new SecurityException("Unable to find app for caller "
8076                        + caller
8077                        + " when granting permission to uri " + grantUri);
8078            }
8079            if (targetPkg == null) {
8080                throw new IllegalArgumentException("null target");
8081            }
8082            if (grantUri == null) {
8083                throw new IllegalArgumentException("null uri");
8084            }
8085
8086            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8087                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8088                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8089                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8090
8091            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8092                    UserHandle.getUserId(r.uid));
8093        }
8094    }
8095
8096    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8097        if (perm.modeFlags == 0) {
8098            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8099                    perm.targetUid);
8100            if (perms != null) {
8101                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8102                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8103
8104                perms.remove(perm.uri);
8105                if (perms.isEmpty()) {
8106                    mGrantedUriPermissions.remove(perm.targetUid);
8107                }
8108            }
8109        }
8110    }
8111
8112    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8113        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8114                "Revoking all granted permissions to " + grantUri);
8115
8116        final IPackageManager pm = AppGlobals.getPackageManager();
8117        final String authority = grantUri.uri.getAuthority();
8118        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8119        if (pi == null) {
8120            Slog.w(TAG, "No content provider found for permission revoke: "
8121                    + grantUri.toSafeString());
8122            return;
8123        }
8124
8125        // Does the caller have this permission on the URI?
8126        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8127            // If they don't have direct access to the URI, then revoke any
8128            // ownerless URI permissions that have been granted to them.
8129            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8130            if (perms != null) {
8131                boolean persistChanged = false;
8132                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8133                    final UriPermission perm = it.next();
8134                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8135                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8136                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8137                                "Revoking non-owned " + perm.targetUid
8138                                + " permission to " + perm.uri);
8139                        persistChanged |= perm.revokeModes(
8140                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8141                        if (perm.modeFlags == 0) {
8142                            it.remove();
8143                        }
8144                    }
8145                }
8146                if (perms.isEmpty()) {
8147                    mGrantedUriPermissions.remove(callingUid);
8148                }
8149                if (persistChanged) {
8150                    schedulePersistUriGrants();
8151                }
8152            }
8153            return;
8154        }
8155
8156        boolean persistChanged = false;
8157
8158        // Go through all of the permissions and remove any that match.
8159        int N = mGrantedUriPermissions.size();
8160        for (int i = 0; i < N; i++) {
8161            final int targetUid = mGrantedUriPermissions.keyAt(i);
8162            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8163
8164            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8165                final UriPermission perm = it.next();
8166                if (perm.uri.sourceUserId == grantUri.sourceUserId
8167                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8168                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8169                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8170                    persistChanged |= perm.revokeModes(
8171                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8172                    if (perm.modeFlags == 0) {
8173                        it.remove();
8174                    }
8175                }
8176            }
8177
8178            if (perms.isEmpty()) {
8179                mGrantedUriPermissions.remove(targetUid);
8180                N--;
8181                i--;
8182            }
8183        }
8184
8185        if (persistChanged) {
8186            schedulePersistUriGrants();
8187        }
8188    }
8189
8190    /**
8191     * @param uri This uri must NOT contain an embedded userId.
8192     * @param userId The userId in which the uri is to be resolved.
8193     */
8194    @Override
8195    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8196            int userId) {
8197        enforceNotIsolatedCaller("revokeUriPermission");
8198        synchronized(this) {
8199            final ProcessRecord r = getRecordForAppLocked(caller);
8200            if (r == null) {
8201                throw new SecurityException("Unable to find app for caller "
8202                        + caller
8203                        + " when revoking permission to uri " + uri);
8204            }
8205            if (uri == null) {
8206                Slog.w(TAG, "revokeUriPermission: null uri");
8207                return;
8208            }
8209
8210            if (!Intent.isAccessUriMode(modeFlags)) {
8211                return;
8212            }
8213
8214            final String authority = uri.getAuthority();
8215            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8216            if (pi == null) {
8217                Slog.w(TAG, "No content provider found for permission revoke: "
8218                        + uri.toSafeString());
8219                return;
8220            }
8221
8222            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8223        }
8224    }
8225
8226    /**
8227     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8228     * given package.
8229     *
8230     * @param packageName Package name to match, or {@code null} to apply to all
8231     *            packages.
8232     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8233     *            to all users.
8234     * @param persistable If persistable grants should be removed.
8235     */
8236    private void removeUriPermissionsForPackageLocked(
8237            String packageName, int userHandle, boolean persistable) {
8238        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8239            throw new IllegalArgumentException("Must narrow by either package or user");
8240        }
8241
8242        boolean persistChanged = false;
8243
8244        int N = mGrantedUriPermissions.size();
8245        for (int i = 0; i < N; i++) {
8246            final int targetUid = mGrantedUriPermissions.keyAt(i);
8247            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8248
8249            // Only inspect grants matching user
8250            if (userHandle == UserHandle.USER_ALL
8251                    || userHandle == UserHandle.getUserId(targetUid)) {
8252                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8253                    final UriPermission perm = it.next();
8254
8255                    // Only inspect grants matching package
8256                    if (packageName == null || perm.sourcePkg.equals(packageName)
8257                            || perm.targetPkg.equals(packageName)) {
8258                        persistChanged |= perm.revokeModes(persistable
8259                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8260
8261                        // Only remove when no modes remain; any persisted grants
8262                        // will keep this alive.
8263                        if (perm.modeFlags == 0) {
8264                            it.remove();
8265                        }
8266                    }
8267                }
8268
8269                if (perms.isEmpty()) {
8270                    mGrantedUriPermissions.remove(targetUid);
8271                    N--;
8272                    i--;
8273                }
8274            }
8275        }
8276
8277        if (persistChanged) {
8278            schedulePersistUriGrants();
8279        }
8280    }
8281
8282    @Override
8283    public IBinder newUriPermissionOwner(String name) {
8284        enforceNotIsolatedCaller("newUriPermissionOwner");
8285        synchronized(this) {
8286            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8287            return owner.getExternalTokenLocked();
8288        }
8289    }
8290
8291    @Override
8292    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8293        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8294        synchronized(this) {
8295            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8296            if (r == null) {
8297                throw new IllegalArgumentException("Activity does not exist; token="
8298                        + activityToken);
8299            }
8300            return r.getUriPermissionsLocked().getExternalTokenLocked();
8301        }
8302    }
8303    /**
8304     * @param uri This uri must NOT contain an embedded userId.
8305     * @param sourceUserId The userId in which the uri is to be resolved.
8306     * @param targetUserId The userId of the app that receives the grant.
8307     */
8308    @Override
8309    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8310            final int modeFlags, int sourceUserId, int targetUserId) {
8311        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8312                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8313                "grantUriPermissionFromOwner", null);
8314        synchronized(this) {
8315            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8316            if (owner == null) {
8317                throw new IllegalArgumentException("Unknown owner: " + token);
8318            }
8319            if (fromUid != Binder.getCallingUid()) {
8320                if (Binder.getCallingUid() != Process.myUid()) {
8321                    // Only system code can grant URI permissions on behalf
8322                    // of other users.
8323                    throw new SecurityException("nice try");
8324                }
8325            }
8326            if (targetPkg == null) {
8327                throw new IllegalArgumentException("null target");
8328            }
8329            if (uri == null) {
8330                throw new IllegalArgumentException("null uri");
8331            }
8332
8333            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8334                    modeFlags, owner, targetUserId);
8335        }
8336    }
8337
8338    /**
8339     * @param uri This uri must NOT contain an embedded userId.
8340     * @param userId The userId in which the uri is to be resolved.
8341     */
8342    @Override
8343    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8344        synchronized(this) {
8345            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8346            if (owner == null) {
8347                throw new IllegalArgumentException("Unknown owner: " + token);
8348            }
8349
8350            if (uri == null) {
8351                owner.removeUriPermissionsLocked(mode);
8352            } else {
8353                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8354            }
8355        }
8356    }
8357
8358    private void schedulePersistUriGrants() {
8359        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8360            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8361                    10 * DateUtils.SECOND_IN_MILLIS);
8362        }
8363    }
8364
8365    private void writeGrantedUriPermissions() {
8366        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8367
8368        // Snapshot permissions so we can persist without lock
8369        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8370        synchronized (this) {
8371            final int size = mGrantedUriPermissions.size();
8372            for (int i = 0; i < size; i++) {
8373                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8374                for (UriPermission perm : perms.values()) {
8375                    if (perm.persistedModeFlags != 0) {
8376                        persist.add(perm.snapshot());
8377                    }
8378                }
8379            }
8380        }
8381
8382        FileOutputStream fos = null;
8383        try {
8384            fos = mGrantFile.startWrite();
8385
8386            XmlSerializer out = new FastXmlSerializer();
8387            out.setOutput(fos, StandardCharsets.UTF_8.name());
8388            out.startDocument(null, true);
8389            out.startTag(null, TAG_URI_GRANTS);
8390            for (UriPermission.Snapshot perm : persist) {
8391                out.startTag(null, TAG_URI_GRANT);
8392                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8393                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8394                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8395                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8396                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8397                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8398                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8399                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8400                out.endTag(null, TAG_URI_GRANT);
8401            }
8402            out.endTag(null, TAG_URI_GRANTS);
8403            out.endDocument();
8404
8405            mGrantFile.finishWrite(fos);
8406        } catch (IOException e) {
8407            if (fos != null) {
8408                mGrantFile.failWrite(fos);
8409            }
8410        }
8411    }
8412
8413    private void readGrantedUriPermissionsLocked() {
8414        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8415
8416        final long now = System.currentTimeMillis();
8417
8418        FileInputStream fis = null;
8419        try {
8420            fis = mGrantFile.openRead();
8421            final XmlPullParser in = Xml.newPullParser();
8422            in.setInput(fis, StandardCharsets.UTF_8.name());
8423
8424            int type;
8425            while ((type = in.next()) != END_DOCUMENT) {
8426                final String tag = in.getName();
8427                if (type == START_TAG) {
8428                    if (TAG_URI_GRANT.equals(tag)) {
8429                        final int sourceUserId;
8430                        final int targetUserId;
8431                        final int userHandle = readIntAttribute(in,
8432                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8433                        if (userHandle != UserHandle.USER_NULL) {
8434                            // For backwards compatibility.
8435                            sourceUserId = userHandle;
8436                            targetUserId = userHandle;
8437                        } else {
8438                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8439                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8440                        }
8441                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8442                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8443                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8444                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8445                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8446                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8447
8448                        // Sanity check that provider still belongs to source package
8449                        final ProviderInfo pi = getProviderInfoLocked(
8450                                uri.getAuthority(), sourceUserId);
8451                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8452                            int targetUid = -1;
8453                            try {
8454                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8455                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8456                            } catch (RemoteException e) {
8457                            }
8458                            if (targetUid != -1) {
8459                                final UriPermission perm = findOrCreateUriPermissionLocked(
8460                                        sourcePkg, targetPkg, targetUid,
8461                                        new GrantUri(sourceUserId, uri, prefix));
8462                                perm.initPersistedModes(modeFlags, createdTime);
8463                            }
8464                        } else {
8465                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8466                                    + " but instead found " + pi);
8467                        }
8468                    }
8469                }
8470            }
8471        } catch (FileNotFoundException e) {
8472            // Missing grants is okay
8473        } catch (IOException e) {
8474            Slog.wtf(TAG, "Failed reading Uri grants", e);
8475        } catch (XmlPullParserException e) {
8476            Slog.wtf(TAG, "Failed reading Uri grants", e);
8477        } finally {
8478            IoUtils.closeQuietly(fis);
8479        }
8480    }
8481
8482    /**
8483     * @param uri This uri must NOT contain an embedded userId.
8484     * @param userId The userId in which the uri is to be resolved.
8485     */
8486    @Override
8487    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8488        enforceNotIsolatedCaller("takePersistableUriPermission");
8489
8490        Preconditions.checkFlagsArgument(modeFlags,
8491                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8492
8493        synchronized (this) {
8494            final int callingUid = Binder.getCallingUid();
8495            boolean persistChanged = false;
8496            GrantUri grantUri = new GrantUri(userId, uri, false);
8497
8498            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8499                    new GrantUri(userId, uri, false));
8500            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8501                    new GrantUri(userId, uri, true));
8502
8503            final boolean exactValid = (exactPerm != null)
8504                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8505            final boolean prefixValid = (prefixPerm != null)
8506                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8507
8508            if (!(exactValid || prefixValid)) {
8509                throw new SecurityException("No persistable permission grants found for UID "
8510                        + callingUid + " and Uri " + grantUri.toSafeString());
8511            }
8512
8513            if (exactValid) {
8514                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8515            }
8516            if (prefixValid) {
8517                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8518            }
8519
8520            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8521
8522            if (persistChanged) {
8523                schedulePersistUriGrants();
8524            }
8525        }
8526    }
8527
8528    /**
8529     * @param uri This uri must NOT contain an embedded userId.
8530     * @param userId The userId in which the uri is to be resolved.
8531     */
8532    @Override
8533    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8534        enforceNotIsolatedCaller("releasePersistableUriPermission");
8535
8536        Preconditions.checkFlagsArgument(modeFlags,
8537                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8538
8539        synchronized (this) {
8540            final int callingUid = Binder.getCallingUid();
8541            boolean persistChanged = false;
8542
8543            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8544                    new GrantUri(userId, uri, false));
8545            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8546                    new GrantUri(userId, uri, true));
8547            if (exactPerm == null && prefixPerm == null) {
8548                throw new SecurityException("No permission grants found for UID " + callingUid
8549                        + " and Uri " + uri.toSafeString());
8550            }
8551
8552            if (exactPerm != null) {
8553                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8554                removeUriPermissionIfNeededLocked(exactPerm);
8555            }
8556            if (prefixPerm != null) {
8557                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8558                removeUriPermissionIfNeededLocked(prefixPerm);
8559            }
8560
8561            if (persistChanged) {
8562                schedulePersistUriGrants();
8563            }
8564        }
8565    }
8566
8567    /**
8568     * Prune any older {@link UriPermission} for the given UID until outstanding
8569     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8570     *
8571     * @return if any mutations occured that require persisting.
8572     */
8573    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8574        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8575        if (perms == null) return false;
8576        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8577
8578        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8579        for (UriPermission perm : perms.values()) {
8580            if (perm.persistedModeFlags != 0) {
8581                persisted.add(perm);
8582            }
8583        }
8584
8585        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8586        if (trimCount <= 0) return false;
8587
8588        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8589        for (int i = 0; i < trimCount; i++) {
8590            final UriPermission perm = persisted.get(i);
8591
8592            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8593                    "Trimming grant created at " + perm.persistedCreateTime);
8594
8595            perm.releasePersistableModes(~0);
8596            removeUriPermissionIfNeededLocked(perm);
8597        }
8598
8599        return true;
8600    }
8601
8602    @Override
8603    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8604            String packageName, boolean incoming) {
8605        enforceNotIsolatedCaller("getPersistedUriPermissions");
8606        Preconditions.checkNotNull(packageName, "packageName");
8607
8608        final int callingUid = Binder.getCallingUid();
8609        final IPackageManager pm = AppGlobals.getPackageManager();
8610        try {
8611            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8612                    UserHandle.getUserId(callingUid));
8613            if (packageUid != callingUid) {
8614                throw new SecurityException(
8615                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8616            }
8617        } catch (RemoteException e) {
8618            throw new SecurityException("Failed to verify package name ownership");
8619        }
8620
8621        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8622        synchronized (this) {
8623            if (incoming) {
8624                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8625                        callingUid);
8626                if (perms == null) {
8627                    Slog.w(TAG, "No permission grants found for " + packageName);
8628                } else {
8629                    for (UriPermission perm : perms.values()) {
8630                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8631                            result.add(perm.buildPersistedPublicApiObject());
8632                        }
8633                    }
8634                }
8635            } else {
8636                final int size = mGrantedUriPermissions.size();
8637                for (int i = 0; i < size; i++) {
8638                    final ArrayMap<GrantUri, UriPermission> perms =
8639                            mGrantedUriPermissions.valueAt(i);
8640                    for (UriPermission perm : perms.values()) {
8641                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8642                            result.add(perm.buildPersistedPublicApiObject());
8643                        }
8644                    }
8645                }
8646            }
8647        }
8648        return new ParceledListSlice<android.content.UriPermission>(result);
8649    }
8650
8651    @Override
8652    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8653            String packageName, int userId) {
8654        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8655                "getGrantedUriPermissions");
8656
8657        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8658        synchronized (this) {
8659            final int size = mGrantedUriPermissions.size();
8660            for (int i = 0; i < size; i++) {
8661                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8662                for (UriPermission perm : perms.values()) {
8663                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8664                            && perm.persistedModeFlags != 0) {
8665                        result.add(perm.buildPersistedPublicApiObject());
8666                    }
8667                }
8668            }
8669        }
8670        return new ParceledListSlice<android.content.UriPermission>(result);
8671    }
8672
8673    @Override
8674    public void clearGrantedUriPermissions(String packageName, int userId) {
8675        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8676                "clearGrantedUriPermissions");
8677        removeUriPermissionsForPackageLocked(packageName, userId, true);
8678    }
8679
8680    @Override
8681    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8682        synchronized (this) {
8683            ProcessRecord app =
8684                who != null ? getRecordForAppLocked(who) : null;
8685            if (app == null) return;
8686
8687            Message msg = Message.obtain();
8688            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8689            msg.obj = app;
8690            msg.arg1 = waiting ? 1 : 0;
8691            mUiHandler.sendMessage(msg);
8692        }
8693    }
8694
8695    @Override
8696    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8697        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8698        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8699        outInfo.availMem = Process.getFreeMemory();
8700        outInfo.totalMem = Process.getTotalMemory();
8701        outInfo.threshold = homeAppMem;
8702        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8703        outInfo.hiddenAppThreshold = cachedAppMem;
8704        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8705                ProcessList.SERVICE_ADJ);
8706        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8707                ProcessList.VISIBLE_APP_ADJ);
8708        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8709                ProcessList.FOREGROUND_APP_ADJ);
8710    }
8711
8712    // =========================================================
8713    // TASK MANAGEMENT
8714    // =========================================================
8715
8716    @Override
8717    public List<IAppTask> getAppTasks(String callingPackage) {
8718        int callingUid = Binder.getCallingUid();
8719        long ident = Binder.clearCallingIdentity();
8720
8721        synchronized(this) {
8722            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8723            try {
8724                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8725
8726                final int N = mRecentTasks.size();
8727                for (int i = 0; i < N; i++) {
8728                    TaskRecord tr = mRecentTasks.get(i);
8729                    // Skip tasks that do not match the caller.  We don't need to verify
8730                    // callingPackage, because we are also limiting to callingUid and know
8731                    // that will limit to the correct security sandbox.
8732                    if (tr.effectiveUid != callingUid) {
8733                        continue;
8734                    }
8735                    Intent intent = tr.getBaseIntent();
8736                    if (intent == null ||
8737                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8738                        continue;
8739                    }
8740                    ActivityManager.RecentTaskInfo taskInfo =
8741                            createRecentTaskInfoFromTaskRecord(tr);
8742                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8743                    list.add(taskImpl);
8744                }
8745            } finally {
8746                Binder.restoreCallingIdentity(ident);
8747            }
8748            return list;
8749        }
8750    }
8751
8752    @Override
8753    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8754        final int callingUid = Binder.getCallingUid();
8755        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8756
8757        synchronized(this) {
8758            if (DEBUG_ALL) Slog.v(
8759                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8760
8761            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8762                    callingUid);
8763
8764            // TODO: Improve with MRU list from all ActivityStacks.
8765            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8766        }
8767
8768        return list;
8769    }
8770
8771    /**
8772     * Creates a new RecentTaskInfo from a TaskRecord.
8773     */
8774    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8775        // Update the task description to reflect any changes in the task stack
8776        tr.updateTaskDescription();
8777
8778        // Compose the recent task info
8779        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8780        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8781        rti.persistentId = tr.taskId;
8782        rti.baseIntent = new Intent(tr.getBaseIntent());
8783        rti.origActivity = tr.origActivity;
8784        rti.realActivity = tr.realActivity;
8785        rti.description = tr.lastDescription;
8786        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8787        rti.userId = tr.userId;
8788        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8789        rti.firstActiveTime = tr.firstActiveTime;
8790        rti.lastActiveTime = tr.lastActiveTime;
8791        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8792        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8793        rti.numActivities = 0;
8794        if (tr.mBounds != null) {
8795            rti.bounds = new Rect(tr.mBounds);
8796        }
8797        rti.isDockable = tr.canGoInDockedStack();
8798
8799        ActivityRecord base = null;
8800        ActivityRecord top = null;
8801        ActivityRecord tmp;
8802
8803        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8804            tmp = tr.mActivities.get(i);
8805            if (tmp.finishing) {
8806                continue;
8807            }
8808            base = tmp;
8809            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8810                top = base;
8811            }
8812            rti.numActivities++;
8813        }
8814
8815        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8816        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8817
8818        return rti;
8819    }
8820
8821    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8822        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8823                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8824        if (!allowed) {
8825            if (checkPermission(android.Manifest.permission.GET_TASKS,
8826                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8827                // Temporary compatibility: some existing apps on the system image may
8828                // still be requesting the old permission and not switched to the new
8829                // one; if so, we'll still allow them full access.  This means we need
8830                // to see if they are holding the old permission and are a system app.
8831                try {
8832                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8833                        allowed = true;
8834                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8835                                + " is using old GET_TASKS but privileged; allowing");
8836                    }
8837                } catch (RemoteException e) {
8838                }
8839            }
8840        }
8841        if (!allowed) {
8842            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8843                    + " does not hold REAL_GET_TASKS; limiting output");
8844        }
8845        return allowed;
8846    }
8847
8848    @Override
8849    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8850        final int callingUid = Binder.getCallingUid();
8851        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8852                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8853
8854        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8855        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8856        synchronized (this) {
8857            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8858                    callingUid);
8859            final boolean detailed = checkCallingPermission(
8860                    android.Manifest.permission.GET_DETAILED_TASKS)
8861                    == PackageManager.PERMISSION_GRANTED;
8862
8863            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8864                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8865                return Collections.emptyList();
8866            }
8867            mRecentTasks.loadUserRecentsLocked(userId);
8868
8869            final int recentsCount = mRecentTasks.size();
8870            ArrayList<ActivityManager.RecentTaskInfo> res =
8871                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8872
8873            final Set<Integer> includedUsers;
8874            if (includeProfiles) {
8875                includedUsers = mUserController.getProfileIds(userId);
8876            } else {
8877                includedUsers = new HashSet<>();
8878            }
8879            includedUsers.add(Integer.valueOf(userId));
8880
8881            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8882                TaskRecord tr = mRecentTasks.get(i);
8883                // Only add calling user or related users recent tasks
8884                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8885                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8886                    continue;
8887                }
8888
8889                if (tr.realActivitySuspended) {
8890                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8891                    continue;
8892                }
8893
8894                // Return the entry if desired by the caller.  We always return
8895                // the first entry, because callers always expect this to be the
8896                // foreground app.  We may filter others if the caller has
8897                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8898                // we should exclude the entry.
8899
8900                if (i == 0
8901                        || withExcluded
8902                        || (tr.intent == null)
8903                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8904                                == 0)) {
8905                    if (!allowed) {
8906                        // If the caller doesn't have the GET_TASKS permission, then only
8907                        // allow them to see a small subset of tasks -- their own and home.
8908                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8909                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8910                            continue;
8911                        }
8912                    }
8913                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8914                        if (tr.stack != null && tr.stack.isHomeStack()) {
8915                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8916                                    "Skipping, home stack task: " + tr);
8917                            continue;
8918                        }
8919                    }
8920                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8921                        final ActivityStack stack = tr.stack;
8922                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8923                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8924                                    "Skipping, top task in docked stack: " + tr);
8925                            continue;
8926                        }
8927                    }
8928                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8929                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8930                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8931                                    "Skipping, pinned stack task: " + tr);
8932                            continue;
8933                        }
8934                    }
8935                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8936                        // Don't include auto remove tasks that are finished or finishing.
8937                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8938                                "Skipping, auto-remove without activity: " + tr);
8939                        continue;
8940                    }
8941                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8942                            && !tr.isAvailable) {
8943                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8944                                "Skipping, unavail real act: " + tr);
8945                        continue;
8946                    }
8947
8948                    if (!tr.mUserSetupComplete) {
8949                        // Don't include task launched while user is not done setting-up.
8950                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8951                                "Skipping, user setup not complete: " + tr);
8952                        continue;
8953                    }
8954
8955                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8956                    if (!detailed) {
8957                        rti.baseIntent.replaceExtras((Bundle)null);
8958                    }
8959
8960                    res.add(rti);
8961                    maxNum--;
8962                }
8963            }
8964            return res;
8965        }
8966    }
8967
8968    @Override
8969    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8970        synchronized (this) {
8971            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8972                    "getTaskThumbnail()");
8973            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8974                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8975            if (tr != null) {
8976                return tr.getTaskThumbnailLocked();
8977            }
8978        }
8979        return null;
8980    }
8981
8982    @Override
8983    public int addAppTask(IBinder activityToken, Intent intent,
8984            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8985        final int callingUid = Binder.getCallingUid();
8986        final long callingIdent = Binder.clearCallingIdentity();
8987
8988        try {
8989            synchronized (this) {
8990                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8991                if (r == null) {
8992                    throw new IllegalArgumentException("Activity does not exist; token="
8993                            + activityToken);
8994                }
8995                ComponentName comp = intent.getComponent();
8996                if (comp == null) {
8997                    throw new IllegalArgumentException("Intent " + intent
8998                            + " must specify explicit component");
8999                }
9000                if (thumbnail.getWidth() != mThumbnailWidth
9001                        || thumbnail.getHeight() != mThumbnailHeight) {
9002                    throw new IllegalArgumentException("Bad thumbnail size: got "
9003                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9004                            + mThumbnailWidth + "x" + mThumbnailHeight);
9005                }
9006                if (intent.getSelector() != null) {
9007                    intent.setSelector(null);
9008                }
9009                if (intent.getSourceBounds() != null) {
9010                    intent.setSourceBounds(null);
9011                }
9012                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9013                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9014                        // The caller has added this as an auto-remove task...  that makes no
9015                        // sense, so turn off auto-remove.
9016                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9017                    }
9018                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9019                    // Must be a new task.
9020                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9021                }
9022                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9023                    mLastAddedTaskActivity = null;
9024                }
9025                ActivityInfo ainfo = mLastAddedTaskActivity;
9026                if (ainfo == null) {
9027                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9028                            comp, 0, UserHandle.getUserId(callingUid));
9029                    if (ainfo.applicationInfo.uid != callingUid) {
9030                        throw new SecurityException(
9031                                "Can't add task for another application: target uid="
9032                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9033                    }
9034                }
9035
9036                // Use the full screen as the context for the task thumbnail
9037                final Point displaySize = new Point();
9038                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9039                r.task.stack.getDisplaySize(displaySize);
9040                thumbnailInfo.taskWidth = displaySize.x;
9041                thumbnailInfo.taskHeight = displaySize.y;
9042                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9043
9044                TaskRecord task = new TaskRecord(this,
9045                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9046                        ainfo, intent, description, thumbnailInfo);
9047
9048                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9049                if (trimIdx >= 0) {
9050                    // If this would have caused a trim, then we'll abort because that
9051                    // means it would be added at the end of the list but then just removed.
9052                    return INVALID_TASK_ID;
9053                }
9054
9055                final int N = mRecentTasks.size();
9056                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9057                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9058                    tr.removedFromRecents();
9059                }
9060
9061                task.inRecents = true;
9062                mRecentTasks.add(task);
9063                r.task.stack.addTask(task, false, "addAppTask");
9064
9065                task.setLastThumbnailLocked(thumbnail);
9066                task.freeLastThumbnail();
9067
9068                return task.taskId;
9069            }
9070        } finally {
9071            Binder.restoreCallingIdentity(callingIdent);
9072        }
9073    }
9074
9075    @Override
9076    public Point getAppTaskThumbnailSize() {
9077        synchronized (this) {
9078            return new Point(mThumbnailWidth,  mThumbnailHeight);
9079        }
9080    }
9081
9082    @Override
9083    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9084        synchronized (this) {
9085            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9086            if (r != null) {
9087                r.setTaskDescription(td);
9088                r.task.updateTaskDescription();
9089            }
9090        }
9091    }
9092
9093    @Override
9094    public void setTaskResizeable(int taskId, int resizeableMode) {
9095        synchronized (this) {
9096            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9097                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9098            if (task == null) {
9099                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9100                return;
9101            }
9102            if (task.mResizeMode != resizeableMode) {
9103                task.mResizeMode = resizeableMode;
9104                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9105                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9106                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9107            }
9108        }
9109    }
9110
9111    @Override
9112    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9113        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9114        long ident = Binder.clearCallingIdentity();
9115        try {
9116            synchronized (this) {
9117                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9118                if (task == null) {
9119                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9120                    return;
9121                }
9122                int stackId = task.stack.mStackId;
9123                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9124                // in crop windows resize mode or if the task size is affected by the docked stack
9125                // changing size. No need to update configuration.
9126                if (bounds != null && task.inCropWindowsResizeMode()
9127                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9128                    mWindowManager.scrollTask(task.taskId, bounds);
9129                    return;
9130                }
9131
9132                // Place the task in the right stack if it isn't there already based on
9133                // the requested bounds.
9134                // The stack transition logic is:
9135                // - a null bounds on a freeform task moves that task to fullscreen
9136                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9137                //   that task to freeform
9138                // - otherwise the task is not moved
9139                if (!StackId.isTaskResizeAllowed(stackId)) {
9140                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9141                }
9142                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9143                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9144                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9145                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9146                }
9147                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9148                if (stackId != task.stack.mStackId) {
9149                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9150                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9151                    preserveWindow = false;
9152                }
9153
9154                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9155                        false /* deferResume */);
9156            }
9157        } finally {
9158            Binder.restoreCallingIdentity(ident);
9159        }
9160    }
9161
9162    @Override
9163    public Rect getTaskBounds(int taskId) {
9164        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9165        long ident = Binder.clearCallingIdentity();
9166        Rect rect = new Rect();
9167        try {
9168            synchronized (this) {
9169                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9170                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9171                if (task == null) {
9172                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9173                    return rect;
9174                }
9175                if (task.stack != null) {
9176                    // Return the bounds from window manager since it will be adjusted for various
9177                    // things like the presense of a docked stack for tasks that aren't resizeable.
9178                    mWindowManager.getTaskBounds(task.taskId, rect);
9179                } else {
9180                    // Task isn't in window manager yet since it isn't associated with a stack.
9181                    // Return the persist value from activity manager
9182                    if (task.mBounds != null) {
9183                        rect.set(task.mBounds);
9184                    } else if (task.mLastNonFullscreenBounds != null) {
9185                        rect.set(task.mLastNonFullscreenBounds);
9186                    }
9187                }
9188            }
9189        } finally {
9190            Binder.restoreCallingIdentity(ident);
9191        }
9192        return rect;
9193    }
9194
9195    @Override
9196    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9197        if (userId != UserHandle.getCallingUserId()) {
9198            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9199                    "getTaskDescriptionIcon");
9200        }
9201        final File passedIconFile = new File(filePath);
9202        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9203                passedIconFile.getName());
9204        if (!legitIconFile.getPath().equals(filePath)
9205                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9206            throw new IllegalArgumentException("Bad file path: " + filePath
9207                    + " passed for userId " + userId);
9208        }
9209        return mRecentTasks.getTaskDescriptionIcon(filePath);
9210    }
9211
9212    @Override
9213    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9214            throws RemoteException {
9215        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9216                opts.getCustomInPlaceResId() == 0) {
9217            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9218                    "with valid animation");
9219        }
9220        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9221        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9222                opts.getCustomInPlaceResId());
9223        mWindowManager.executeAppTransition();
9224    }
9225
9226    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9227            boolean removeFromRecents) {
9228        if (removeFromRecents) {
9229            mRecentTasks.remove(tr);
9230            tr.removedFromRecents();
9231        }
9232        ComponentName component = tr.getBaseIntent().getComponent();
9233        if (component == null) {
9234            Slog.w(TAG, "No component for base intent of task: " + tr);
9235            return;
9236        }
9237
9238        // Find any running services associated with this app and stop if needed.
9239        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9240
9241        if (!killProcess) {
9242            return;
9243        }
9244
9245        // Determine if the process(es) for this task should be killed.
9246        final String pkg = component.getPackageName();
9247        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9248        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9249        for (int i = 0; i < pmap.size(); i++) {
9250
9251            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9252            for (int j = 0; j < uids.size(); j++) {
9253                ProcessRecord proc = uids.valueAt(j);
9254                if (proc.userId != tr.userId) {
9255                    // Don't kill process for a different user.
9256                    continue;
9257                }
9258                if (proc == mHomeProcess) {
9259                    // Don't kill the home process along with tasks from the same package.
9260                    continue;
9261                }
9262                if (!proc.pkgList.containsKey(pkg)) {
9263                    // Don't kill process that is not associated with this task.
9264                    continue;
9265                }
9266
9267                for (int k = 0; k < proc.activities.size(); k++) {
9268                    TaskRecord otherTask = proc.activities.get(k).task;
9269                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9270                        // Don't kill process(es) that has an activity in a different task that is
9271                        // also in recents.
9272                        return;
9273                    }
9274                }
9275
9276                if (proc.foregroundServices) {
9277                    // Don't kill process(es) with foreground service.
9278                    return;
9279                }
9280
9281                // Add process to kill list.
9282                procsToKill.add(proc);
9283            }
9284        }
9285
9286        // Kill the running processes.
9287        for (int i = 0; i < procsToKill.size(); i++) {
9288            ProcessRecord pr = procsToKill.get(i);
9289            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9290                    && pr.curReceiver == null) {
9291                pr.kill("remove task", true);
9292            } else {
9293                // We delay killing processes that are not in the background or running a receiver.
9294                pr.waitingToKill = "remove task";
9295            }
9296        }
9297    }
9298
9299    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9300        // Remove all tasks with activities in the specified package from the list of recent tasks
9301        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9302            TaskRecord tr = mRecentTasks.get(i);
9303            if (tr.userId != userId) continue;
9304
9305            ComponentName cn = tr.intent.getComponent();
9306            if (cn != null && cn.getPackageName().equals(packageName)) {
9307                // If the package name matches, remove the task.
9308                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9309            }
9310        }
9311    }
9312
9313    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9314            int userId) {
9315
9316        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9317            TaskRecord tr = mRecentTasks.get(i);
9318            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9319                continue;
9320            }
9321
9322            ComponentName cn = tr.intent.getComponent();
9323            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9324                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9325            if (sameComponent) {
9326                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9327            }
9328        }
9329    }
9330
9331    /**
9332     * Removes the task with the specified task id.
9333     *
9334     * @param taskId Identifier of the task to be removed.
9335     * @param killProcess Kill any process associated with the task if possible.
9336     * @param removeFromRecents Whether to also remove the task from recents.
9337     * @return Returns true if the given task was found and removed.
9338     */
9339    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9340            boolean removeFromRecents) {
9341        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9342                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9343        if (tr != null) {
9344            tr.removeTaskActivitiesLocked();
9345            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9346            if (tr.isPersistable) {
9347                notifyTaskPersisterLocked(null, true);
9348            }
9349            return true;
9350        }
9351        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9352        return false;
9353    }
9354
9355    @Override
9356    public void removeStack(int stackId) {
9357        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9358        if (stackId == HOME_STACK_ID) {
9359            throw new IllegalArgumentException("Removing home stack is not allowed.");
9360        }
9361
9362        synchronized (this) {
9363            final long ident = Binder.clearCallingIdentity();
9364            try {
9365                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9366                if (stack == null) {
9367                    return;
9368                }
9369                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9370                for (int i = tasks.size() - 1; i >= 0; i--) {
9371                    removeTaskByIdLocked(
9372                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9373                }
9374            } finally {
9375                Binder.restoreCallingIdentity(ident);
9376            }
9377        }
9378    }
9379
9380    @Override
9381    public boolean removeTask(int taskId) {
9382        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9383        synchronized (this) {
9384            final long ident = Binder.clearCallingIdentity();
9385            try {
9386                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9387            } finally {
9388                Binder.restoreCallingIdentity(ident);
9389            }
9390        }
9391    }
9392
9393    /**
9394     * TODO: Add mController hook
9395     */
9396    @Override
9397    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9398        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9399
9400        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9401        synchronized(this) {
9402            moveTaskToFrontLocked(taskId, flags, bOptions);
9403        }
9404    }
9405
9406    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9407        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9408
9409        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9410                Binder.getCallingUid(), -1, -1, "Task to front")) {
9411            ActivityOptions.abort(options);
9412            return;
9413        }
9414        final long origId = Binder.clearCallingIdentity();
9415        try {
9416            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9417            if (task == null) {
9418                Slog.d(TAG, "Could not find task for id: "+ taskId);
9419                return;
9420            }
9421            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9422                mStackSupervisor.showLockTaskToast();
9423                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9424                return;
9425            }
9426            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9427            if (prev != null && prev.isRecentsActivity()) {
9428                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9429            }
9430            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9431        } finally {
9432            Binder.restoreCallingIdentity(origId);
9433        }
9434        ActivityOptions.abort(options);
9435    }
9436
9437    /**
9438     * Moves an activity, and all of the other activities within the same task, to the bottom
9439     * of the history stack.  The activity's order within the task is unchanged.
9440     *
9441     * @param token A reference to the activity we wish to move
9442     * @param nonRoot If false then this only works if the activity is the root
9443     *                of a task; if true it will work for any activity in a task.
9444     * @return Returns true if the move completed, false if not.
9445     */
9446    @Override
9447    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9448        enforceNotIsolatedCaller("moveActivityTaskToBack");
9449        synchronized(this) {
9450            final long origId = Binder.clearCallingIdentity();
9451            try {
9452                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9453                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9454                if (task != null) {
9455                    if (mStackSupervisor.isLockedTask(task)) {
9456                        mStackSupervisor.showLockTaskToast();
9457                        return false;
9458                    }
9459                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9460                }
9461            } finally {
9462                Binder.restoreCallingIdentity(origId);
9463            }
9464        }
9465        return false;
9466    }
9467
9468    @Override
9469    public void moveTaskBackwards(int task) {
9470        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9471                "moveTaskBackwards()");
9472
9473        synchronized(this) {
9474            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9475                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9476                return;
9477            }
9478            final long origId = Binder.clearCallingIdentity();
9479            moveTaskBackwardsLocked(task);
9480            Binder.restoreCallingIdentity(origId);
9481        }
9482    }
9483
9484    private final void moveTaskBackwardsLocked(int task) {
9485        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9486    }
9487
9488    @Override
9489    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9490            IActivityContainerCallback callback) throws RemoteException {
9491        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9492        synchronized (this) {
9493            if (parentActivityToken == null) {
9494                throw new IllegalArgumentException("parent token must not be null");
9495            }
9496            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9497            if (r == null) {
9498                return null;
9499            }
9500            if (callback == null) {
9501                throw new IllegalArgumentException("callback must not be null");
9502            }
9503            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9504        }
9505    }
9506
9507    @Override
9508    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9509        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9510        synchronized (this) {
9511            mStackSupervisor.deleteActivityContainer(container);
9512        }
9513    }
9514
9515    @Override
9516    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9517        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9518        synchronized (this) {
9519            final int stackId = mStackSupervisor.getNextStackId();
9520            final ActivityStack stack =
9521                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9522            if (stack == null) {
9523                return null;
9524            }
9525            return stack.mActivityContainer;
9526        }
9527    }
9528
9529    @Override
9530    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9531        synchronized (this) {
9532            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9533            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9534                return stack.mActivityContainer.getDisplayId();
9535            }
9536            return Display.DEFAULT_DISPLAY;
9537        }
9538    }
9539
9540    @Override
9541    public int getActivityStackId(IBinder token) throws RemoteException {
9542        synchronized (this) {
9543            ActivityStack stack = ActivityRecord.getStackLocked(token);
9544            if (stack == null) {
9545                return INVALID_STACK_ID;
9546            }
9547            return stack.mStackId;
9548        }
9549    }
9550
9551    @Override
9552    public void exitFreeformMode(IBinder token) throws RemoteException {
9553        synchronized (this) {
9554            long ident = Binder.clearCallingIdentity();
9555            try {
9556                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9557                if (r == null) {
9558                    throw new IllegalArgumentException(
9559                            "exitFreeformMode: No activity record matching token=" + token);
9560                }
9561                final ActivityStack stack = r.getStackLocked(token);
9562                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9563                    throw new IllegalStateException(
9564                            "exitFreeformMode: You can only go fullscreen from freeform.");
9565                }
9566                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9567                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9568                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9569            } finally {
9570                Binder.restoreCallingIdentity(ident);
9571            }
9572        }
9573    }
9574
9575    @Override
9576    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9577        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9578        if (stackId == HOME_STACK_ID) {
9579            throw new IllegalArgumentException(
9580                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9581        }
9582        synchronized (this) {
9583            long ident = Binder.clearCallingIdentity();
9584            try {
9585                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9586                        + " to stackId=" + stackId + " toTop=" + toTop);
9587                if (stackId == DOCKED_STACK_ID) {
9588                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9589                            null /* initialBounds */);
9590                }
9591                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9592                        "moveTaskToStack", ANIMATE);
9593            } finally {
9594                Binder.restoreCallingIdentity(ident);
9595            }
9596        }
9597    }
9598
9599    @Override
9600    public void swapDockedAndFullscreenStack() throws RemoteException {
9601        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9602        synchronized (this) {
9603            long ident = Binder.clearCallingIdentity();
9604            try {
9605                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9606                        FULLSCREEN_WORKSPACE_STACK_ID);
9607                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9608                        : null;
9609                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9610                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9611                        : null;
9612                if (topTask == null || tasks == null || tasks.size() == 0) {
9613                    Slog.w(TAG,
9614                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9615                    return;
9616                }
9617
9618                // TODO: App transition
9619                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9620
9621                // Defer the resume so resume/pausing while moving stacks is dangerous.
9622                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9623                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9624                        ANIMATE, true /* deferResume */);
9625                final int size = tasks.size();
9626                for (int i = 0; i < size; i++) {
9627                    final int id = tasks.get(i).taskId;
9628                    if (id == topTask.taskId) {
9629                        continue;
9630                    }
9631                    mStackSupervisor.moveTaskToStackLocked(id,
9632                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9633                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9634                }
9635
9636                // Because we deferred the resume, to avoid conflicts with stack switches while
9637                // resuming, we need to do it after all the tasks are moved.
9638                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9639                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9640
9641                mWindowManager.executeAppTransition();
9642            } finally {
9643                Binder.restoreCallingIdentity(ident);
9644            }
9645        }
9646    }
9647
9648    /**
9649     * Moves the input task to the docked stack.
9650     *
9651     * @param taskId Id of task to move.
9652     * @param createMode The mode the docked stack should be created in if it doesn't exist
9653     *                   already. See
9654     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9655     *                   and
9656     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9657     * @param toTop If the task and stack should be moved to the top.
9658     * @param animate Whether we should play an animation for the moving the task
9659     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9660     *                      docked stack. Pass {@code null} to use default bounds.
9661     */
9662    @Override
9663    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9664            Rect initialBounds) {
9665        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9666        synchronized (this) {
9667            long ident = Binder.clearCallingIdentity();
9668            try {
9669                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9670                        + " to createMode=" + createMode + " toTop=" + toTop);
9671                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9672                return mStackSupervisor.moveTaskToStackLocked(
9673                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9674                        "moveTaskToDockedStack", animate);
9675            } finally {
9676                Binder.restoreCallingIdentity(ident);
9677            }
9678        }
9679    }
9680
9681    /**
9682     * Moves the top activity in the input stackId to the pinned stack.
9683     *
9684     * @param stackId Id of stack to move the top activity to pinned stack.
9685     * @param bounds Bounds to use for pinned stack.
9686     *
9687     * @return True if the top activity of the input stack was successfully moved to the pinned
9688     *          stack.
9689     */
9690    @Override
9691    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9692        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9693        synchronized (this) {
9694            if (!mSupportsPictureInPicture) {
9695                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9696                        + "Device doesn't support picture-in-pciture mode");
9697            }
9698
9699            long ident = Binder.clearCallingIdentity();
9700            try {
9701                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9702            } finally {
9703                Binder.restoreCallingIdentity(ident);
9704            }
9705        }
9706    }
9707
9708    @Override
9709    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9710            boolean preserveWindows, boolean animate, int animationDuration) {
9711        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9712        long ident = Binder.clearCallingIdentity();
9713        try {
9714            synchronized (this) {
9715                if (animate) {
9716                    if (stackId == PINNED_STACK_ID) {
9717                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9718                    } else {
9719                        throw new IllegalArgumentException("Stack: " + stackId
9720                                + " doesn't support animated resize.");
9721                    }
9722                } else {
9723                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9724                            null /* tempTaskInsetBounds */, preserveWindows,
9725                            allowResizeInDockedMode);
9726                }
9727            }
9728        } finally {
9729            Binder.restoreCallingIdentity(ident);
9730        }
9731    }
9732
9733    @Override
9734    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9735            Rect tempDockedTaskInsetBounds,
9736            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9737        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9738                "resizeDockedStack()");
9739        long ident = Binder.clearCallingIdentity();
9740        try {
9741            synchronized (this) {
9742                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9743                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9744                        PRESERVE_WINDOWS);
9745            }
9746        } finally {
9747            Binder.restoreCallingIdentity(ident);
9748        }
9749    }
9750
9751    @Override
9752    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9753        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9754                "resizePinnedStack()");
9755        final long ident = Binder.clearCallingIdentity();
9756        try {
9757            synchronized (this) {
9758                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9759            }
9760        } finally {
9761            Binder.restoreCallingIdentity(ident);
9762        }
9763    }
9764
9765    @Override
9766    public void positionTaskInStack(int taskId, int stackId, int position) {
9767        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9768        if (stackId == HOME_STACK_ID) {
9769            throw new IllegalArgumentException(
9770                    "positionTaskInStack: Attempt to change the position of task "
9771                    + taskId + " in/to home stack");
9772        }
9773        synchronized (this) {
9774            long ident = Binder.clearCallingIdentity();
9775            try {
9776                if (DEBUG_STACK) Slog.d(TAG_STACK,
9777                        "positionTaskInStack: positioning task=" + taskId
9778                        + " in stackId=" + stackId + " at position=" + position);
9779                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9780            } finally {
9781                Binder.restoreCallingIdentity(ident);
9782            }
9783        }
9784    }
9785
9786    @Override
9787    public List<StackInfo> getAllStackInfos() {
9788        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9789        long ident = Binder.clearCallingIdentity();
9790        try {
9791            synchronized (this) {
9792                return mStackSupervisor.getAllStackInfosLocked();
9793            }
9794        } finally {
9795            Binder.restoreCallingIdentity(ident);
9796        }
9797    }
9798
9799    @Override
9800    public StackInfo getStackInfo(int stackId) {
9801        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9802        long ident = Binder.clearCallingIdentity();
9803        try {
9804            synchronized (this) {
9805                return mStackSupervisor.getStackInfoLocked(stackId);
9806            }
9807        } finally {
9808            Binder.restoreCallingIdentity(ident);
9809        }
9810    }
9811
9812    @Override
9813    public boolean isInHomeStack(int taskId) {
9814        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9815        long ident = Binder.clearCallingIdentity();
9816        try {
9817            synchronized (this) {
9818                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9819                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9820                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9821            }
9822        } finally {
9823            Binder.restoreCallingIdentity(ident);
9824        }
9825    }
9826
9827    @Override
9828    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9829        synchronized(this) {
9830            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9831        }
9832    }
9833
9834    @Override
9835    public void updateDeviceOwner(String packageName) {
9836        final int callingUid = Binder.getCallingUid();
9837        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9838            throw new SecurityException("updateDeviceOwner called from non-system process");
9839        }
9840        synchronized (this) {
9841            mDeviceOwnerName = packageName;
9842        }
9843    }
9844
9845    @Override
9846    public void updateLockTaskPackages(int userId, String[] packages) {
9847        final int callingUid = Binder.getCallingUid();
9848        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9849            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9850                    "updateLockTaskPackages()");
9851        }
9852        synchronized (this) {
9853            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9854                    Arrays.toString(packages));
9855            mLockTaskPackages.put(userId, packages);
9856            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9857        }
9858    }
9859
9860
9861    void startLockTaskModeLocked(TaskRecord task) {
9862        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9863        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9864            return;
9865        }
9866
9867        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9868        // is initiated by system after the pinning request was shown and locked mode is initiated
9869        // by an authorized app directly
9870        final int callingUid = Binder.getCallingUid();
9871        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9872        long ident = Binder.clearCallingIdentity();
9873        try {
9874            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9875            if (!isSystemInitiated) {
9876                task.mLockTaskUid = callingUid;
9877                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9878                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9879                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9880                    StatusBarManagerInternal statusBarManager =
9881                            LocalServices.getService(StatusBarManagerInternal.class);
9882                    if (statusBarManager != null) {
9883                        statusBarManager.showScreenPinningRequest();
9884                    }
9885                    return;
9886                }
9887
9888                if (stack == null || task != stack.topTask()) {
9889                    throw new IllegalArgumentException("Invalid task, not in foreground");
9890                }
9891            }
9892            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9893                    "Locking fully");
9894            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9895                    ActivityManager.LOCK_TASK_MODE_PINNED :
9896                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9897                    "startLockTask", true);
9898        } finally {
9899            Binder.restoreCallingIdentity(ident);
9900        }
9901    }
9902
9903    @Override
9904    public void startLockTaskMode(int taskId) {
9905        synchronized (this) {
9906            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9907            if (task != null) {
9908                startLockTaskModeLocked(task);
9909            }
9910        }
9911    }
9912
9913    @Override
9914    public void startLockTaskMode(IBinder token) {
9915        synchronized (this) {
9916            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9917            if (r == null) {
9918                return;
9919            }
9920            final TaskRecord task = r.task;
9921            if (task != null) {
9922                startLockTaskModeLocked(task);
9923            }
9924        }
9925    }
9926
9927    @Override
9928    public void startLockTaskModeOnCurrent() throws RemoteException {
9929        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9930        long ident = Binder.clearCallingIdentity();
9931        try {
9932            synchronized (this) {
9933                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9934                if (r != null) {
9935                    startLockTaskModeLocked(r.task);
9936                }
9937            }
9938        } finally {
9939            Binder.restoreCallingIdentity(ident);
9940        }
9941    }
9942
9943    @Override
9944    public void stopLockTaskMode() {
9945        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9946        if (lockTask == null) {
9947            // Our work here is done.
9948            return;
9949        }
9950
9951        final int callingUid = Binder.getCallingUid();
9952        final int lockTaskUid = lockTask.mLockTaskUid;
9953        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9954        // It is possible lockTaskMode was started by the system process because
9955        // android:lockTaskMode is set to a locking value in the application manifest instead of
9956        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9957        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9958        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9959                callingUid != lockTaskUid
9960                && (lockTaskUid != 0
9961                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9962            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9963                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9964        }
9965
9966        long ident = Binder.clearCallingIdentity();
9967        try {
9968            Log.d(TAG, "stopLockTaskMode");
9969            // Stop lock task
9970            synchronized (this) {
9971                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9972                        "stopLockTask", true);
9973            }
9974        } finally {
9975            Binder.restoreCallingIdentity(ident);
9976        }
9977    }
9978
9979    @Override
9980    public void stopLockTaskModeOnCurrent() throws RemoteException {
9981        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9982        long ident = Binder.clearCallingIdentity();
9983        try {
9984            stopLockTaskMode();
9985        } finally {
9986            Binder.restoreCallingIdentity(ident);
9987        }
9988    }
9989
9990    @Override
9991    public boolean isInLockTaskMode() {
9992        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9993    }
9994
9995    @Override
9996    public int getLockTaskModeState() {
9997        synchronized (this) {
9998            return mStackSupervisor.getLockTaskModeState();
9999        }
10000    }
10001
10002    @Override
10003    public void showLockTaskEscapeMessage(IBinder token) {
10004        synchronized (this) {
10005            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10006            if (r == null) {
10007                return;
10008            }
10009            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10010        }
10011    }
10012
10013    // =========================================================
10014    // CONTENT PROVIDERS
10015    // =========================================================
10016
10017    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10018        List<ProviderInfo> providers = null;
10019        try {
10020            providers = AppGlobals.getPackageManager()
10021                    .queryContentProviders(app.processName, app.uid,
10022                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10023                                    | MATCH_DEBUG_TRIAGED_MISSING)
10024                    .getList();
10025        } catch (RemoteException ex) {
10026        }
10027        if (DEBUG_MU) Slog.v(TAG_MU,
10028                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10029        int userId = app.userId;
10030        if (providers != null) {
10031            int N = providers.size();
10032            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10033            for (int i=0; i<N; i++) {
10034                ProviderInfo cpi =
10035                    (ProviderInfo)providers.get(i);
10036                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10037                        cpi.name, cpi.flags);
10038                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10039                    // This is a singleton provider, but a user besides the
10040                    // default user is asking to initialize a process it runs
10041                    // in...  well, no, it doesn't actually run in this process,
10042                    // it runs in the process of the default user.  Get rid of it.
10043                    providers.remove(i);
10044                    N--;
10045                    i--;
10046                    continue;
10047                }
10048
10049                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10050                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10051                if (cpr == null) {
10052                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10053                    mProviderMap.putProviderByClass(comp, cpr);
10054                }
10055                if (DEBUG_MU) Slog.v(TAG_MU,
10056                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10057                app.pubProviders.put(cpi.name, cpr);
10058                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10059                    // Don't add this if it is a platform component that is marked
10060                    // to run in multiple processes, because this is actually
10061                    // part of the framework so doesn't make sense to track as a
10062                    // separate apk in the process.
10063                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10064                            mProcessStats);
10065                }
10066                notifyPackageUse(cpi.applicationInfo.packageName);
10067            }
10068        }
10069        return providers;
10070    }
10071
10072    /**
10073     * Check if {@link ProcessRecord} has a possible chance at accessing the
10074     * given {@link ProviderInfo}. Final permission checking is always done
10075     * in {@link ContentProvider}.
10076     */
10077    private final String checkContentProviderPermissionLocked(
10078            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10079        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10080        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10081        boolean checkedGrants = false;
10082        if (checkUser) {
10083            // Looking for cross-user grants before enforcing the typical cross-users permissions
10084            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10085            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10086                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10087                    return null;
10088                }
10089                checkedGrants = true;
10090            }
10091            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10092                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10093            if (userId != tmpTargetUserId) {
10094                // When we actually went to determine the final targer user ID, this ended
10095                // up different than our initial check for the authority.  This is because
10096                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10097                // SELF.  So we need to re-check the grants again.
10098                checkedGrants = false;
10099            }
10100        }
10101        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10102                cpi.applicationInfo.uid, cpi.exported)
10103                == PackageManager.PERMISSION_GRANTED) {
10104            return null;
10105        }
10106        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10107                cpi.applicationInfo.uid, cpi.exported)
10108                == PackageManager.PERMISSION_GRANTED) {
10109            return null;
10110        }
10111
10112        PathPermission[] pps = cpi.pathPermissions;
10113        if (pps != null) {
10114            int i = pps.length;
10115            while (i > 0) {
10116                i--;
10117                PathPermission pp = pps[i];
10118                String pprperm = pp.getReadPermission();
10119                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10120                        cpi.applicationInfo.uid, cpi.exported)
10121                        == PackageManager.PERMISSION_GRANTED) {
10122                    return null;
10123                }
10124                String ppwperm = pp.getWritePermission();
10125                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10126                        cpi.applicationInfo.uid, cpi.exported)
10127                        == PackageManager.PERMISSION_GRANTED) {
10128                    return null;
10129                }
10130            }
10131        }
10132        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10133            return null;
10134        }
10135
10136        String msg;
10137        if (!cpi.exported) {
10138            msg = "Permission Denial: opening provider " + cpi.name
10139                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10140                    + ", uid=" + callingUid + ") that is not exported from uid "
10141                    + cpi.applicationInfo.uid;
10142        } else {
10143            msg = "Permission Denial: opening provider " + cpi.name
10144                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10145                    + ", uid=" + callingUid + ") requires "
10146                    + cpi.readPermission + " or " + cpi.writePermission;
10147        }
10148        Slog.w(TAG, msg);
10149        return msg;
10150    }
10151
10152    /**
10153     * Returns if the ContentProvider has granted a uri to callingUid
10154     */
10155    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10156        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10157        if (perms != null) {
10158            for (int i=perms.size()-1; i>=0; i--) {
10159                GrantUri grantUri = perms.keyAt(i);
10160                if (grantUri.sourceUserId == userId || !checkUser) {
10161                    if (matchesProvider(grantUri.uri, cpi)) {
10162                        return true;
10163                    }
10164                }
10165            }
10166        }
10167        return false;
10168    }
10169
10170    /**
10171     * Returns true if the uri authority is one of the authorities specified in the provider.
10172     */
10173    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10174        String uriAuth = uri.getAuthority();
10175        String cpiAuth = cpi.authority;
10176        if (cpiAuth.indexOf(';') == -1) {
10177            return cpiAuth.equals(uriAuth);
10178        }
10179        String[] cpiAuths = cpiAuth.split(";");
10180        int length = cpiAuths.length;
10181        for (int i = 0; i < length; i++) {
10182            if (cpiAuths[i].equals(uriAuth)) return true;
10183        }
10184        return false;
10185    }
10186
10187    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10188            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10189        if (r != null) {
10190            for (int i=0; i<r.conProviders.size(); i++) {
10191                ContentProviderConnection conn = r.conProviders.get(i);
10192                if (conn.provider == cpr) {
10193                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10194                            "Adding provider requested by "
10195                            + r.processName + " from process "
10196                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10197                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10198                    if (stable) {
10199                        conn.stableCount++;
10200                        conn.numStableIncs++;
10201                    } else {
10202                        conn.unstableCount++;
10203                        conn.numUnstableIncs++;
10204                    }
10205                    return conn;
10206                }
10207            }
10208            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10209            if (stable) {
10210                conn.stableCount = 1;
10211                conn.numStableIncs = 1;
10212            } else {
10213                conn.unstableCount = 1;
10214                conn.numUnstableIncs = 1;
10215            }
10216            cpr.connections.add(conn);
10217            r.conProviders.add(conn);
10218            startAssociationLocked(r.uid, r.processName, r.curProcState,
10219                    cpr.uid, cpr.name, cpr.info.processName);
10220            return conn;
10221        }
10222        cpr.addExternalProcessHandleLocked(externalProcessToken);
10223        return null;
10224    }
10225
10226    boolean decProviderCountLocked(ContentProviderConnection conn,
10227            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10228        if (conn != null) {
10229            cpr = conn.provider;
10230            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10231                    "Removing provider requested by "
10232                    + conn.client.processName + " from process "
10233                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10234                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10235            if (stable) {
10236                conn.stableCount--;
10237            } else {
10238                conn.unstableCount--;
10239            }
10240            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10241                cpr.connections.remove(conn);
10242                conn.client.conProviders.remove(conn);
10243                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10244                    // The client is more important than last activity -- note the time this
10245                    // is happening, so we keep the old provider process around a bit as last
10246                    // activity to avoid thrashing it.
10247                    if (cpr.proc != null) {
10248                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10249                    }
10250                }
10251                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10252                return true;
10253            }
10254            return false;
10255        }
10256        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10257        return false;
10258    }
10259
10260    private void checkTime(long startTime, String where) {
10261        long now = SystemClock.elapsedRealtime();
10262        if ((now-startTime) > 1000) {
10263            // If we are taking more than a second, log about it.
10264            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10265        }
10266    }
10267
10268    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10269            String name, IBinder token, boolean stable, int userId) {
10270        ContentProviderRecord cpr;
10271        ContentProviderConnection conn = null;
10272        ProviderInfo cpi = null;
10273
10274        synchronized(this) {
10275            long startTime = SystemClock.elapsedRealtime();
10276
10277            ProcessRecord r = null;
10278            if (caller != null) {
10279                r = getRecordForAppLocked(caller);
10280                if (r == null) {
10281                    throw new SecurityException(
10282                            "Unable to find app for caller " + caller
10283                          + " (pid=" + Binder.getCallingPid()
10284                          + ") when getting content provider " + name);
10285                }
10286            }
10287
10288            boolean checkCrossUser = true;
10289
10290            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10291
10292            // First check if this content provider has been published...
10293            cpr = mProviderMap.getProviderByName(name, userId);
10294            // If that didn't work, check if it exists for user 0 and then
10295            // verify that it's a singleton provider before using it.
10296            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10297                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10298                if (cpr != null) {
10299                    cpi = cpr.info;
10300                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10301                            cpi.name, cpi.flags)
10302                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10303                        userId = UserHandle.USER_SYSTEM;
10304                        checkCrossUser = false;
10305                    } else {
10306                        cpr = null;
10307                        cpi = null;
10308                    }
10309                }
10310            }
10311
10312            boolean providerRunning = cpr != null;
10313            if (providerRunning) {
10314                cpi = cpr.info;
10315                String msg;
10316                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10317                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10318                        != null) {
10319                    throw new SecurityException(msg);
10320                }
10321                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10322
10323                if (r != null && cpr.canRunHere(r)) {
10324                    // This provider has been published or is in the process
10325                    // of being published...  but it is also allowed to run
10326                    // in the caller's process, so don't make a connection
10327                    // and just let the caller instantiate its own instance.
10328                    ContentProviderHolder holder = cpr.newHolder(null);
10329                    // don't give caller the provider object, it needs
10330                    // to make its own.
10331                    holder.provider = null;
10332                    return holder;
10333                }
10334
10335                final long origId = Binder.clearCallingIdentity();
10336
10337                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10338
10339                // In this case the provider instance already exists, so we can
10340                // return it right away.
10341                conn = incProviderCountLocked(r, cpr, token, stable);
10342                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10343                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10344                        // If this is a perceptible app accessing the provider,
10345                        // make sure to count it as being accessed and thus
10346                        // back up on the LRU list.  This is good because
10347                        // content providers are often expensive to start.
10348                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10349                        updateLruProcessLocked(cpr.proc, false, null);
10350                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10351                    }
10352                }
10353
10354                if (cpr.proc != null) {
10355                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10356                    boolean success = updateOomAdjLocked(cpr.proc);
10357                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10358                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10359                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10360                    // NOTE: there is still a race here where a signal could be
10361                    // pending on the process even though we managed to update its
10362                    // adj level.  Not sure what to do about this, but at least
10363                    // the race is now smaller.
10364                    if (!success) {
10365                        // Uh oh...  it looks like the provider's process
10366                        // has been killed on us.  We need to wait for a new
10367                        // process to be started, and make sure its death
10368                        // doesn't kill our process.
10369                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10370                                + " is crashing; detaching " + r);
10371                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10372                        checkTime(startTime, "getContentProviderImpl: before appDied");
10373                        appDiedLocked(cpr.proc);
10374                        checkTime(startTime, "getContentProviderImpl: after appDied");
10375                        if (!lastRef) {
10376                            // This wasn't the last ref our process had on
10377                            // the provider...  we have now been killed, bail.
10378                            return null;
10379                        }
10380                        providerRunning = false;
10381                        conn = null;
10382                    }
10383                }
10384
10385                Binder.restoreCallingIdentity(origId);
10386            }
10387
10388            if (!providerRunning) {
10389                try {
10390                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10391                    cpi = AppGlobals.getPackageManager().
10392                        resolveContentProvider(name,
10393                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10394                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10395                } catch (RemoteException ex) {
10396                }
10397                if (cpi == null) {
10398                    return null;
10399                }
10400                // If the provider is a singleton AND
10401                // (it's a call within the same user || the provider is a
10402                // privileged app)
10403                // Then allow connecting to the singleton provider
10404                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10405                        cpi.name, cpi.flags)
10406                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10407                if (singleton) {
10408                    userId = UserHandle.USER_SYSTEM;
10409                }
10410                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10411                checkTime(startTime, "getContentProviderImpl: got app info for user");
10412
10413                String msg;
10414                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10415                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10416                        != null) {
10417                    throw new SecurityException(msg);
10418                }
10419                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10420
10421                if (!mProcessesReady
10422                        && !cpi.processName.equals("system")) {
10423                    // If this content provider does not run in the system
10424                    // process, and the system is not yet ready to run other
10425                    // processes, then fail fast instead of hanging.
10426                    throw new IllegalArgumentException(
10427                            "Attempt to launch content provider before system ready");
10428                }
10429
10430                // Make sure that the user who owns this provider is running.  If not,
10431                // we don't want to allow it to run.
10432                if (!mUserController.isUserRunningLocked(userId, 0)) {
10433                    Slog.w(TAG, "Unable to launch app "
10434                            + cpi.applicationInfo.packageName + "/"
10435                            + cpi.applicationInfo.uid + " for provider "
10436                            + name + ": user " + userId + " is stopped");
10437                    return null;
10438                }
10439
10440                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10441                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10442                cpr = mProviderMap.getProviderByClass(comp, userId);
10443                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10444                final boolean firstClass = cpr == null;
10445                if (firstClass) {
10446                    final long ident = Binder.clearCallingIdentity();
10447
10448                    // If permissions need a review before any of the app components can run,
10449                    // we return no provider and launch a review activity if the calling app
10450                    // is in the foreground.
10451                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10452                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10453                            return null;
10454                        }
10455                    }
10456
10457                    try {
10458                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10459                        ApplicationInfo ai =
10460                            AppGlobals.getPackageManager().
10461                                getApplicationInfo(
10462                                        cpi.applicationInfo.packageName,
10463                                        STOCK_PM_FLAGS, userId);
10464                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10465                        if (ai == null) {
10466                            Slog.w(TAG, "No package info for content provider "
10467                                    + cpi.name);
10468                            return null;
10469                        }
10470                        ai = getAppInfoForUser(ai, userId);
10471                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10472                    } catch (RemoteException ex) {
10473                        // pm is in same process, this will never happen.
10474                    } finally {
10475                        Binder.restoreCallingIdentity(ident);
10476                    }
10477                }
10478
10479                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10480
10481                if (r != null && cpr.canRunHere(r)) {
10482                    // If this is a multiprocess provider, then just return its
10483                    // info and allow the caller to instantiate it.  Only do
10484                    // this if the provider is the same user as the caller's
10485                    // process, or can run as root (so can be in any process).
10486                    return cpr.newHolder(null);
10487                }
10488
10489                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10490                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10491                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10492
10493                // This is single process, and our app is now connecting to it.
10494                // See if we are already in the process of launching this
10495                // provider.
10496                final int N = mLaunchingProviders.size();
10497                int i;
10498                for (i = 0; i < N; i++) {
10499                    if (mLaunchingProviders.get(i) == cpr) {
10500                        break;
10501                    }
10502                }
10503
10504                // If the provider is not already being launched, then get it
10505                // started.
10506                if (i >= N) {
10507                    final long origId = Binder.clearCallingIdentity();
10508
10509                    try {
10510                        // Content provider is now in use, its package can't be stopped.
10511                        try {
10512                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10513                            AppGlobals.getPackageManager().setPackageStoppedState(
10514                                    cpr.appInfo.packageName, false, userId);
10515                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10516                        } catch (RemoteException e) {
10517                        } catch (IllegalArgumentException e) {
10518                            Slog.w(TAG, "Failed trying to unstop package "
10519                                    + cpr.appInfo.packageName + ": " + e);
10520                        }
10521
10522                        // Use existing process if already started
10523                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10524                        ProcessRecord proc = getProcessRecordLocked(
10525                                cpi.processName, cpr.appInfo.uid, false);
10526                        if (proc != null && proc.thread != null) {
10527                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10528                                    "Installing in existing process " + proc);
10529                            if (!proc.pubProviders.containsKey(cpi.name)) {
10530                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10531                                proc.pubProviders.put(cpi.name, cpr);
10532                                try {
10533                                    proc.thread.scheduleInstallProvider(cpi);
10534                                } catch (RemoteException e) {
10535                                }
10536                            }
10537                        } else {
10538                            checkTime(startTime, "getContentProviderImpl: before start process");
10539                            proc = startProcessLocked(cpi.processName,
10540                                    cpr.appInfo, false, 0, "content provider",
10541                                    new ComponentName(cpi.applicationInfo.packageName,
10542                                            cpi.name), false, false, false);
10543                            checkTime(startTime, "getContentProviderImpl: after start process");
10544                            if (proc == null) {
10545                                Slog.w(TAG, "Unable to launch app "
10546                                        + cpi.applicationInfo.packageName + "/"
10547                                        + cpi.applicationInfo.uid + " for provider "
10548                                        + name + ": process is bad");
10549                                return null;
10550                            }
10551                        }
10552                        cpr.launchingApp = proc;
10553                        mLaunchingProviders.add(cpr);
10554                    } finally {
10555                        Binder.restoreCallingIdentity(origId);
10556                    }
10557                }
10558
10559                checkTime(startTime, "getContentProviderImpl: updating data structures");
10560
10561                // Make sure the provider is published (the same provider class
10562                // may be published under multiple names).
10563                if (firstClass) {
10564                    mProviderMap.putProviderByClass(comp, cpr);
10565                }
10566
10567                mProviderMap.putProviderByName(name, cpr);
10568                conn = incProviderCountLocked(r, cpr, token, stable);
10569                if (conn != null) {
10570                    conn.waiting = true;
10571                }
10572            }
10573            checkTime(startTime, "getContentProviderImpl: done!");
10574        }
10575
10576        // Wait for the provider to be published...
10577        synchronized (cpr) {
10578            while (cpr.provider == null) {
10579                if (cpr.launchingApp == null) {
10580                    Slog.w(TAG, "Unable to launch app "
10581                            + cpi.applicationInfo.packageName + "/"
10582                            + cpi.applicationInfo.uid + " for provider "
10583                            + name + ": launching app became null");
10584                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10585                            UserHandle.getUserId(cpi.applicationInfo.uid),
10586                            cpi.applicationInfo.packageName,
10587                            cpi.applicationInfo.uid, name);
10588                    return null;
10589                }
10590                try {
10591                    if (DEBUG_MU) Slog.v(TAG_MU,
10592                            "Waiting to start provider " + cpr
10593                            + " launchingApp=" + cpr.launchingApp);
10594                    if (conn != null) {
10595                        conn.waiting = true;
10596                    }
10597                    cpr.wait();
10598                } catch (InterruptedException ex) {
10599                } finally {
10600                    if (conn != null) {
10601                        conn.waiting = false;
10602                    }
10603                }
10604            }
10605        }
10606        return cpr != null ? cpr.newHolder(conn) : null;
10607    }
10608
10609    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10610            ProcessRecord r, final int userId) {
10611        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10612                cpi.packageName, userId)) {
10613
10614            final boolean callerForeground = r == null || r.setSchedGroup
10615                    != ProcessList.SCHED_GROUP_BACKGROUND;
10616
10617            // Show a permission review UI only for starting from a foreground app
10618            if (!callerForeground) {
10619                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10620                        + cpi.packageName + " requires a permissions review");
10621                return false;
10622            }
10623
10624            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10625            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10626                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10627            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10628
10629            if (DEBUG_PERMISSIONS_REVIEW) {
10630                Slog.i(TAG, "u" + userId + " Launching permission review "
10631                        + "for package " + cpi.packageName);
10632            }
10633
10634            final UserHandle userHandle = new UserHandle(userId);
10635            mHandler.post(new Runnable() {
10636                @Override
10637                public void run() {
10638                    mContext.startActivityAsUser(intent, userHandle);
10639                }
10640            });
10641
10642            return false;
10643        }
10644
10645        return true;
10646    }
10647
10648    PackageManagerInternal getPackageManagerInternalLocked() {
10649        if (mPackageManagerInt == null) {
10650            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10651        }
10652        return mPackageManagerInt;
10653    }
10654
10655    @Override
10656    public final ContentProviderHolder getContentProvider(
10657            IApplicationThread caller, String name, int userId, boolean stable) {
10658        enforceNotIsolatedCaller("getContentProvider");
10659        if (caller == null) {
10660            String msg = "null IApplicationThread when getting content provider "
10661                    + name;
10662            Slog.w(TAG, msg);
10663            throw new SecurityException(msg);
10664        }
10665        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10666        // with cross-user grant.
10667        return getContentProviderImpl(caller, name, null, stable, userId);
10668    }
10669
10670    public ContentProviderHolder getContentProviderExternal(
10671            String name, int userId, IBinder token) {
10672        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10673            "Do not have permission in call getContentProviderExternal()");
10674        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10675                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10676        return getContentProviderExternalUnchecked(name, token, userId);
10677    }
10678
10679    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10680            IBinder token, int userId) {
10681        return getContentProviderImpl(null, name, token, true, userId);
10682    }
10683
10684    /**
10685     * Drop a content provider from a ProcessRecord's bookkeeping
10686     */
10687    public void removeContentProvider(IBinder connection, boolean stable) {
10688        enforceNotIsolatedCaller("removeContentProvider");
10689        long ident = Binder.clearCallingIdentity();
10690        try {
10691            synchronized (this) {
10692                ContentProviderConnection conn;
10693                try {
10694                    conn = (ContentProviderConnection)connection;
10695                } catch (ClassCastException e) {
10696                    String msg ="removeContentProvider: " + connection
10697                            + " not a ContentProviderConnection";
10698                    Slog.w(TAG, msg);
10699                    throw new IllegalArgumentException(msg);
10700                }
10701                if (conn == null) {
10702                    throw new NullPointerException("connection is null");
10703                }
10704                if (decProviderCountLocked(conn, null, null, stable)) {
10705                    updateOomAdjLocked();
10706                }
10707            }
10708        } finally {
10709            Binder.restoreCallingIdentity(ident);
10710        }
10711    }
10712
10713    public void removeContentProviderExternal(String name, IBinder token) {
10714        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10715            "Do not have permission in call removeContentProviderExternal()");
10716        int userId = UserHandle.getCallingUserId();
10717        long ident = Binder.clearCallingIdentity();
10718        try {
10719            removeContentProviderExternalUnchecked(name, token, userId);
10720        } finally {
10721            Binder.restoreCallingIdentity(ident);
10722        }
10723    }
10724
10725    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10726        synchronized (this) {
10727            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10728            if(cpr == null) {
10729                //remove from mProvidersByClass
10730                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10731                return;
10732            }
10733
10734            //update content provider record entry info
10735            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10736            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10737            if (localCpr.hasExternalProcessHandles()) {
10738                if (localCpr.removeExternalProcessHandleLocked(token)) {
10739                    updateOomAdjLocked();
10740                } else {
10741                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10742                            + " with no external reference for token: "
10743                            + token + ".");
10744                }
10745            } else {
10746                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10747                        + " with no external references.");
10748            }
10749        }
10750    }
10751
10752    public final void publishContentProviders(IApplicationThread caller,
10753            List<ContentProviderHolder> providers) {
10754        if (providers == null) {
10755            return;
10756        }
10757
10758        enforceNotIsolatedCaller("publishContentProviders");
10759        synchronized (this) {
10760            final ProcessRecord r = getRecordForAppLocked(caller);
10761            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10762            if (r == null) {
10763                throw new SecurityException(
10764                        "Unable to find app for caller " + caller
10765                      + " (pid=" + Binder.getCallingPid()
10766                      + ") when publishing content providers");
10767            }
10768
10769            final long origId = Binder.clearCallingIdentity();
10770
10771            final int N = providers.size();
10772            for (int i = 0; i < N; i++) {
10773                ContentProviderHolder src = providers.get(i);
10774                if (src == null || src.info == null || src.provider == null) {
10775                    continue;
10776                }
10777                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10778                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10779                if (dst != null) {
10780                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10781                    mProviderMap.putProviderByClass(comp, dst);
10782                    String names[] = dst.info.authority.split(";");
10783                    for (int j = 0; j < names.length; j++) {
10784                        mProviderMap.putProviderByName(names[j], dst);
10785                    }
10786
10787                    int launchingCount = mLaunchingProviders.size();
10788                    int j;
10789                    boolean wasInLaunchingProviders = false;
10790                    for (j = 0; j < launchingCount; j++) {
10791                        if (mLaunchingProviders.get(j) == dst) {
10792                            mLaunchingProviders.remove(j);
10793                            wasInLaunchingProviders = true;
10794                            j--;
10795                            launchingCount--;
10796                        }
10797                    }
10798                    if (wasInLaunchingProviders) {
10799                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10800                    }
10801                    synchronized (dst) {
10802                        dst.provider = src.provider;
10803                        dst.proc = r;
10804                        dst.notifyAll();
10805                    }
10806                    updateOomAdjLocked(r);
10807                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10808                            src.info.authority);
10809                }
10810            }
10811
10812            Binder.restoreCallingIdentity(origId);
10813        }
10814    }
10815
10816    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10817        ContentProviderConnection conn;
10818        try {
10819            conn = (ContentProviderConnection)connection;
10820        } catch (ClassCastException e) {
10821            String msg ="refContentProvider: " + connection
10822                    + " not a ContentProviderConnection";
10823            Slog.w(TAG, msg);
10824            throw new IllegalArgumentException(msg);
10825        }
10826        if (conn == null) {
10827            throw new NullPointerException("connection is null");
10828        }
10829
10830        synchronized (this) {
10831            if (stable > 0) {
10832                conn.numStableIncs += stable;
10833            }
10834            stable = conn.stableCount + stable;
10835            if (stable < 0) {
10836                throw new IllegalStateException("stableCount < 0: " + stable);
10837            }
10838
10839            if (unstable > 0) {
10840                conn.numUnstableIncs += unstable;
10841            }
10842            unstable = conn.unstableCount + unstable;
10843            if (unstable < 0) {
10844                throw new IllegalStateException("unstableCount < 0: " + unstable);
10845            }
10846
10847            if ((stable+unstable) <= 0) {
10848                throw new IllegalStateException("ref counts can't go to zero here: stable="
10849                        + stable + " unstable=" + unstable);
10850            }
10851            conn.stableCount = stable;
10852            conn.unstableCount = unstable;
10853            return !conn.dead;
10854        }
10855    }
10856
10857    public void unstableProviderDied(IBinder connection) {
10858        ContentProviderConnection conn;
10859        try {
10860            conn = (ContentProviderConnection)connection;
10861        } catch (ClassCastException e) {
10862            String msg ="refContentProvider: " + connection
10863                    + " not a ContentProviderConnection";
10864            Slog.w(TAG, msg);
10865            throw new IllegalArgumentException(msg);
10866        }
10867        if (conn == null) {
10868            throw new NullPointerException("connection is null");
10869        }
10870
10871        // Safely retrieve the content provider associated with the connection.
10872        IContentProvider provider;
10873        synchronized (this) {
10874            provider = conn.provider.provider;
10875        }
10876
10877        if (provider == null) {
10878            // Um, yeah, we're way ahead of you.
10879            return;
10880        }
10881
10882        // Make sure the caller is being honest with us.
10883        if (provider.asBinder().pingBinder()) {
10884            // Er, no, still looks good to us.
10885            synchronized (this) {
10886                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10887                        + " says " + conn + " died, but we don't agree");
10888                return;
10889            }
10890        }
10891
10892        // Well look at that!  It's dead!
10893        synchronized (this) {
10894            if (conn.provider.provider != provider) {
10895                // But something changed...  good enough.
10896                return;
10897            }
10898
10899            ProcessRecord proc = conn.provider.proc;
10900            if (proc == null || proc.thread == null) {
10901                // Seems like the process is already cleaned up.
10902                return;
10903            }
10904
10905            // As far as we're concerned, this is just like receiving a
10906            // death notification...  just a bit prematurely.
10907            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10908                    + ") early provider death");
10909            final long ident = Binder.clearCallingIdentity();
10910            try {
10911                appDiedLocked(proc);
10912            } finally {
10913                Binder.restoreCallingIdentity(ident);
10914            }
10915        }
10916    }
10917
10918    @Override
10919    public void appNotRespondingViaProvider(IBinder connection) {
10920        enforceCallingPermission(
10921                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10922
10923        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10924        if (conn == null) {
10925            Slog.w(TAG, "ContentProviderConnection is null");
10926            return;
10927        }
10928
10929        final ProcessRecord host = conn.provider.proc;
10930        if (host == null) {
10931            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10932            return;
10933        }
10934
10935        mHandler.post(new Runnable() {
10936            @Override
10937            public void run() {
10938                mAppErrors.appNotResponding(host, null, null, false,
10939                        "ContentProvider not responding");
10940            }
10941        });
10942    }
10943
10944    public final void installSystemProviders() {
10945        List<ProviderInfo> providers;
10946        synchronized (this) {
10947            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10948            providers = generateApplicationProvidersLocked(app);
10949            if (providers != null) {
10950                for (int i=providers.size()-1; i>=0; i--) {
10951                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10952                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10953                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10954                                + ": not system .apk");
10955                        providers.remove(i);
10956                    }
10957                }
10958            }
10959        }
10960        if (providers != null) {
10961            mSystemThread.installSystemProviders(providers);
10962        }
10963
10964        mCoreSettingsObserver = new CoreSettingsObserver(this);
10965        mFontScaleSettingObserver = new FontScaleSettingObserver();
10966
10967        //mUsageStatsService.monitorPackages();
10968    }
10969
10970    private void startPersistentApps(int matchFlags) {
10971        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
10972
10973        synchronized (this) {
10974            try {
10975                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
10976                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
10977                for (ApplicationInfo app : apps) {
10978                    if (!"android".equals(app.packageName)) {
10979                        addAppLocked(app, false, null /* ABI override */);
10980                    }
10981                }
10982            } catch (RemoteException ex) {
10983            }
10984        }
10985    }
10986
10987    /**
10988     * When a user is unlocked, we need to install encryption-unaware providers
10989     * belonging to any running apps.
10990     */
10991    private void installEncryptionUnawareProviders(int userId) {
10992        if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
10993            // TODO: eventually pivot this back to look at current user state,
10994            // similar to the comment in UserManager.isUserUnlocked(), but for
10995            // now, if we started apps when "unlocked" then unaware providers
10996            // have already been spun up.
10997            return;
10998        }
10999
11000        // We're only interested in providers that are encryption unaware, and
11001        // we don't care about uninstalled apps, since there's no way they're
11002        // running at this point.
11003        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11004
11005        synchronized (this) {
11006            final int NP = mProcessNames.getMap().size();
11007            for (int ip = 0; ip < NP; ip++) {
11008                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11009                final int NA = apps.size();
11010                for (int ia = 0; ia < NA; ia++) {
11011                    final ProcessRecord app = apps.valueAt(ia);
11012                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11013
11014                    final int NG = app.pkgList.size();
11015                    for (int ig = 0; ig < NG; ig++) {
11016                        try {
11017                            final String pkgName = app.pkgList.keyAt(ig);
11018                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11019                                    .getPackageInfo(pkgName, matchFlags, userId);
11020                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11021                                for (ProviderInfo provInfo : pkgInfo.providers) {
11022                                    Log.v(TAG, "Installing " + provInfo);
11023                                    app.thread.scheduleInstallProvider(provInfo);
11024                                }
11025                            }
11026                        } catch (RemoteException ignored) {
11027                        }
11028                    }
11029                }
11030            }
11031        }
11032    }
11033
11034    /**
11035     * Allows apps to retrieve the MIME type of a URI.
11036     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11037     * users, then it does not need permission to access the ContentProvider.
11038     * Either, it needs cross-user uri grants.
11039     *
11040     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11041     *
11042     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11043     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11044     */
11045    public String getProviderMimeType(Uri uri, int userId) {
11046        enforceNotIsolatedCaller("getProviderMimeType");
11047        final String name = uri.getAuthority();
11048        int callingUid = Binder.getCallingUid();
11049        int callingPid = Binder.getCallingPid();
11050        long ident = 0;
11051        boolean clearedIdentity = false;
11052        synchronized (this) {
11053            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11054        }
11055        if (canClearIdentity(callingPid, callingUid, userId)) {
11056            clearedIdentity = true;
11057            ident = Binder.clearCallingIdentity();
11058        }
11059        ContentProviderHolder holder = null;
11060        try {
11061            holder = getContentProviderExternalUnchecked(name, null, userId);
11062            if (holder != null) {
11063                return holder.provider.getType(uri);
11064            }
11065        } catch (RemoteException e) {
11066            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11067            return null;
11068        } finally {
11069            // We need to clear the identity to call removeContentProviderExternalUnchecked
11070            if (!clearedIdentity) {
11071                ident = Binder.clearCallingIdentity();
11072            }
11073            try {
11074                if (holder != null) {
11075                    removeContentProviderExternalUnchecked(name, null, userId);
11076                }
11077            } finally {
11078                Binder.restoreCallingIdentity(ident);
11079            }
11080        }
11081
11082        return null;
11083    }
11084
11085    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11086        if (UserHandle.getUserId(callingUid) == userId) {
11087            return true;
11088        }
11089        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11090                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11091                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11092                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11093                return true;
11094        }
11095        return false;
11096    }
11097
11098    // =========================================================
11099    // GLOBAL MANAGEMENT
11100    // =========================================================
11101
11102    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11103            boolean isolated, int isolatedUid) {
11104        String proc = customProcess != null ? customProcess : info.processName;
11105        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11106        final int userId = UserHandle.getUserId(info.uid);
11107        int uid = info.uid;
11108        if (isolated) {
11109            if (isolatedUid == 0) {
11110                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11111                while (true) {
11112                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11113                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11114                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11115                    }
11116                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11117                    mNextIsolatedProcessUid++;
11118                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11119                        // No process for this uid, use it.
11120                        break;
11121                    }
11122                    stepsLeft--;
11123                    if (stepsLeft <= 0) {
11124                        return null;
11125                    }
11126                }
11127            } else {
11128                // Special case for startIsolatedProcess (internal only), where
11129                // the uid of the isolated process is specified by the caller.
11130                uid = isolatedUid;
11131            }
11132        }
11133        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11134        if (!mBooted && !mBooting
11135                && userId == UserHandle.USER_SYSTEM
11136                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11137            r.persistent = true;
11138        }
11139        addProcessNameLocked(r);
11140        return r;
11141    }
11142
11143    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11144            String abiOverride) {
11145        ProcessRecord app;
11146        if (!isolated) {
11147            app = getProcessRecordLocked(info.processName, info.uid, true);
11148        } else {
11149            app = null;
11150        }
11151
11152        if (app == null) {
11153            app = newProcessRecordLocked(info, null, isolated, 0);
11154            updateLruProcessLocked(app, false, null);
11155            updateOomAdjLocked();
11156        }
11157
11158        // This package really, really can not be stopped.
11159        try {
11160            AppGlobals.getPackageManager().setPackageStoppedState(
11161                    info.packageName, false, UserHandle.getUserId(app.uid));
11162        } catch (RemoteException e) {
11163        } catch (IllegalArgumentException e) {
11164            Slog.w(TAG, "Failed trying to unstop package "
11165                    + info.packageName + ": " + e);
11166        }
11167
11168        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11169            app.persistent = true;
11170            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11171        }
11172        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11173            mPersistentStartingProcesses.add(app);
11174            startProcessLocked(app, "added application", app.processName, abiOverride,
11175                    null /* entryPoint */, null /* entryPointArgs */);
11176        }
11177
11178        return app;
11179    }
11180
11181    public void unhandledBack() {
11182        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11183                "unhandledBack()");
11184
11185        synchronized(this) {
11186            final long origId = Binder.clearCallingIdentity();
11187            try {
11188                getFocusedStack().unhandledBackLocked();
11189            } finally {
11190                Binder.restoreCallingIdentity(origId);
11191            }
11192        }
11193    }
11194
11195    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11196        enforceNotIsolatedCaller("openContentUri");
11197        final int userId = UserHandle.getCallingUserId();
11198        String name = uri.getAuthority();
11199        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11200        ParcelFileDescriptor pfd = null;
11201        if (cph != null) {
11202            // We record the binder invoker's uid in thread-local storage before
11203            // going to the content provider to open the file.  Later, in the code
11204            // that handles all permissions checks, we look for this uid and use
11205            // that rather than the Activity Manager's own uid.  The effect is that
11206            // we do the check against the caller's permissions even though it looks
11207            // to the content provider like the Activity Manager itself is making
11208            // the request.
11209            Binder token = new Binder();
11210            sCallerIdentity.set(new Identity(
11211                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11212            try {
11213                pfd = cph.provider.openFile(null, uri, "r", null, token);
11214            } catch (FileNotFoundException e) {
11215                // do nothing; pfd will be returned null
11216            } finally {
11217                // Ensure that whatever happens, we clean up the identity state
11218                sCallerIdentity.remove();
11219                // Ensure we're done with the provider.
11220                removeContentProviderExternalUnchecked(name, null, userId);
11221            }
11222        } else {
11223            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11224        }
11225        return pfd;
11226    }
11227
11228    // Actually is sleeping or shutting down or whatever else in the future
11229    // is an inactive state.
11230    public boolean isSleepingOrShuttingDown() {
11231        return isSleeping() || mShuttingDown;
11232    }
11233
11234    public boolean isSleeping() {
11235        return mSleeping;
11236    }
11237
11238    void onWakefulnessChanged(int wakefulness) {
11239        synchronized(this) {
11240            mWakefulness = wakefulness;
11241            updateSleepIfNeededLocked();
11242        }
11243    }
11244
11245    void finishRunningVoiceLocked() {
11246        if (mRunningVoice != null) {
11247            mRunningVoice = null;
11248            mVoiceWakeLock.release();
11249            updateSleepIfNeededLocked();
11250        }
11251    }
11252
11253    void startTimeTrackingFocusedActivityLocked() {
11254        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11255            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11256        }
11257    }
11258
11259    void updateSleepIfNeededLocked() {
11260        if (mSleeping && !shouldSleepLocked()) {
11261            mSleeping = false;
11262            startTimeTrackingFocusedActivityLocked();
11263            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11264            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11265            updateOomAdjLocked();
11266        } else if (!mSleeping && shouldSleepLocked()) {
11267            mSleeping = true;
11268            if (mCurAppTimeTracker != null) {
11269                mCurAppTimeTracker.stop();
11270            }
11271            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11272            mStackSupervisor.goingToSleepLocked();
11273            updateOomAdjLocked();
11274
11275            // Initialize the wake times of all processes.
11276            checkExcessivePowerUsageLocked(false);
11277            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11278            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11279            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11280        }
11281    }
11282
11283    private boolean shouldSleepLocked() {
11284        // Resume applications while running a voice interactor.
11285        if (mRunningVoice != null) {
11286            return false;
11287        }
11288
11289        // TODO: Transform the lock screen state into a sleep token instead.
11290        switch (mWakefulness) {
11291            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11292            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11293            case PowerManagerInternal.WAKEFULNESS_DOZING:
11294                // Pause applications whenever the lock screen is shown or any sleep
11295                // tokens have been acquired.
11296                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11297            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11298            default:
11299                // If we're asleep then pause applications unconditionally.
11300                return true;
11301        }
11302    }
11303
11304    /** Pokes the task persister. */
11305    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11306        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11307    }
11308
11309    /** Notifies all listeners when the task stack has changed. */
11310    void notifyTaskStackChangedLocked() {
11311        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11312        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11313        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11314        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11315    }
11316
11317    /** Notifies all listeners when an Activity is pinned. */
11318    void notifyActivityPinnedLocked() {
11319        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11320        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11321    }
11322
11323    /**
11324     * Notifies all listeners when an attempt was made to start an an activity that is already
11325     * running in the pinned stack and the activity was not actually started, but the task is
11326     * either brought to the front or a new Intent is delivered to it.
11327     */
11328    void notifyPinnedActivityRestartAttemptLocked() {
11329        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11330        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11331    }
11332
11333    /** Notifies all listeners when the pinned stack animation ends. */
11334    @Override
11335    public void notifyPinnedStackAnimationEnded() {
11336        synchronized (this) {
11337            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11338            mHandler.obtainMessage(
11339                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11340        }
11341    }
11342
11343    @Override
11344    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11345        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11346    }
11347
11348    @Override
11349    public boolean shutdown(int timeout) {
11350        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11351                != PackageManager.PERMISSION_GRANTED) {
11352            throw new SecurityException("Requires permission "
11353                    + android.Manifest.permission.SHUTDOWN);
11354        }
11355
11356        boolean timedout = false;
11357
11358        synchronized(this) {
11359            mShuttingDown = true;
11360            updateEventDispatchingLocked();
11361            timedout = mStackSupervisor.shutdownLocked(timeout);
11362        }
11363
11364        mAppOpsService.shutdown();
11365        if (mUsageStatsService != null) {
11366            mUsageStatsService.prepareShutdown();
11367        }
11368        mBatteryStatsService.shutdown();
11369        synchronized (this) {
11370            mProcessStats.shutdownLocked();
11371            notifyTaskPersisterLocked(null, true);
11372        }
11373
11374        return timedout;
11375    }
11376
11377    public final void activitySlept(IBinder token) {
11378        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11379
11380        final long origId = Binder.clearCallingIdentity();
11381
11382        synchronized (this) {
11383            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11384            if (r != null) {
11385                mStackSupervisor.activitySleptLocked(r);
11386            }
11387        }
11388
11389        Binder.restoreCallingIdentity(origId);
11390    }
11391
11392    private String lockScreenShownToString() {
11393        switch (mLockScreenShown) {
11394            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11395            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11396            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11397            default: return "Unknown=" + mLockScreenShown;
11398        }
11399    }
11400
11401    void logLockScreen(String msg) {
11402        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11403                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11404                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11405                + " mSleeping=" + mSleeping);
11406    }
11407
11408    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11409        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11410        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11411        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11412            boolean wasRunningVoice = mRunningVoice != null;
11413            mRunningVoice = session;
11414            if (!wasRunningVoice) {
11415                mVoiceWakeLock.acquire();
11416                updateSleepIfNeededLocked();
11417            }
11418        }
11419    }
11420
11421    private void updateEventDispatchingLocked() {
11422        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11423    }
11424
11425    public void setLockScreenShown(boolean shown) {
11426        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11427                != PackageManager.PERMISSION_GRANTED) {
11428            throw new SecurityException("Requires permission "
11429                    + android.Manifest.permission.DEVICE_POWER);
11430        }
11431
11432        synchronized(this) {
11433            long ident = Binder.clearCallingIdentity();
11434            try {
11435                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11436                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11437                updateSleepIfNeededLocked();
11438            } finally {
11439                Binder.restoreCallingIdentity(ident);
11440            }
11441        }
11442    }
11443
11444    @Override
11445    public void notifyLockedProfile(@UserIdInt int userId) {
11446        try {
11447            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11448                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11449            }
11450        } catch (RemoteException ex) {
11451            throw new SecurityException("Fail to check is caller a privileged app", ex);
11452        }
11453
11454        synchronized (this) {
11455            if (mStackSupervisor.isFocusedUserLockedProfile()) {
11456                final long ident = Binder.clearCallingIdentity();
11457                try {
11458                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11459                    // Get the focused task before launching launcher.
11460
11461                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11462
11463                        // If there is no device lock, we will show the profile's credential page.
11464                        // startActivityFromRecentsInner is intercepted and will forward user to it.
11465                        if (mFocusedActivity != null) {
11466                            mStackSupervisor.startActivityFromRecentsInner(
11467                                    mFocusedActivity.task.taskId, null);
11468                        }
11469                    } else {
11470                        // Showing launcher to avoid user entering credential twice.
11471                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11472                    }
11473                } finally {
11474                    Binder.restoreCallingIdentity(ident);
11475                }
11476            }
11477        }
11478    }
11479
11480    @Override
11481    public void stopAppSwitches() {
11482        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11483                != PackageManager.PERMISSION_GRANTED) {
11484            throw new SecurityException("viewquires permission "
11485                    + android.Manifest.permission.STOP_APP_SWITCHES);
11486        }
11487
11488        synchronized(this) {
11489            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11490                    + APP_SWITCH_DELAY_TIME;
11491            mDidAppSwitch = false;
11492            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11493            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11494            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11495        }
11496    }
11497
11498    public void resumeAppSwitches() {
11499        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11500                != PackageManager.PERMISSION_GRANTED) {
11501            throw new SecurityException("Requires permission "
11502                    + android.Manifest.permission.STOP_APP_SWITCHES);
11503        }
11504
11505        synchronized(this) {
11506            // Note that we don't execute any pending app switches... we will
11507            // let those wait until either the timeout, or the next start
11508            // activity request.
11509            mAppSwitchesAllowedTime = 0;
11510        }
11511    }
11512
11513    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11514            int callingPid, int callingUid, String name) {
11515        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11516            return true;
11517        }
11518
11519        int perm = checkComponentPermission(
11520                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11521                sourceUid, -1, true);
11522        if (perm == PackageManager.PERMISSION_GRANTED) {
11523            return true;
11524        }
11525
11526        // If the actual IPC caller is different from the logical source, then
11527        // also see if they are allowed to control app switches.
11528        if (callingUid != -1 && callingUid != sourceUid) {
11529            perm = checkComponentPermission(
11530                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11531                    callingUid, -1, true);
11532            if (perm == PackageManager.PERMISSION_GRANTED) {
11533                return true;
11534            }
11535        }
11536
11537        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11538        return false;
11539    }
11540
11541    public void setDebugApp(String packageName, boolean waitForDebugger,
11542            boolean persistent) {
11543        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11544                "setDebugApp()");
11545
11546        long ident = Binder.clearCallingIdentity();
11547        try {
11548            // Note that this is not really thread safe if there are multiple
11549            // callers into it at the same time, but that's not a situation we
11550            // care about.
11551            if (persistent) {
11552                final ContentResolver resolver = mContext.getContentResolver();
11553                Settings.Global.putString(
11554                    resolver, Settings.Global.DEBUG_APP,
11555                    packageName);
11556                Settings.Global.putInt(
11557                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11558                    waitForDebugger ? 1 : 0);
11559            }
11560
11561            synchronized (this) {
11562                if (!persistent) {
11563                    mOrigDebugApp = mDebugApp;
11564                    mOrigWaitForDebugger = mWaitForDebugger;
11565                }
11566                mDebugApp = packageName;
11567                mWaitForDebugger = waitForDebugger;
11568                mDebugTransient = !persistent;
11569                if (packageName != null) {
11570                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11571                            false, UserHandle.USER_ALL, "set debug app");
11572                }
11573            }
11574        } finally {
11575            Binder.restoreCallingIdentity(ident);
11576        }
11577    }
11578
11579    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11580        synchronized (this) {
11581            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11582            if (!isDebuggable) {
11583                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11584                    throw new SecurityException("Process not debuggable: " + app.packageName);
11585                }
11586            }
11587
11588            mTrackAllocationApp = processName;
11589        }
11590    }
11591
11592    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11593        synchronized (this) {
11594            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11595            if (!isDebuggable) {
11596                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11597                    throw new SecurityException("Process not debuggable: " + app.packageName);
11598                }
11599            }
11600            mProfileApp = processName;
11601            mProfileFile = profilerInfo.profileFile;
11602            if (mProfileFd != null) {
11603                try {
11604                    mProfileFd.close();
11605                } catch (IOException e) {
11606                }
11607                mProfileFd = null;
11608            }
11609            mProfileFd = profilerInfo.profileFd;
11610            mSamplingInterval = profilerInfo.samplingInterval;
11611            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11612            mProfileType = 0;
11613        }
11614    }
11615
11616    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11617        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11618        if (!isDebuggable) {
11619            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11620                throw new SecurityException("Process not debuggable: " + app.packageName);
11621            }
11622        }
11623        mNativeDebuggingApp = processName;
11624    }
11625
11626    @Override
11627    public void setAlwaysFinish(boolean enabled) {
11628        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11629                "setAlwaysFinish()");
11630
11631        long ident = Binder.clearCallingIdentity();
11632        try {
11633            Settings.Global.putInt(
11634                    mContext.getContentResolver(),
11635                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11636
11637            synchronized (this) {
11638                mAlwaysFinishActivities = enabled;
11639            }
11640        } finally {
11641            Binder.restoreCallingIdentity(ident);
11642        }
11643    }
11644
11645    @Override
11646    public void setLenientBackgroundCheck(boolean enabled) {
11647        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11648                "setLenientBackgroundCheck()");
11649
11650        long ident = Binder.clearCallingIdentity();
11651        try {
11652            Settings.Global.putInt(
11653                    mContext.getContentResolver(),
11654                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11655
11656            synchronized (this) {
11657                mLenientBackgroundCheck = enabled;
11658            }
11659        } finally {
11660            Binder.restoreCallingIdentity(ident);
11661        }
11662    }
11663
11664    @Override
11665    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11666        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11667                "setActivityController()");
11668        synchronized (this) {
11669            mController = controller;
11670            mControllerIsAMonkey = imAMonkey;
11671            Watchdog.getInstance().setActivityController(controller);
11672        }
11673    }
11674
11675    @Override
11676    public void setUserIsMonkey(boolean userIsMonkey) {
11677        synchronized (this) {
11678            synchronized (mPidsSelfLocked) {
11679                final int callingPid = Binder.getCallingPid();
11680                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11681                if (precessRecord == null) {
11682                    throw new SecurityException("Unknown process: " + callingPid);
11683                }
11684                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11685                    throw new SecurityException("Only an instrumentation process "
11686                            + "with a UiAutomation can call setUserIsMonkey");
11687                }
11688            }
11689            mUserIsMonkey = userIsMonkey;
11690        }
11691    }
11692
11693    @Override
11694    public boolean isUserAMonkey() {
11695        synchronized (this) {
11696            // If there is a controller also implies the user is a monkey.
11697            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11698        }
11699    }
11700
11701    public void requestBugReport(int bugreportType) {
11702        String service = null;
11703        switch (bugreportType) {
11704            case ActivityManager.BUGREPORT_OPTION_FULL:
11705                service = "bugreport";
11706                break;
11707            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11708                service = "bugreportplus";
11709                break;
11710            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11711                service = "bugreportremote";
11712                break;
11713        }
11714        if (service == null) {
11715            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11716                    + bugreportType);
11717        }
11718        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11719        SystemProperties.set("ctl.start", service);
11720    }
11721
11722    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11723        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11724    }
11725
11726    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11727        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11728            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11729        }
11730        return KEY_DISPATCHING_TIMEOUT;
11731    }
11732
11733    @Override
11734    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11735        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11736                != PackageManager.PERMISSION_GRANTED) {
11737            throw new SecurityException("Requires permission "
11738                    + android.Manifest.permission.FILTER_EVENTS);
11739        }
11740        ProcessRecord proc;
11741        long timeout;
11742        synchronized (this) {
11743            synchronized (mPidsSelfLocked) {
11744                proc = mPidsSelfLocked.get(pid);
11745            }
11746            timeout = getInputDispatchingTimeoutLocked(proc);
11747        }
11748
11749        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11750            return -1;
11751        }
11752
11753        return timeout;
11754    }
11755
11756    /**
11757     * Handle input dispatching timeouts.
11758     * Returns whether input dispatching should be aborted or not.
11759     */
11760    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11761            final ActivityRecord activity, final ActivityRecord parent,
11762            final boolean aboveSystem, String reason) {
11763        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11764                != PackageManager.PERMISSION_GRANTED) {
11765            throw new SecurityException("Requires permission "
11766                    + android.Manifest.permission.FILTER_EVENTS);
11767        }
11768
11769        final String annotation;
11770        if (reason == null) {
11771            annotation = "Input dispatching timed out";
11772        } else {
11773            annotation = "Input dispatching timed out (" + reason + ")";
11774        }
11775
11776        if (proc != null) {
11777            synchronized (this) {
11778                if (proc.debugging) {
11779                    return false;
11780                }
11781
11782                if (mDidDexOpt) {
11783                    // Give more time since we were dexopting.
11784                    mDidDexOpt = false;
11785                    return false;
11786                }
11787
11788                if (proc.instrumentationClass != null) {
11789                    Bundle info = new Bundle();
11790                    info.putString("shortMsg", "keyDispatchingTimedOut");
11791                    info.putString("longMsg", annotation);
11792                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11793                    return true;
11794                }
11795            }
11796            mHandler.post(new Runnable() {
11797                @Override
11798                public void run() {
11799                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11800                }
11801            });
11802        }
11803
11804        return true;
11805    }
11806
11807    @Override
11808    public Bundle getAssistContextExtras(int requestType) {
11809        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11810                null, null, true, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11811        if (pae == null) {
11812            return null;
11813        }
11814        synchronized (pae) {
11815            while (!pae.haveResult) {
11816                try {
11817                    pae.wait();
11818                } catch (InterruptedException e) {
11819                }
11820            }
11821        }
11822        synchronized (this) {
11823            buildAssistBundleLocked(pae, pae.result);
11824            mPendingAssistExtras.remove(pae);
11825            mUiHandler.removeCallbacks(pae);
11826        }
11827        return pae.extras;
11828    }
11829
11830    @Override
11831    public boolean isAssistDataAllowedOnCurrentActivity() {
11832        int userId;
11833        synchronized (this) {
11834            userId = mUserController.getCurrentUserIdLocked();
11835            ActivityRecord activity = getFocusedStack().topActivity();
11836            if (activity == null) {
11837                return false;
11838            }
11839            userId = activity.userId;
11840        }
11841        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11842                Context.DEVICE_POLICY_SERVICE);
11843        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11844    }
11845
11846    @Override
11847    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11848        long ident = Binder.clearCallingIdentity();
11849        try {
11850            synchronized (this) {
11851                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11852                ActivityRecord top = getFocusedStack().topActivity();
11853                if (top != caller) {
11854                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11855                            + " is not current top " + top);
11856                    return false;
11857                }
11858                if (!top.nowVisible) {
11859                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11860                            + " is not visible");
11861                    return false;
11862                }
11863            }
11864            AssistUtils utils = new AssistUtils(mContext);
11865            return utils.showSessionForActiveService(args,
11866                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11867        } finally {
11868            Binder.restoreCallingIdentity(ident);
11869        }
11870    }
11871
11872    @Override
11873    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11874            Bundle receiverExtras,
11875            IBinder activityToken, boolean focused) {
11876        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11877                activityToken, focused,
11878                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11879                != null;
11880    }
11881
11882    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11883            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused,
11884            int userHandle, Bundle args, long timeout) {
11885        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11886                "enqueueAssistContext()");
11887        synchronized (this) {
11888            ActivityRecord activity = getFocusedStack().topActivity();
11889            if (activity == null) {
11890                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11891                return null;
11892            }
11893            if (activity.app == null || activity.app.thread == null) {
11894                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11895                return null;
11896            }
11897            if (focused) {
11898                if (activityToken != null) {
11899                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11900                    if (activity != caller) {
11901                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11902                                + " is not current top " + activity);
11903                        return null;
11904                    }
11905                }
11906            } else {
11907                activity = ActivityRecord.forTokenLocked(activityToken);
11908                if (activity == null) {
11909                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
11910                            + " couldn't be found");
11911                    return null;
11912                }
11913            }
11914
11915            PendingAssistExtras pae;
11916            Bundle extras = new Bundle();
11917            if (args != null) {
11918                extras.putAll(args);
11919            }
11920            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11921            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11922            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
11923                    userHandle);
11924            try {
11925                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11926                        requestType);
11927                mPendingAssistExtras.add(pae);
11928                mUiHandler.postDelayed(pae, timeout);
11929            } catch (RemoteException e) {
11930                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11931                return null;
11932            }
11933            return pae;
11934        }
11935    }
11936
11937    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11938        IResultReceiver receiver;
11939        synchronized (this) {
11940            mPendingAssistExtras.remove(pae);
11941            receiver = pae.receiver;
11942        }
11943        if (receiver != null) {
11944            // Caller wants result sent back to them.
11945            try {
11946                pae.receiver.send(0, null);
11947            } catch (RemoteException e) {
11948            }
11949        }
11950    }
11951
11952    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11953        if (result != null) {
11954            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11955        }
11956        if (pae.hint != null) {
11957            pae.extras.putBoolean(pae.hint, true);
11958        }
11959    }
11960
11961    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11962            AssistContent content, Uri referrer) {
11963        PendingAssistExtras pae = (PendingAssistExtras)token;
11964        synchronized (pae) {
11965            pae.result = extras;
11966            pae.structure = structure;
11967            pae.content = content;
11968            if (referrer != null) {
11969                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11970            }
11971            pae.haveResult = true;
11972            pae.notifyAll();
11973            if (pae.intent == null && pae.receiver == null) {
11974                // Caller is just waiting for the result.
11975                return;
11976            }
11977        }
11978
11979        // We are now ready to launch the assist activity.
11980        IResultReceiver sendReceiver = null;
11981        Bundle sendBundle = null;
11982        synchronized (this) {
11983            buildAssistBundleLocked(pae, extras);
11984            boolean exists = mPendingAssistExtras.remove(pae);
11985            mUiHandler.removeCallbacks(pae);
11986            if (!exists) {
11987                // Timed out.
11988                return;
11989            }
11990            if ((sendReceiver=pae.receiver) != null) {
11991                // Caller wants result sent back to them.
11992                sendBundle = new Bundle();
11993                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
11994                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
11995                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
11996                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
11997                        pae.receiverExtras);
11998            }
11999        }
12000        if (sendReceiver != null) {
12001            try {
12002                sendReceiver.send(0, sendBundle);
12003            } catch (RemoteException e) {
12004            }
12005            return;
12006        }
12007
12008        long ident = Binder.clearCallingIdentity();
12009        try {
12010            pae.intent.replaceExtras(pae.extras);
12011            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12012                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12013                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12014            closeSystemDialogs("assist");
12015            try {
12016                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12017            } catch (ActivityNotFoundException e) {
12018                Slog.w(TAG, "No activity to handle assist action.", e);
12019            }
12020        } finally {
12021            Binder.restoreCallingIdentity(ident);
12022        }
12023    }
12024
12025    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12026            Bundle args) {
12027        return enqueueAssistContext(requestType, intent, hint, null, null, null, true,
12028                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12029    }
12030
12031    public void registerProcessObserver(IProcessObserver observer) {
12032        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12033                "registerProcessObserver()");
12034        synchronized (this) {
12035            mProcessObservers.register(observer);
12036        }
12037    }
12038
12039    @Override
12040    public void unregisterProcessObserver(IProcessObserver observer) {
12041        synchronized (this) {
12042            mProcessObservers.unregister(observer);
12043        }
12044    }
12045
12046    @Override
12047    public void registerUidObserver(IUidObserver observer, int which) {
12048        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12049                "registerUidObserver()");
12050        synchronized (this) {
12051            mUidObservers.register(observer, which);
12052        }
12053    }
12054
12055    @Override
12056    public void unregisterUidObserver(IUidObserver observer) {
12057        synchronized (this) {
12058            mUidObservers.unregister(observer);
12059        }
12060    }
12061
12062    @Override
12063    public boolean convertFromTranslucent(IBinder token) {
12064        final long origId = Binder.clearCallingIdentity();
12065        try {
12066            synchronized (this) {
12067                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12068                if (r == null) {
12069                    return false;
12070                }
12071                final boolean translucentChanged = r.changeWindowTranslucency(true);
12072                if (translucentChanged) {
12073                    r.task.stack.releaseBackgroundResources(r);
12074                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12075                }
12076                mWindowManager.setAppFullscreen(token, true);
12077                return translucentChanged;
12078            }
12079        } finally {
12080            Binder.restoreCallingIdentity(origId);
12081        }
12082    }
12083
12084    @Override
12085    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12086        final long origId = Binder.clearCallingIdentity();
12087        try {
12088            synchronized (this) {
12089                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12090                if (r == null) {
12091                    return false;
12092                }
12093                int index = r.task.mActivities.lastIndexOf(r);
12094                if (index > 0) {
12095                    ActivityRecord under = r.task.mActivities.get(index - 1);
12096                    under.returningOptions = options;
12097                }
12098                final boolean translucentChanged = r.changeWindowTranslucency(false);
12099                if (translucentChanged) {
12100                    r.task.stack.convertActivityToTranslucent(r);
12101                }
12102                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12103                mWindowManager.setAppFullscreen(token, false);
12104                return translucentChanged;
12105            }
12106        } finally {
12107            Binder.restoreCallingIdentity(origId);
12108        }
12109    }
12110
12111    @Override
12112    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12113        final long origId = Binder.clearCallingIdentity();
12114        try {
12115            synchronized (this) {
12116                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12117                if (r != null) {
12118                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12119                }
12120            }
12121            return false;
12122        } finally {
12123            Binder.restoreCallingIdentity(origId);
12124        }
12125    }
12126
12127    @Override
12128    public boolean isBackgroundVisibleBehind(IBinder token) {
12129        final long origId = Binder.clearCallingIdentity();
12130        try {
12131            synchronized (this) {
12132                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12133                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12134                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12135                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12136                return visible;
12137            }
12138        } finally {
12139            Binder.restoreCallingIdentity(origId);
12140        }
12141    }
12142
12143    @Override
12144    public ActivityOptions getActivityOptions(IBinder token) {
12145        final long origId = Binder.clearCallingIdentity();
12146        try {
12147            synchronized (this) {
12148                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12149                if (r != null) {
12150                    final ActivityOptions activityOptions = r.pendingOptions;
12151                    r.pendingOptions = null;
12152                    return activityOptions;
12153                }
12154                return null;
12155            }
12156        } finally {
12157            Binder.restoreCallingIdentity(origId);
12158        }
12159    }
12160
12161    @Override
12162    public void setImmersive(IBinder token, boolean immersive) {
12163        synchronized(this) {
12164            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12165            if (r == null) {
12166                throw new IllegalArgumentException();
12167            }
12168            r.immersive = immersive;
12169
12170            // update associated state if we're frontmost
12171            if (r == mFocusedActivity) {
12172                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12173                applyUpdateLockStateLocked(r);
12174            }
12175        }
12176    }
12177
12178    @Override
12179    public boolean isImmersive(IBinder token) {
12180        synchronized (this) {
12181            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12182            if (r == null) {
12183                throw new IllegalArgumentException();
12184            }
12185            return r.immersive;
12186        }
12187    }
12188
12189    @Override
12190    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12191        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12192            throw new UnsupportedOperationException("VR mode not supported on this device!");
12193        }
12194
12195        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12196
12197        ActivityRecord r;
12198        synchronized (this) {
12199            r = ActivityRecord.isInStackLocked(token);
12200        }
12201
12202        if (r == null) {
12203            throw new IllegalArgumentException();
12204        }
12205
12206        int err;
12207        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12208                VrManagerInternal.NO_ERROR) {
12209            return err;
12210        }
12211
12212        synchronized(this) {
12213            r.requestedVrComponent = (enabled) ? packageName : null;
12214
12215            // Update associated state if this activity is currently focused
12216            if (r == mFocusedActivity) {
12217                applyUpdateVrModeLocked(r);
12218            }
12219            return 0;
12220        }
12221    }
12222
12223    @Override
12224    public boolean isVrModePackageEnabled(ComponentName packageName) {
12225        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12226            throw new UnsupportedOperationException("VR mode not supported on this device!");
12227        }
12228
12229        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12230
12231        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12232                VrManagerInternal.NO_ERROR;
12233    }
12234
12235    public boolean isTopActivityImmersive() {
12236        enforceNotIsolatedCaller("startActivity");
12237        synchronized (this) {
12238            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12239            return (r != null) ? r.immersive : false;
12240        }
12241    }
12242
12243    @Override
12244    public boolean isTopOfTask(IBinder token) {
12245        synchronized (this) {
12246            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12247            if (r == null) {
12248                throw new IllegalArgumentException();
12249            }
12250            return r.task.getTopActivity() == r;
12251        }
12252    }
12253
12254    public final void enterSafeMode() {
12255        synchronized(this) {
12256            // It only makes sense to do this before the system is ready
12257            // and started launching other packages.
12258            if (!mSystemReady) {
12259                try {
12260                    AppGlobals.getPackageManager().enterSafeMode();
12261                } catch (RemoteException e) {
12262                }
12263            }
12264
12265            mSafeMode = true;
12266        }
12267    }
12268
12269    public final void showSafeModeOverlay() {
12270        View v = LayoutInflater.from(mContext).inflate(
12271                com.android.internal.R.layout.safe_mode, null);
12272        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12273        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12274        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12275        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12276        lp.gravity = Gravity.BOTTOM | Gravity.START;
12277        lp.format = v.getBackground().getOpacity();
12278        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12279                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12280        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12281        ((WindowManager)mContext.getSystemService(
12282                Context.WINDOW_SERVICE)).addView(v, lp);
12283    }
12284
12285    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12286        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12287            return;
12288        }
12289        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12290        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12291        synchronized (stats) {
12292            if (mBatteryStatsService.isOnBattery()) {
12293                mBatteryStatsService.enforceCallingPermission();
12294                int MY_UID = Binder.getCallingUid();
12295                final int uid;
12296                if (sender == null) {
12297                    uid = sourceUid;
12298                } else {
12299                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12300                }
12301                BatteryStatsImpl.Uid.Pkg pkg =
12302                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12303                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12304                pkg.noteWakeupAlarmLocked(tag);
12305            }
12306        }
12307    }
12308
12309    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12310        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12311            return;
12312        }
12313        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12314        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12315        synchronized (stats) {
12316            mBatteryStatsService.enforceCallingPermission();
12317            int MY_UID = Binder.getCallingUid();
12318            final int uid;
12319            if (sender == null) {
12320                uid = sourceUid;
12321            } else {
12322                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12323            }
12324            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12325        }
12326    }
12327
12328    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12329        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12330            return;
12331        }
12332        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12333        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12334        synchronized (stats) {
12335            mBatteryStatsService.enforceCallingPermission();
12336            int MY_UID = Binder.getCallingUid();
12337            final int uid;
12338            if (sender == null) {
12339                uid = sourceUid;
12340            } else {
12341                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12342            }
12343            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12344        }
12345    }
12346
12347    public boolean killPids(int[] pids, String pReason, boolean secure) {
12348        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12349            throw new SecurityException("killPids only available to the system");
12350        }
12351        String reason = (pReason == null) ? "Unknown" : pReason;
12352        // XXX Note: don't acquire main activity lock here, because the window
12353        // manager calls in with its locks held.
12354
12355        boolean killed = false;
12356        synchronized (mPidsSelfLocked) {
12357            int worstType = 0;
12358            for (int i=0; i<pids.length; i++) {
12359                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12360                if (proc != null) {
12361                    int type = proc.setAdj;
12362                    if (type > worstType) {
12363                        worstType = type;
12364                    }
12365                }
12366            }
12367
12368            // If the worst oom_adj is somewhere in the cached proc LRU range,
12369            // then constrain it so we will kill all cached procs.
12370            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12371                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12372                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12373            }
12374
12375            // If this is not a secure call, don't let it kill processes that
12376            // are important.
12377            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12378                worstType = ProcessList.SERVICE_ADJ;
12379            }
12380
12381            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12382            for (int i=0; i<pids.length; i++) {
12383                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12384                if (proc == null) {
12385                    continue;
12386                }
12387                int adj = proc.setAdj;
12388                if (adj >= worstType && !proc.killedByAm) {
12389                    proc.kill(reason, true);
12390                    killed = true;
12391                }
12392            }
12393        }
12394        return killed;
12395    }
12396
12397    @Override
12398    public void killUid(int appId, int userId, String reason) {
12399        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12400        synchronized (this) {
12401            final long identity = Binder.clearCallingIdentity();
12402            try {
12403                killPackageProcessesLocked(null, appId, userId,
12404                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12405                        reason != null ? reason : "kill uid");
12406            } finally {
12407                Binder.restoreCallingIdentity(identity);
12408            }
12409        }
12410    }
12411
12412    @Override
12413    public boolean killProcessesBelowForeground(String reason) {
12414        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12415            throw new SecurityException("killProcessesBelowForeground() only available to system");
12416        }
12417
12418        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12419    }
12420
12421    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12422        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12423            throw new SecurityException("killProcessesBelowAdj() only available to system");
12424        }
12425
12426        boolean killed = false;
12427        synchronized (mPidsSelfLocked) {
12428            final int size = mPidsSelfLocked.size();
12429            for (int i = 0; i < size; i++) {
12430                final int pid = mPidsSelfLocked.keyAt(i);
12431                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12432                if (proc == null) continue;
12433
12434                final int adj = proc.setAdj;
12435                if (adj > belowAdj && !proc.killedByAm) {
12436                    proc.kill(reason, true);
12437                    killed = true;
12438                }
12439            }
12440        }
12441        return killed;
12442    }
12443
12444    @Override
12445    public void hang(final IBinder who, boolean allowRestart) {
12446        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12447                != PackageManager.PERMISSION_GRANTED) {
12448            throw new SecurityException("Requires permission "
12449                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12450        }
12451
12452        final IBinder.DeathRecipient death = new DeathRecipient() {
12453            @Override
12454            public void binderDied() {
12455                synchronized (this) {
12456                    notifyAll();
12457                }
12458            }
12459        };
12460
12461        try {
12462            who.linkToDeath(death, 0);
12463        } catch (RemoteException e) {
12464            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12465            return;
12466        }
12467
12468        synchronized (this) {
12469            Watchdog.getInstance().setAllowRestart(allowRestart);
12470            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12471            synchronized (death) {
12472                while (who.isBinderAlive()) {
12473                    try {
12474                        death.wait();
12475                    } catch (InterruptedException e) {
12476                    }
12477                }
12478            }
12479            Watchdog.getInstance().setAllowRestart(true);
12480        }
12481    }
12482
12483    @Override
12484    public void restart() {
12485        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12486                != PackageManager.PERMISSION_GRANTED) {
12487            throw new SecurityException("Requires permission "
12488                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12489        }
12490
12491        Log.i(TAG, "Sending shutdown broadcast...");
12492
12493        BroadcastReceiver br = new BroadcastReceiver() {
12494            @Override public void onReceive(Context context, Intent intent) {
12495                // Now the broadcast is done, finish up the low-level shutdown.
12496                Log.i(TAG, "Shutting down activity manager...");
12497                shutdown(10000);
12498                Log.i(TAG, "Shutdown complete, restarting!");
12499                Process.killProcess(Process.myPid());
12500                System.exit(10);
12501            }
12502        };
12503
12504        // First send the high-level shut down broadcast.
12505        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12506        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12507        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12508        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12509        mContext.sendOrderedBroadcastAsUser(intent,
12510                UserHandle.ALL, null, br, mHandler, 0, null, null);
12511        */
12512        br.onReceive(mContext, intent);
12513    }
12514
12515    private long getLowRamTimeSinceIdle(long now) {
12516        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12517    }
12518
12519    @Override
12520    public void performIdleMaintenance() {
12521        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12522                != PackageManager.PERMISSION_GRANTED) {
12523            throw new SecurityException("Requires permission "
12524                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12525        }
12526
12527        synchronized (this) {
12528            final long now = SystemClock.uptimeMillis();
12529            final long timeSinceLastIdle = now - mLastIdleTime;
12530            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12531            mLastIdleTime = now;
12532            mLowRamTimeSinceLastIdle = 0;
12533            if (mLowRamStartTime != 0) {
12534                mLowRamStartTime = now;
12535            }
12536
12537            StringBuilder sb = new StringBuilder(128);
12538            sb.append("Idle maintenance over ");
12539            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12540            sb.append(" low RAM for ");
12541            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12542            Slog.i(TAG, sb.toString());
12543
12544            // If at least 1/3 of our time since the last idle period has been spent
12545            // with RAM low, then we want to kill processes.
12546            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12547
12548            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12549                ProcessRecord proc = mLruProcesses.get(i);
12550                if (proc.notCachedSinceIdle) {
12551                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12552                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12553                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12554                        if (doKilling && proc.initialIdlePss != 0
12555                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12556                            sb = new StringBuilder(128);
12557                            sb.append("Kill");
12558                            sb.append(proc.processName);
12559                            sb.append(" in idle maint: pss=");
12560                            sb.append(proc.lastPss);
12561                            sb.append(", swapPss=");
12562                            sb.append(proc.lastSwapPss);
12563                            sb.append(", initialPss=");
12564                            sb.append(proc.initialIdlePss);
12565                            sb.append(", period=");
12566                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12567                            sb.append(", lowRamPeriod=");
12568                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12569                            Slog.wtfQuiet(TAG, sb.toString());
12570                            proc.kill("idle maint (pss " + proc.lastPss
12571                                    + " from " + proc.initialIdlePss + ")", true);
12572                        }
12573                    }
12574                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12575                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12576                    proc.notCachedSinceIdle = true;
12577                    proc.initialIdlePss = 0;
12578                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12579                            mTestPssMode, isSleeping(), now);
12580                }
12581            }
12582
12583            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12584            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12585        }
12586    }
12587
12588    private void retrieveSettings() {
12589        final ContentResolver resolver = mContext.getContentResolver();
12590        final boolean freeformWindowManagement =
12591                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12592                        || Settings.Global.getInt(
12593                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12594        final boolean supportsPictureInPicture =
12595                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12596
12597        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12598        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12599        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12600        final boolean alwaysFinishActivities =
12601                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12602        final boolean lenientBackgroundCheck =
12603                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12604        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12605        final boolean forceResizable = Settings.Global.getInt(
12606                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12607        // Transfer any global setting for forcing RTL layout, into a System Property
12608        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12609
12610        final Configuration configuration = new Configuration();
12611        Settings.System.getConfiguration(resolver, configuration);
12612        if (forceRtl) {
12613            // This will take care of setting the correct layout direction flags
12614            configuration.setLayoutDirection(configuration.locale);
12615        }
12616
12617        synchronized (this) {
12618            mDebugApp = mOrigDebugApp = debugApp;
12619            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12620            mAlwaysFinishActivities = alwaysFinishActivities;
12621            mLenientBackgroundCheck = lenientBackgroundCheck;
12622            mForceResizableActivities = forceResizable;
12623            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12624            if (supportsMultiWindow || forceResizable) {
12625                mSupportsMultiWindow = true;
12626                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12627                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12628            } else {
12629                mSupportsMultiWindow = false;
12630                mSupportsFreeformWindowManagement = false;
12631                mSupportsPictureInPicture = false;
12632            }
12633            // This happens before any activities are started, so we can
12634            // change mConfiguration in-place.
12635            updateConfigurationLocked(configuration, null, true);
12636            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12637                    "Initial config: " + mConfiguration);
12638
12639            // Load resources only after the current configuration has been set.
12640            final Resources res = mContext.getResources();
12641            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12642            mThumbnailWidth = res.getDimensionPixelSize(
12643                    com.android.internal.R.dimen.thumbnail_width);
12644            mThumbnailHeight = res.getDimensionPixelSize(
12645                    com.android.internal.R.dimen.thumbnail_height);
12646            mFullscreenThumbnailScale = res.getFraction(
12647                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12648            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12649                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12650            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12651                    com.android.internal.R.string.config_appsNotReportingCrashes));
12652        }
12653    }
12654
12655    public boolean testIsSystemReady() {
12656        // no need to synchronize(this) just to read & return the value
12657        return mSystemReady;
12658    }
12659
12660    public void systemReady(final Runnable goingCallback) {
12661        synchronized(this) {
12662            if (mSystemReady) {
12663                // If we're done calling all the receivers, run the next "boot phase" passed in
12664                // by the SystemServer
12665                if (goingCallback != null) {
12666                    goingCallback.run();
12667                }
12668                return;
12669            }
12670
12671            mLocalDeviceIdleController
12672                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12673
12674            // Make sure we have the current profile info, since it is needed for security checks.
12675            mUserController.onSystemReady();
12676            mRecentTasks.onSystemReadyLocked();
12677            mAppOpsService.systemReady();
12678            mSystemReady = true;
12679        }
12680
12681        ArrayList<ProcessRecord> procsToKill = null;
12682        synchronized(mPidsSelfLocked) {
12683            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12684                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12685                if (!isAllowedWhileBooting(proc.info)){
12686                    if (procsToKill == null) {
12687                        procsToKill = new ArrayList<ProcessRecord>();
12688                    }
12689                    procsToKill.add(proc);
12690                }
12691            }
12692        }
12693
12694        synchronized(this) {
12695            if (procsToKill != null) {
12696                for (int i=procsToKill.size()-1; i>=0; i--) {
12697                    ProcessRecord proc = procsToKill.get(i);
12698                    Slog.i(TAG, "Removing system update proc: " + proc);
12699                    removeProcessLocked(proc, true, false, "system update done");
12700                }
12701            }
12702
12703            // Now that we have cleaned up any update processes, we
12704            // are ready to start launching real processes and know that
12705            // we won't trample on them any more.
12706            mProcessesReady = true;
12707        }
12708
12709        Slog.i(TAG, "System now ready");
12710        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12711            SystemClock.uptimeMillis());
12712
12713        synchronized(this) {
12714            // Make sure we have no pre-ready processes sitting around.
12715
12716            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12717                ResolveInfo ri = mContext.getPackageManager()
12718                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12719                                STOCK_PM_FLAGS);
12720                CharSequence errorMsg = null;
12721                if (ri != null) {
12722                    ActivityInfo ai = ri.activityInfo;
12723                    ApplicationInfo app = ai.applicationInfo;
12724                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12725                        mTopAction = Intent.ACTION_FACTORY_TEST;
12726                        mTopData = null;
12727                        mTopComponent = new ComponentName(app.packageName,
12728                                ai.name);
12729                    } else {
12730                        errorMsg = mContext.getResources().getText(
12731                                com.android.internal.R.string.factorytest_not_system);
12732                    }
12733                } else {
12734                    errorMsg = mContext.getResources().getText(
12735                            com.android.internal.R.string.factorytest_no_action);
12736                }
12737                if (errorMsg != null) {
12738                    mTopAction = null;
12739                    mTopData = null;
12740                    mTopComponent = null;
12741                    Message msg = Message.obtain();
12742                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12743                    msg.getData().putCharSequence("msg", errorMsg);
12744                    mUiHandler.sendMessage(msg);
12745                }
12746            }
12747        }
12748
12749        retrieveSettings();
12750        final int currentUserId;
12751        synchronized (this) {
12752            currentUserId = mUserController.getCurrentUserIdLocked();
12753            readGrantedUriPermissionsLocked();
12754        }
12755
12756        if (goingCallback != null) goingCallback.run();
12757
12758        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12759                Integer.toString(currentUserId), currentUserId);
12760        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12761                Integer.toString(currentUserId), currentUserId);
12762        mSystemServiceManager.startUser(currentUserId);
12763
12764        synchronized (this) {
12765            // Only start up encryption-aware persistent apps; once user is
12766            // unlocked we'll come back around and start unaware apps
12767            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12768
12769            // Start up initial activity.
12770            mBooting = true;
12771            // Enable home activity for system user, so that the system can always boot
12772            if (UserManager.isSplitSystemUser()) {
12773                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12774                try {
12775                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12776                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12777                            UserHandle.USER_SYSTEM);
12778                } catch (RemoteException e) {
12779                    throw e.rethrowAsRuntimeException();
12780                }
12781            }
12782            startHomeActivityLocked(currentUserId, "systemReady");
12783
12784            try {
12785                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12786                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12787                            + " data partition or your device will be unstable.");
12788                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12789                }
12790            } catch (RemoteException e) {
12791            }
12792
12793            if (!Build.isBuildConsistent()) {
12794                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12795                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12796            }
12797
12798            long ident = Binder.clearCallingIdentity();
12799            try {
12800                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12801                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12802                        | Intent.FLAG_RECEIVER_FOREGROUND);
12803                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12804                broadcastIntentLocked(null, null, intent,
12805                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12806                        null, false, false, MY_PID, Process.SYSTEM_UID,
12807                        currentUserId);
12808                intent = new Intent(Intent.ACTION_USER_STARTING);
12809                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12810                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12811                broadcastIntentLocked(null, null, intent,
12812                        null, new IIntentReceiver.Stub() {
12813                            @Override
12814                            public void performReceive(Intent intent, int resultCode, String data,
12815                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12816                                    throws RemoteException {
12817                            }
12818                        }, 0, null, null,
12819                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12820                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12821            } catch (Throwable t) {
12822                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12823            } finally {
12824                Binder.restoreCallingIdentity(ident);
12825            }
12826            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12827            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12828        }
12829    }
12830
12831    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12832        synchronized (this) {
12833            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12834        }
12835    }
12836
12837    void skipCurrentReceiverLocked(ProcessRecord app) {
12838        for (BroadcastQueue queue : mBroadcastQueues) {
12839            queue.skipCurrentReceiverLocked(app);
12840        }
12841    }
12842
12843    /**
12844     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12845     * The application process will exit immediately after this call returns.
12846     * @param app object of the crashing app, null for the system server
12847     * @param crashInfo describing the exception
12848     */
12849    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12850        ProcessRecord r = findAppProcess(app, "Crash");
12851        final String processName = app == null ? "system_server"
12852                : (r == null ? "unknown" : r.processName);
12853
12854        handleApplicationCrashInner("crash", r, processName, crashInfo);
12855    }
12856
12857    /* Native crash reporting uses this inner version because it needs to be somewhat
12858     * decoupled from the AM-managed cleanup lifecycle
12859     */
12860    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12861            ApplicationErrorReport.CrashInfo crashInfo) {
12862        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12863                UserHandle.getUserId(Binder.getCallingUid()), processName,
12864                r == null ? -1 : r.info.flags,
12865                crashInfo.exceptionClassName,
12866                crashInfo.exceptionMessage,
12867                crashInfo.throwFileName,
12868                crashInfo.throwLineNumber);
12869
12870        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12871
12872        mAppErrors.crashApplication(r, crashInfo);
12873    }
12874
12875    public void handleApplicationStrictModeViolation(
12876            IBinder app,
12877            int violationMask,
12878            StrictMode.ViolationInfo info) {
12879        ProcessRecord r = findAppProcess(app, "StrictMode");
12880        if (r == null) {
12881            return;
12882        }
12883
12884        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12885            Integer stackFingerprint = info.hashCode();
12886            boolean logIt = true;
12887            synchronized (mAlreadyLoggedViolatedStacks) {
12888                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12889                    logIt = false;
12890                    // TODO: sub-sample into EventLog for these, with
12891                    // the info.durationMillis?  Then we'd get
12892                    // the relative pain numbers, without logging all
12893                    // the stack traces repeatedly.  We'd want to do
12894                    // likewise in the client code, which also does
12895                    // dup suppression, before the Binder call.
12896                } else {
12897                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12898                        mAlreadyLoggedViolatedStacks.clear();
12899                    }
12900                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12901                }
12902            }
12903            if (logIt) {
12904                logStrictModeViolationToDropBox(r, info);
12905            }
12906        }
12907
12908        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12909            AppErrorResult result = new AppErrorResult();
12910            synchronized (this) {
12911                final long origId = Binder.clearCallingIdentity();
12912
12913                Message msg = Message.obtain();
12914                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12915                HashMap<String, Object> data = new HashMap<String, Object>();
12916                data.put("result", result);
12917                data.put("app", r);
12918                data.put("violationMask", violationMask);
12919                data.put("info", info);
12920                msg.obj = data;
12921                mUiHandler.sendMessage(msg);
12922
12923                Binder.restoreCallingIdentity(origId);
12924            }
12925            int res = result.get();
12926            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12927        }
12928    }
12929
12930    // Depending on the policy in effect, there could be a bunch of
12931    // these in quick succession so we try to batch these together to
12932    // minimize disk writes, number of dropbox entries, and maximize
12933    // compression, by having more fewer, larger records.
12934    private void logStrictModeViolationToDropBox(
12935            ProcessRecord process,
12936            StrictMode.ViolationInfo info) {
12937        if (info == null) {
12938            return;
12939        }
12940        final boolean isSystemApp = process == null ||
12941                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12942                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12943        final String processName = process == null ? "unknown" : process.processName;
12944        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12945        final DropBoxManager dbox = (DropBoxManager)
12946                mContext.getSystemService(Context.DROPBOX_SERVICE);
12947
12948        // Exit early if the dropbox isn't configured to accept this report type.
12949        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12950
12951        boolean bufferWasEmpty;
12952        boolean needsFlush;
12953        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12954        synchronized (sb) {
12955            bufferWasEmpty = sb.length() == 0;
12956            appendDropBoxProcessHeaders(process, processName, sb);
12957            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12958            sb.append("System-App: ").append(isSystemApp).append("\n");
12959            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12960            if (info.violationNumThisLoop != 0) {
12961                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12962            }
12963            if (info.numAnimationsRunning != 0) {
12964                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12965            }
12966            if (info.broadcastIntentAction != null) {
12967                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12968            }
12969            if (info.durationMillis != -1) {
12970                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12971            }
12972            if (info.numInstances != -1) {
12973                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12974            }
12975            if (info.tags != null) {
12976                for (String tag : info.tags) {
12977                    sb.append("Span-Tag: ").append(tag).append("\n");
12978                }
12979            }
12980            sb.append("\n");
12981            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12982                sb.append(info.crashInfo.stackTrace);
12983                sb.append("\n");
12984            }
12985            if (info.message != null) {
12986                sb.append(info.message);
12987                sb.append("\n");
12988            }
12989
12990            // Only buffer up to ~64k.  Various logging bits truncate
12991            // things at 128k.
12992            needsFlush = (sb.length() > 64 * 1024);
12993        }
12994
12995        // Flush immediately if the buffer's grown too large, or this
12996        // is a non-system app.  Non-system apps are isolated with a
12997        // different tag & policy and not batched.
12998        //
12999        // Batching is useful during internal testing with
13000        // StrictMode settings turned up high.  Without batching,
13001        // thousands of separate files could be created on boot.
13002        if (!isSystemApp || needsFlush) {
13003            new Thread("Error dump: " + dropboxTag) {
13004                @Override
13005                public void run() {
13006                    String report;
13007                    synchronized (sb) {
13008                        report = sb.toString();
13009                        sb.delete(0, sb.length());
13010                        sb.trimToSize();
13011                    }
13012                    if (report.length() != 0) {
13013                        dbox.addText(dropboxTag, report);
13014                    }
13015                }
13016            }.start();
13017            return;
13018        }
13019
13020        // System app batching:
13021        if (!bufferWasEmpty) {
13022            // An existing dropbox-writing thread is outstanding, so
13023            // we don't need to start it up.  The existing thread will
13024            // catch the buffer appends we just did.
13025            return;
13026        }
13027
13028        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13029        // (After this point, we shouldn't access AMS internal data structures.)
13030        new Thread("Error dump: " + dropboxTag) {
13031            @Override
13032            public void run() {
13033                // 5 second sleep to let stacks arrive and be batched together
13034                try {
13035                    Thread.sleep(5000);  // 5 seconds
13036                } catch (InterruptedException e) {}
13037
13038                String errorReport;
13039                synchronized (mStrictModeBuffer) {
13040                    errorReport = mStrictModeBuffer.toString();
13041                    if (errorReport.length() == 0) {
13042                        return;
13043                    }
13044                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13045                    mStrictModeBuffer.trimToSize();
13046                }
13047                dbox.addText(dropboxTag, errorReport);
13048            }
13049        }.start();
13050    }
13051
13052    /**
13053     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13054     * @param app object of the crashing app, null for the system server
13055     * @param tag reported by the caller
13056     * @param system whether this wtf is coming from the system
13057     * @param crashInfo describing the context of the error
13058     * @return true if the process should exit immediately (WTF is fatal)
13059     */
13060    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13061            final ApplicationErrorReport.CrashInfo crashInfo) {
13062        final int callingUid = Binder.getCallingUid();
13063        final int callingPid = Binder.getCallingPid();
13064
13065        if (system) {
13066            // If this is coming from the system, we could very well have low-level
13067            // system locks held, so we want to do this all asynchronously.  And we
13068            // never want this to become fatal, so there is that too.
13069            mHandler.post(new Runnable() {
13070                @Override public void run() {
13071                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13072                }
13073            });
13074            return false;
13075        }
13076
13077        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13078                crashInfo);
13079
13080        if (r != null && r.pid != Process.myPid() &&
13081                Settings.Global.getInt(mContext.getContentResolver(),
13082                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13083            mAppErrors.crashApplication(r, crashInfo);
13084            return true;
13085        } else {
13086            return false;
13087        }
13088    }
13089
13090    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13091            final ApplicationErrorReport.CrashInfo crashInfo) {
13092        final ProcessRecord r = findAppProcess(app, "WTF");
13093        final String processName = app == null ? "system_server"
13094                : (r == null ? "unknown" : r.processName);
13095
13096        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13097                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13098
13099        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13100
13101        return r;
13102    }
13103
13104    /**
13105     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13106     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13107     */
13108    private ProcessRecord findAppProcess(IBinder app, String reason) {
13109        if (app == null) {
13110            return null;
13111        }
13112
13113        synchronized (this) {
13114            final int NP = mProcessNames.getMap().size();
13115            for (int ip=0; ip<NP; ip++) {
13116                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13117                final int NA = apps.size();
13118                for (int ia=0; ia<NA; ia++) {
13119                    ProcessRecord p = apps.valueAt(ia);
13120                    if (p.thread != null && p.thread.asBinder() == app) {
13121                        return p;
13122                    }
13123                }
13124            }
13125
13126            Slog.w(TAG, "Can't find mystery application for " + reason
13127                    + " from pid=" + Binder.getCallingPid()
13128                    + " uid=" + Binder.getCallingUid() + ": " + app);
13129            return null;
13130        }
13131    }
13132
13133    /**
13134     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13135     * to append various headers to the dropbox log text.
13136     */
13137    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13138            StringBuilder sb) {
13139        // Watchdog thread ends up invoking this function (with
13140        // a null ProcessRecord) to add the stack file to dropbox.
13141        // Do not acquire a lock on this (am) in such cases, as it
13142        // could cause a potential deadlock, if and when watchdog
13143        // is invoked due to unavailability of lock on am and it
13144        // would prevent watchdog from killing system_server.
13145        if (process == null) {
13146            sb.append("Process: ").append(processName).append("\n");
13147            return;
13148        }
13149        // Note: ProcessRecord 'process' is guarded by the service
13150        // instance.  (notably process.pkgList, which could otherwise change
13151        // concurrently during execution of this method)
13152        synchronized (this) {
13153            sb.append("Process: ").append(processName).append("\n");
13154            int flags = process.info.flags;
13155            IPackageManager pm = AppGlobals.getPackageManager();
13156            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13157            for (int ip=0; ip<process.pkgList.size(); ip++) {
13158                String pkg = process.pkgList.keyAt(ip);
13159                sb.append("Package: ").append(pkg);
13160                try {
13161                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13162                    if (pi != null) {
13163                        sb.append(" v").append(pi.versionCode);
13164                        if (pi.versionName != null) {
13165                            sb.append(" (").append(pi.versionName).append(")");
13166                        }
13167                    }
13168                } catch (RemoteException e) {
13169                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13170                }
13171                sb.append("\n");
13172            }
13173        }
13174    }
13175
13176    private static String processClass(ProcessRecord process) {
13177        if (process == null || process.pid == MY_PID) {
13178            return "system_server";
13179        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13180            return "system_app";
13181        } else {
13182            return "data_app";
13183        }
13184    }
13185
13186    /**
13187     * Write a description of an error (crash, WTF, ANR) to the drop box.
13188     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13189     * @param process which caused the error, null means the system server
13190     * @param activity which triggered the error, null if unknown
13191     * @param parent activity related to the error, null if unknown
13192     * @param subject line related to the error, null if absent
13193     * @param report in long form describing the error, null if absent
13194     * @param logFile to include in the report, null if none
13195     * @param crashInfo giving an application stack trace, null if absent
13196     */
13197    public void addErrorToDropBox(String eventType,
13198            ProcessRecord process, String processName, ActivityRecord activity,
13199            ActivityRecord parent, String subject,
13200            final String report, final File logFile,
13201            final ApplicationErrorReport.CrashInfo crashInfo) {
13202        // NOTE -- this must never acquire the ActivityManagerService lock,
13203        // otherwise the watchdog may be prevented from resetting the system.
13204
13205        final String dropboxTag = processClass(process) + "_" + eventType;
13206        final DropBoxManager dbox = (DropBoxManager)
13207                mContext.getSystemService(Context.DROPBOX_SERVICE);
13208
13209        // Exit early if the dropbox isn't configured to accept this report type.
13210        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13211
13212        final StringBuilder sb = new StringBuilder(1024);
13213        appendDropBoxProcessHeaders(process, processName, sb);
13214        if (process != null) {
13215            sb.append("Foreground: ")
13216                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13217                    .append("\n");
13218        }
13219        if (activity != null) {
13220            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13221        }
13222        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13223            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13224        }
13225        if (parent != null && parent != activity) {
13226            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13227        }
13228        if (subject != null) {
13229            sb.append("Subject: ").append(subject).append("\n");
13230        }
13231        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13232        if (Debug.isDebuggerConnected()) {
13233            sb.append("Debugger: Connected\n");
13234        }
13235        sb.append("\n");
13236
13237        // Do the rest in a worker thread to avoid blocking the caller on I/O
13238        // (After this point, we shouldn't access AMS internal data structures.)
13239        Thread worker = new Thread("Error dump: " + dropboxTag) {
13240            @Override
13241            public void run() {
13242                if (report != null) {
13243                    sb.append(report);
13244                }
13245                if (logFile != null) {
13246                    try {
13247                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13248                                    "\n\n[[TRUNCATED]]"));
13249                    } catch (IOException e) {
13250                        Slog.e(TAG, "Error reading " + logFile, e);
13251                    }
13252                }
13253                if (crashInfo != null && crashInfo.stackTrace != null) {
13254                    sb.append(crashInfo.stackTrace);
13255                }
13256
13257                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13258                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13259                if (lines > 0) {
13260                    sb.append("\n");
13261
13262                    // Merge several logcat streams, and take the last N lines
13263                    InputStreamReader input = null;
13264                    try {
13265                        java.lang.Process logcat = new ProcessBuilder(
13266                                "/system/bin/timeout", "-k", "15s", "10s",
13267                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13268                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13269                                        .redirectErrorStream(true).start();
13270
13271                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13272                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13273                        input = new InputStreamReader(logcat.getInputStream());
13274
13275                        int num;
13276                        char[] buf = new char[8192];
13277                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13278                    } catch (IOException e) {
13279                        Slog.e(TAG, "Error running logcat", e);
13280                    } finally {
13281                        if (input != null) try { input.close(); } catch (IOException e) {}
13282                    }
13283                }
13284
13285                dbox.addText(dropboxTag, sb.toString());
13286            }
13287        };
13288
13289        if (process == null) {
13290            // If process is null, we are being called from some internal code
13291            // and may be about to die -- run this synchronously.
13292            worker.run();
13293        } else {
13294            worker.start();
13295        }
13296    }
13297
13298    @Override
13299    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13300        enforceNotIsolatedCaller("getProcessesInErrorState");
13301        // assume our apps are happy - lazy create the list
13302        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13303
13304        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13305                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13306        int userId = UserHandle.getUserId(Binder.getCallingUid());
13307
13308        synchronized (this) {
13309
13310            // iterate across all processes
13311            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13312                ProcessRecord app = mLruProcesses.get(i);
13313                if (!allUsers && app.userId != userId) {
13314                    continue;
13315                }
13316                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13317                    // This one's in trouble, so we'll generate a report for it
13318                    // crashes are higher priority (in case there's a crash *and* an anr)
13319                    ActivityManager.ProcessErrorStateInfo report = null;
13320                    if (app.crashing) {
13321                        report = app.crashingReport;
13322                    } else if (app.notResponding) {
13323                        report = app.notRespondingReport;
13324                    }
13325
13326                    if (report != null) {
13327                        if (errList == null) {
13328                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13329                        }
13330                        errList.add(report);
13331                    } else {
13332                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13333                                " crashing = " + app.crashing +
13334                                " notResponding = " + app.notResponding);
13335                    }
13336                }
13337            }
13338        }
13339
13340        return errList;
13341    }
13342
13343    static int procStateToImportance(int procState, int memAdj,
13344            ActivityManager.RunningAppProcessInfo currApp) {
13345        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13346        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13347            currApp.lru = memAdj;
13348        } else {
13349            currApp.lru = 0;
13350        }
13351        return imp;
13352    }
13353
13354    private void fillInProcMemInfo(ProcessRecord app,
13355            ActivityManager.RunningAppProcessInfo outInfo) {
13356        outInfo.pid = app.pid;
13357        outInfo.uid = app.info.uid;
13358        if (mHeavyWeightProcess == app) {
13359            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13360        }
13361        if (app.persistent) {
13362            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13363        }
13364        if (app.activities.size() > 0) {
13365            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13366        }
13367        outInfo.lastTrimLevel = app.trimMemoryLevel;
13368        int adj = app.curAdj;
13369        int procState = app.curProcState;
13370        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13371        outInfo.importanceReasonCode = app.adjTypeCode;
13372        outInfo.processState = app.curProcState;
13373    }
13374
13375    @Override
13376    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13377        enforceNotIsolatedCaller("getRunningAppProcesses");
13378
13379        final int callingUid = Binder.getCallingUid();
13380
13381        // Lazy instantiation of list
13382        List<ActivityManager.RunningAppProcessInfo> runList = null;
13383        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13384                callingUid) == PackageManager.PERMISSION_GRANTED;
13385        final int userId = UserHandle.getUserId(callingUid);
13386        final boolean allUids = isGetTasksAllowed(
13387                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13388
13389        synchronized (this) {
13390            // Iterate across all processes
13391            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13392                ProcessRecord app = mLruProcesses.get(i);
13393                if ((!allUsers && app.userId != userId)
13394                        || (!allUids && app.uid != callingUid)) {
13395                    continue;
13396                }
13397                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13398                    // Generate process state info for running application
13399                    ActivityManager.RunningAppProcessInfo currApp =
13400                        new ActivityManager.RunningAppProcessInfo(app.processName,
13401                                app.pid, app.getPackageList());
13402                    fillInProcMemInfo(app, currApp);
13403                    if (app.adjSource instanceof ProcessRecord) {
13404                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13405                        currApp.importanceReasonImportance =
13406                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13407                                        app.adjSourceProcState);
13408                    } else if (app.adjSource instanceof ActivityRecord) {
13409                        ActivityRecord r = (ActivityRecord)app.adjSource;
13410                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13411                    }
13412                    if (app.adjTarget instanceof ComponentName) {
13413                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13414                    }
13415                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13416                    //        + " lru=" + currApp.lru);
13417                    if (runList == null) {
13418                        runList = new ArrayList<>();
13419                    }
13420                    runList.add(currApp);
13421                }
13422            }
13423        }
13424        return runList;
13425    }
13426
13427    @Override
13428    public List<ApplicationInfo> getRunningExternalApplications() {
13429        enforceNotIsolatedCaller("getRunningExternalApplications");
13430        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13431        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13432        if (runningApps != null && runningApps.size() > 0) {
13433            Set<String> extList = new HashSet<String>();
13434            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13435                if (app.pkgList != null) {
13436                    for (String pkg : app.pkgList) {
13437                        extList.add(pkg);
13438                    }
13439                }
13440            }
13441            IPackageManager pm = AppGlobals.getPackageManager();
13442            for (String pkg : extList) {
13443                try {
13444                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13445                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13446                        retList.add(info);
13447                    }
13448                } catch (RemoteException e) {
13449                }
13450            }
13451        }
13452        return retList;
13453    }
13454
13455    @Override
13456    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13457        enforceNotIsolatedCaller("getMyMemoryState");
13458        synchronized (this) {
13459            ProcessRecord proc;
13460            synchronized (mPidsSelfLocked) {
13461                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13462            }
13463            fillInProcMemInfo(proc, outInfo);
13464        }
13465    }
13466
13467    @Override
13468    public int getMemoryTrimLevel() {
13469        enforceNotIsolatedCaller("getMyMemoryState");
13470        synchronized (this) {
13471            return mLastMemoryLevel;
13472        }
13473    }
13474
13475    @Override
13476    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13477            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13478        (new ActivityManagerShellCommand(this, false)).exec(
13479                this, in, out, err, args, resultReceiver);
13480    }
13481
13482    @Override
13483    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13484        if (checkCallingPermission(android.Manifest.permission.DUMP)
13485                != PackageManager.PERMISSION_GRANTED) {
13486            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13487                    + Binder.getCallingPid()
13488                    + ", uid=" + Binder.getCallingUid()
13489                    + " without permission "
13490                    + android.Manifest.permission.DUMP);
13491            return;
13492        }
13493
13494        boolean dumpAll = false;
13495        boolean dumpClient = false;
13496        String dumpPackage = null;
13497
13498        int opti = 0;
13499        while (opti < args.length) {
13500            String opt = args[opti];
13501            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13502                break;
13503            }
13504            opti++;
13505            if ("-a".equals(opt)) {
13506                dumpAll = true;
13507            } else if ("-c".equals(opt)) {
13508                dumpClient = true;
13509            } else if ("-p".equals(opt)) {
13510                if (opti < args.length) {
13511                    dumpPackage = args[opti];
13512                    opti++;
13513                } else {
13514                    pw.println("Error: -p option requires package argument");
13515                    return;
13516                }
13517                dumpClient = true;
13518            } else if ("-h".equals(opt)) {
13519                ActivityManagerShellCommand.dumpHelp(pw, true);
13520                return;
13521            } else {
13522                pw.println("Unknown argument: " + opt + "; use -h for help");
13523            }
13524        }
13525
13526        long origId = Binder.clearCallingIdentity();
13527        boolean more = false;
13528        // Is the caller requesting to dump a particular piece of data?
13529        if (opti < args.length) {
13530            String cmd = args[opti];
13531            opti++;
13532            if ("activities".equals(cmd) || "a".equals(cmd)) {
13533                synchronized (this) {
13534                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13535                }
13536            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13537                synchronized (this) {
13538                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13539                }
13540            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13541                String[] newArgs;
13542                String name;
13543                if (opti >= args.length) {
13544                    name = null;
13545                    newArgs = EMPTY_STRING_ARRAY;
13546                } else {
13547                    dumpPackage = args[opti];
13548                    opti++;
13549                    newArgs = new String[args.length - opti];
13550                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13551                            args.length - opti);
13552                }
13553                synchronized (this) {
13554                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13555                }
13556            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13557                String[] newArgs;
13558                String name;
13559                if (opti >= args.length) {
13560                    name = null;
13561                    newArgs = EMPTY_STRING_ARRAY;
13562                } else {
13563                    dumpPackage = args[opti];
13564                    opti++;
13565                    newArgs = new String[args.length - opti];
13566                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13567                            args.length - opti);
13568                }
13569                synchronized (this) {
13570                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13571                }
13572            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13573                String[] newArgs;
13574                String name;
13575                if (opti >= args.length) {
13576                    name = null;
13577                    newArgs = EMPTY_STRING_ARRAY;
13578                } else {
13579                    dumpPackage = args[opti];
13580                    opti++;
13581                    newArgs = new String[args.length - opti];
13582                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13583                            args.length - opti);
13584                }
13585                synchronized (this) {
13586                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13587                }
13588            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13589                synchronized (this) {
13590                    dumpOomLocked(fd, pw, args, opti, true);
13591                }
13592            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13593                synchronized (this) {
13594                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13595                }
13596            } else if ("provider".equals(cmd)) {
13597                String[] newArgs;
13598                String name;
13599                if (opti >= args.length) {
13600                    name = null;
13601                    newArgs = EMPTY_STRING_ARRAY;
13602                } else {
13603                    name = args[opti];
13604                    opti++;
13605                    newArgs = new String[args.length - opti];
13606                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13607                }
13608                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13609                    pw.println("No providers match: " + name);
13610                    pw.println("Use -h for help.");
13611                }
13612            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13613                synchronized (this) {
13614                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13615                }
13616            } else if ("service".equals(cmd)) {
13617                String[] newArgs;
13618                String name;
13619                if (opti >= args.length) {
13620                    name = null;
13621                    newArgs = EMPTY_STRING_ARRAY;
13622                } else {
13623                    name = args[opti];
13624                    opti++;
13625                    newArgs = new String[args.length - opti];
13626                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13627                            args.length - opti);
13628                }
13629                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13630                    pw.println("No services match: " + name);
13631                    pw.println("Use -h for help.");
13632                }
13633            } else if ("package".equals(cmd)) {
13634                String[] newArgs;
13635                if (opti >= args.length) {
13636                    pw.println("package: no package name specified");
13637                    pw.println("Use -h for help.");
13638                } else {
13639                    dumpPackage = args[opti];
13640                    opti++;
13641                    newArgs = new String[args.length - opti];
13642                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13643                            args.length - opti);
13644                    args = newArgs;
13645                    opti = 0;
13646                    more = true;
13647                }
13648            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13649                synchronized (this) {
13650                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13651                }
13652            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13653                synchronized (this) {
13654                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13655                }
13656            } else if ("locks".equals(cmd)) {
13657                LockGuard.dump(fd, pw, args);
13658            } else {
13659                // Dumping a single activity?
13660                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13661                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13662                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13663                    if (res < 0) {
13664                        pw.println("Bad activity command, or no activities match: " + cmd);
13665                        pw.println("Use -h for help.");
13666                    }
13667                }
13668            }
13669            if (!more) {
13670                Binder.restoreCallingIdentity(origId);
13671                return;
13672            }
13673        }
13674
13675        // No piece of data specified, dump everything.
13676        synchronized (this) {
13677            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13678            pw.println();
13679            if (dumpAll) {
13680                pw.println("-------------------------------------------------------------------------------");
13681            }
13682            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13683            pw.println();
13684            if (dumpAll) {
13685                pw.println("-------------------------------------------------------------------------------");
13686            }
13687            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13688            pw.println();
13689            if (dumpAll) {
13690                pw.println("-------------------------------------------------------------------------------");
13691            }
13692            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13693            pw.println();
13694            if (dumpAll) {
13695                pw.println("-------------------------------------------------------------------------------");
13696            }
13697            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13698            pw.println();
13699            if (dumpAll) {
13700                pw.println("-------------------------------------------------------------------------------");
13701            }
13702            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13703            pw.println();
13704            if (dumpAll) {
13705                pw.println("-------------------------------------------------------------------------------");
13706            }
13707            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13708            if (mAssociations.size() > 0) {
13709                pw.println();
13710                if (dumpAll) {
13711                    pw.println("-------------------------------------------------------------------------------");
13712                }
13713                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13714            }
13715            pw.println();
13716            if (dumpAll) {
13717                pw.println("-------------------------------------------------------------------------------");
13718            }
13719            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13720        }
13721        Binder.restoreCallingIdentity(origId);
13722    }
13723
13724    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13725            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13726        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13727
13728        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13729                dumpPackage);
13730        boolean needSep = printedAnything;
13731
13732        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13733                dumpPackage, needSep, "  mFocusedActivity: ");
13734        if (printed) {
13735            printedAnything = true;
13736            needSep = false;
13737        }
13738
13739        if (dumpPackage == null) {
13740            if (needSep) {
13741                pw.println();
13742            }
13743            needSep = true;
13744            printedAnything = true;
13745            mStackSupervisor.dump(pw, "  ");
13746        }
13747
13748        if (!printedAnything) {
13749            pw.println("  (nothing)");
13750        }
13751    }
13752
13753    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13754            int opti, boolean dumpAll, String dumpPackage) {
13755        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13756
13757        boolean printedAnything = false;
13758
13759        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13760            boolean printedHeader = false;
13761
13762            final int N = mRecentTasks.size();
13763            for (int i=0; i<N; i++) {
13764                TaskRecord tr = mRecentTasks.get(i);
13765                if (dumpPackage != null) {
13766                    if (tr.realActivity == null ||
13767                            !dumpPackage.equals(tr.realActivity)) {
13768                        continue;
13769                    }
13770                }
13771                if (!printedHeader) {
13772                    pw.println("  Recent tasks:");
13773                    printedHeader = true;
13774                    printedAnything = true;
13775                }
13776                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13777                        pw.println(tr);
13778                if (dumpAll) {
13779                    mRecentTasks.get(i).dump(pw, "    ");
13780                }
13781            }
13782        }
13783
13784        if (!printedAnything) {
13785            pw.println("  (nothing)");
13786        }
13787    }
13788
13789    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13790            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13791        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13792
13793        int dumpUid = 0;
13794        if (dumpPackage != null) {
13795            IPackageManager pm = AppGlobals.getPackageManager();
13796            try {
13797                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13798            } catch (RemoteException e) {
13799            }
13800        }
13801
13802        boolean printedAnything = false;
13803
13804        final long now = SystemClock.uptimeMillis();
13805
13806        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13807            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13808                    = mAssociations.valueAt(i1);
13809            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13810                SparseArray<ArrayMap<String, Association>> sourceUids
13811                        = targetComponents.valueAt(i2);
13812                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13813                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13814                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13815                        Association ass = sourceProcesses.valueAt(i4);
13816                        if (dumpPackage != null) {
13817                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13818                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13819                                continue;
13820                            }
13821                        }
13822                        printedAnything = true;
13823                        pw.print("  ");
13824                        pw.print(ass.mTargetProcess);
13825                        pw.print("/");
13826                        UserHandle.formatUid(pw, ass.mTargetUid);
13827                        pw.print(" <- ");
13828                        pw.print(ass.mSourceProcess);
13829                        pw.print("/");
13830                        UserHandle.formatUid(pw, ass.mSourceUid);
13831                        pw.println();
13832                        pw.print("    via ");
13833                        pw.print(ass.mTargetComponent.flattenToShortString());
13834                        pw.println();
13835                        pw.print("    ");
13836                        long dur = ass.mTime;
13837                        if (ass.mNesting > 0) {
13838                            dur += now - ass.mStartTime;
13839                        }
13840                        TimeUtils.formatDuration(dur, pw);
13841                        pw.print(" (");
13842                        pw.print(ass.mCount);
13843                        pw.print(" times)");
13844                        pw.print("  ");
13845                        for (int i=0; i<ass.mStateTimes.length; i++) {
13846                            long amt = ass.mStateTimes[i];
13847                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13848                                amt += now - ass.mLastStateUptime;
13849                            }
13850                            if (amt != 0) {
13851                                pw.print(" ");
13852                                pw.print(ProcessList.makeProcStateString(
13853                                            i + ActivityManager.MIN_PROCESS_STATE));
13854                                pw.print("=");
13855                                TimeUtils.formatDuration(amt, pw);
13856                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13857                                    pw.print("*");
13858                                }
13859                            }
13860                        }
13861                        pw.println();
13862                        if (ass.mNesting > 0) {
13863                            pw.print("    Currently active: ");
13864                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13865                            pw.println();
13866                        }
13867                    }
13868                }
13869            }
13870
13871        }
13872
13873        if (!printedAnything) {
13874            pw.println("  (nothing)");
13875        }
13876    }
13877
13878    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13879            String header, boolean needSep) {
13880        boolean printed = false;
13881        int whichAppId = -1;
13882        if (dumpPackage != null) {
13883            try {
13884                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13885                        dumpPackage, 0);
13886                whichAppId = UserHandle.getAppId(info.uid);
13887            } catch (NameNotFoundException e) {
13888                e.printStackTrace();
13889            }
13890        }
13891        for (int i=0; i<uids.size(); i++) {
13892            UidRecord uidRec = uids.valueAt(i);
13893            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13894                continue;
13895            }
13896            if (!printed) {
13897                printed = true;
13898                if (needSep) {
13899                    pw.println();
13900                }
13901                pw.print("  ");
13902                pw.println(header);
13903                needSep = true;
13904            }
13905            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13906            pw.print(": "); pw.println(uidRec);
13907        }
13908        return printed;
13909    }
13910
13911    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13912            int opti, boolean dumpAll, String dumpPackage) {
13913        boolean needSep = false;
13914        boolean printedAnything = false;
13915        int numPers = 0;
13916
13917        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13918
13919        if (dumpAll) {
13920            final int NP = mProcessNames.getMap().size();
13921            for (int ip=0; ip<NP; ip++) {
13922                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13923                final int NA = procs.size();
13924                for (int ia=0; ia<NA; ia++) {
13925                    ProcessRecord r = procs.valueAt(ia);
13926                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13927                        continue;
13928                    }
13929                    if (!needSep) {
13930                        pw.println("  All known processes:");
13931                        needSep = true;
13932                        printedAnything = true;
13933                    }
13934                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13935                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13936                        pw.print(" "); pw.println(r);
13937                    r.dump(pw, "    ");
13938                    if (r.persistent) {
13939                        numPers++;
13940                    }
13941                }
13942            }
13943        }
13944
13945        if (mIsolatedProcesses.size() > 0) {
13946            boolean printed = false;
13947            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13948                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13949                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13950                    continue;
13951                }
13952                if (!printed) {
13953                    if (needSep) {
13954                        pw.println();
13955                    }
13956                    pw.println("  Isolated process list (sorted by uid):");
13957                    printedAnything = true;
13958                    printed = true;
13959                    needSep = true;
13960                }
13961                pw.println(String.format("%sIsolated #%2d: %s",
13962                        "    ", i, r.toString()));
13963            }
13964        }
13965
13966        if (mActiveUids.size() > 0) {
13967            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13968                printedAnything = needSep = true;
13969            }
13970        }
13971        if (mValidateUids.size() > 0) {
13972            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13973                printedAnything = needSep = true;
13974            }
13975        }
13976
13977        if (mLruProcesses.size() > 0) {
13978            if (needSep) {
13979                pw.println();
13980            }
13981            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13982                    pw.print(" total, non-act at ");
13983                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13984                    pw.print(", non-svc at ");
13985                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13986                    pw.println("):");
13987            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13988            needSep = true;
13989            printedAnything = true;
13990        }
13991
13992        if (dumpAll || dumpPackage != null) {
13993            synchronized (mPidsSelfLocked) {
13994                boolean printed = false;
13995                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13996                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13997                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13998                        continue;
13999                    }
14000                    if (!printed) {
14001                        if (needSep) pw.println();
14002                        needSep = true;
14003                        pw.println("  PID mappings:");
14004                        printed = true;
14005                        printedAnything = true;
14006                    }
14007                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14008                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14009                }
14010            }
14011        }
14012
14013        if (mForegroundProcesses.size() > 0) {
14014            synchronized (mPidsSelfLocked) {
14015                boolean printed = false;
14016                for (int i=0; i<mForegroundProcesses.size(); i++) {
14017                    ProcessRecord r = mPidsSelfLocked.get(
14018                            mForegroundProcesses.valueAt(i).pid);
14019                    if (dumpPackage != null && (r == null
14020                            || !r.pkgList.containsKey(dumpPackage))) {
14021                        continue;
14022                    }
14023                    if (!printed) {
14024                        if (needSep) pw.println();
14025                        needSep = true;
14026                        pw.println("  Foreground Processes:");
14027                        printed = true;
14028                        printedAnything = true;
14029                    }
14030                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14031                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14032                }
14033            }
14034        }
14035
14036        if (mPersistentStartingProcesses.size() > 0) {
14037            if (needSep) pw.println();
14038            needSep = true;
14039            printedAnything = true;
14040            pw.println("  Persisent processes that are starting:");
14041            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14042                    "Starting Norm", "Restarting PERS", dumpPackage);
14043        }
14044
14045        if (mRemovedProcesses.size() > 0) {
14046            if (needSep) pw.println();
14047            needSep = true;
14048            printedAnything = true;
14049            pw.println("  Processes that are being removed:");
14050            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14051                    "Removed Norm", "Removed PERS", dumpPackage);
14052        }
14053
14054        if (mProcessesOnHold.size() > 0) {
14055            if (needSep) pw.println();
14056            needSep = true;
14057            printedAnything = true;
14058            pw.println("  Processes that are on old until the system is ready:");
14059            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14060                    "OnHold Norm", "OnHold PERS", dumpPackage);
14061        }
14062
14063        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14064
14065        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14066        if (needSep) {
14067            printedAnything = true;
14068        }
14069
14070        if (dumpPackage == null) {
14071            pw.println();
14072            needSep = false;
14073            mUserController.dump(pw, dumpAll);
14074        }
14075        if (mHomeProcess != null && (dumpPackage == null
14076                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14077            if (needSep) {
14078                pw.println();
14079                needSep = false;
14080            }
14081            pw.println("  mHomeProcess: " + mHomeProcess);
14082        }
14083        if (mPreviousProcess != null && (dumpPackage == null
14084                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14085            if (needSep) {
14086                pw.println();
14087                needSep = false;
14088            }
14089            pw.println("  mPreviousProcess: " + mPreviousProcess);
14090        }
14091        if (dumpAll) {
14092            StringBuilder sb = new StringBuilder(128);
14093            sb.append("  mPreviousProcessVisibleTime: ");
14094            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14095            pw.println(sb);
14096        }
14097        if (mHeavyWeightProcess != null && (dumpPackage == null
14098                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14099            if (needSep) {
14100                pw.println();
14101                needSep = false;
14102            }
14103            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14104        }
14105        if (dumpPackage == null) {
14106            pw.println("  mConfiguration: " + mConfiguration);
14107        }
14108        if (dumpAll) {
14109            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14110            if (mCompatModePackages.getPackages().size() > 0) {
14111                boolean printed = false;
14112                for (Map.Entry<String, Integer> entry
14113                        : mCompatModePackages.getPackages().entrySet()) {
14114                    String pkg = entry.getKey();
14115                    int mode = entry.getValue();
14116                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14117                        continue;
14118                    }
14119                    if (!printed) {
14120                        pw.println("  mScreenCompatPackages:");
14121                        printed = true;
14122                    }
14123                    pw.print("    "); pw.print(pkg); pw.print(": ");
14124                            pw.print(mode); pw.println();
14125                }
14126            }
14127        }
14128        if (dumpPackage == null) {
14129            pw.println("  mWakefulness="
14130                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14131            pw.println("  mSleepTokens=" + mSleepTokens);
14132            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14133                    + lockScreenShownToString());
14134            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14135            if (mRunningVoice != null) {
14136                pw.println("  mRunningVoice=" + mRunningVoice);
14137                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14138            }
14139        }
14140        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14141                || mOrigWaitForDebugger) {
14142            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14143                    || dumpPackage.equals(mOrigDebugApp)) {
14144                if (needSep) {
14145                    pw.println();
14146                    needSep = false;
14147                }
14148                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14149                        + " mDebugTransient=" + mDebugTransient
14150                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14151            }
14152        }
14153        if (mCurAppTimeTracker != null) {
14154            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14155        }
14156        if (mMemWatchProcesses.getMap().size() > 0) {
14157            pw.println("  Mem watch processes:");
14158            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14159                    = mMemWatchProcesses.getMap();
14160            for (int i=0; i<procs.size(); i++) {
14161                final String proc = procs.keyAt(i);
14162                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14163                for (int j=0; j<uids.size(); j++) {
14164                    if (needSep) {
14165                        pw.println();
14166                        needSep = false;
14167                    }
14168                    StringBuilder sb = new StringBuilder();
14169                    sb.append("    ").append(proc).append('/');
14170                    UserHandle.formatUid(sb, uids.keyAt(j));
14171                    Pair<Long, String> val = uids.valueAt(j);
14172                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14173                    if (val.second != null) {
14174                        sb.append(", report to ").append(val.second);
14175                    }
14176                    pw.println(sb.toString());
14177                }
14178            }
14179            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14180            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14181            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14182                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14183        }
14184        if (mTrackAllocationApp != null) {
14185            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14186                if (needSep) {
14187                    pw.println();
14188                    needSep = false;
14189                }
14190                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14191            }
14192        }
14193        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14194                || mProfileFd != null) {
14195            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14196                if (needSep) {
14197                    pw.println();
14198                    needSep = false;
14199                }
14200                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14201                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14202                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14203                        + mAutoStopProfiler);
14204                pw.println("  mProfileType=" + mProfileType);
14205            }
14206        }
14207        if (mNativeDebuggingApp != null) {
14208            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14209                if (needSep) {
14210                    pw.println();
14211                    needSep = false;
14212                }
14213                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14214            }
14215        }
14216        if (dumpPackage == null) {
14217            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14218                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14219                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14220            }
14221            if (mController != null) {
14222                pw.println("  mController=" + mController
14223                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14224            }
14225            if (dumpAll) {
14226                pw.println("  Total persistent processes: " + numPers);
14227                pw.println("  mProcessesReady=" + mProcessesReady
14228                        + " mSystemReady=" + mSystemReady
14229                        + " mBooted=" + mBooted
14230                        + " mFactoryTest=" + mFactoryTest);
14231                pw.println("  mBooting=" + mBooting
14232                        + " mCallFinishBooting=" + mCallFinishBooting
14233                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14234                pw.print("  mLastPowerCheckRealtime=");
14235                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14236                        pw.println("");
14237                pw.print("  mLastPowerCheckUptime=");
14238                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14239                        pw.println("");
14240                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14241                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14242                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14243                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14244                        + " (" + mLruProcesses.size() + " total)"
14245                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14246                        + " mNumServiceProcs=" + mNumServiceProcs
14247                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14248                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14249                        + " mLastMemoryLevel" + mLastMemoryLevel
14250                        + " mLastNumProcesses" + mLastNumProcesses);
14251                long now = SystemClock.uptimeMillis();
14252                pw.print("  mLastIdleTime=");
14253                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14254                        pw.print(" mLowRamSinceLastIdle=");
14255                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14256                        pw.println();
14257            }
14258        }
14259
14260        if (!printedAnything) {
14261            pw.println("  (nothing)");
14262        }
14263    }
14264
14265    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14266            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14267        if (mProcessesToGc.size() > 0) {
14268            boolean printed = false;
14269            long now = SystemClock.uptimeMillis();
14270            for (int i=0; i<mProcessesToGc.size(); i++) {
14271                ProcessRecord proc = mProcessesToGc.get(i);
14272                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14273                    continue;
14274                }
14275                if (!printed) {
14276                    if (needSep) pw.println();
14277                    needSep = true;
14278                    pw.println("  Processes that are waiting to GC:");
14279                    printed = true;
14280                }
14281                pw.print("    Process "); pw.println(proc);
14282                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14283                        pw.print(", last gced=");
14284                        pw.print(now-proc.lastRequestedGc);
14285                        pw.print(" ms ago, last lowMem=");
14286                        pw.print(now-proc.lastLowMemory);
14287                        pw.println(" ms ago");
14288
14289            }
14290        }
14291        return needSep;
14292    }
14293
14294    void printOomLevel(PrintWriter pw, String name, int adj) {
14295        pw.print("    ");
14296        if (adj >= 0) {
14297            pw.print(' ');
14298            if (adj < 10) pw.print(' ');
14299        } else {
14300            if (adj > -10) pw.print(' ');
14301        }
14302        pw.print(adj);
14303        pw.print(": ");
14304        pw.print(name);
14305        pw.print(" (");
14306        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14307        pw.println(")");
14308    }
14309
14310    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14311            int opti, boolean dumpAll) {
14312        boolean needSep = false;
14313
14314        if (mLruProcesses.size() > 0) {
14315            if (needSep) pw.println();
14316            needSep = true;
14317            pw.println("  OOM levels:");
14318            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14319            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14320            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14321            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14322            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14323            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14324            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14325            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14326            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14327            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14328            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14329            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14330            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14331            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14332
14333            if (needSep) pw.println();
14334            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14335                    pw.print(" total, non-act at ");
14336                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14337                    pw.print(", non-svc at ");
14338                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14339                    pw.println("):");
14340            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14341            needSep = true;
14342        }
14343
14344        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14345
14346        pw.println();
14347        pw.println("  mHomeProcess: " + mHomeProcess);
14348        pw.println("  mPreviousProcess: " + mPreviousProcess);
14349        if (mHeavyWeightProcess != null) {
14350            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14351        }
14352
14353        return true;
14354    }
14355
14356    /**
14357     * There are three ways to call this:
14358     *  - no provider specified: dump all the providers
14359     *  - a flattened component name that matched an existing provider was specified as the
14360     *    first arg: dump that one provider
14361     *  - the first arg isn't the flattened component name of an existing provider:
14362     *    dump all providers whose component contains the first arg as a substring
14363     */
14364    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14365            int opti, boolean dumpAll) {
14366        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14367    }
14368
14369    static class ItemMatcher {
14370        ArrayList<ComponentName> components;
14371        ArrayList<String> strings;
14372        ArrayList<Integer> objects;
14373        boolean all;
14374
14375        ItemMatcher() {
14376            all = true;
14377        }
14378
14379        void build(String name) {
14380            ComponentName componentName = ComponentName.unflattenFromString(name);
14381            if (componentName != null) {
14382                if (components == null) {
14383                    components = new ArrayList<ComponentName>();
14384                }
14385                components.add(componentName);
14386                all = false;
14387            } else {
14388                int objectId = 0;
14389                // Not a '/' separated full component name; maybe an object ID?
14390                try {
14391                    objectId = Integer.parseInt(name, 16);
14392                    if (objects == null) {
14393                        objects = new ArrayList<Integer>();
14394                    }
14395                    objects.add(objectId);
14396                    all = false;
14397                } catch (RuntimeException e) {
14398                    // Not an integer; just do string match.
14399                    if (strings == null) {
14400                        strings = new ArrayList<String>();
14401                    }
14402                    strings.add(name);
14403                    all = false;
14404                }
14405            }
14406        }
14407
14408        int build(String[] args, int opti) {
14409            for (; opti<args.length; opti++) {
14410                String name = args[opti];
14411                if ("--".equals(name)) {
14412                    return opti+1;
14413                }
14414                build(name);
14415            }
14416            return opti;
14417        }
14418
14419        boolean match(Object object, ComponentName comp) {
14420            if (all) {
14421                return true;
14422            }
14423            if (components != null) {
14424                for (int i=0; i<components.size(); i++) {
14425                    if (components.get(i).equals(comp)) {
14426                        return true;
14427                    }
14428                }
14429            }
14430            if (objects != null) {
14431                for (int i=0; i<objects.size(); i++) {
14432                    if (System.identityHashCode(object) == objects.get(i)) {
14433                        return true;
14434                    }
14435                }
14436            }
14437            if (strings != null) {
14438                String flat = comp.flattenToString();
14439                for (int i=0; i<strings.size(); i++) {
14440                    if (flat.contains(strings.get(i))) {
14441                        return true;
14442                    }
14443                }
14444            }
14445            return false;
14446        }
14447    }
14448
14449    /**
14450     * There are three things that cmd can be:
14451     *  - a flattened component name that matches an existing activity
14452     *  - the cmd arg isn't the flattened component name of an existing activity:
14453     *    dump all activity whose component contains the cmd as a substring
14454     *  - A hex number of the ActivityRecord object instance.
14455     */
14456    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14457            int opti, boolean dumpAll) {
14458        ArrayList<ActivityRecord> activities;
14459
14460        synchronized (this) {
14461            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14462        }
14463
14464        if (activities.size() <= 0) {
14465            return false;
14466        }
14467
14468        String[] newArgs = new String[args.length - opti];
14469        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14470
14471        TaskRecord lastTask = null;
14472        boolean needSep = false;
14473        for (int i=activities.size()-1; i>=0; i--) {
14474            ActivityRecord r = activities.get(i);
14475            if (needSep) {
14476                pw.println();
14477            }
14478            needSep = true;
14479            synchronized (this) {
14480                if (lastTask != r.task) {
14481                    lastTask = r.task;
14482                    pw.print("TASK "); pw.print(lastTask.affinity);
14483                            pw.print(" id="); pw.println(lastTask.taskId);
14484                    if (dumpAll) {
14485                        lastTask.dump(pw, "  ");
14486                    }
14487                }
14488            }
14489            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14490        }
14491        return true;
14492    }
14493
14494    /**
14495     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14496     * there is a thread associated with the activity.
14497     */
14498    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14499            final ActivityRecord r, String[] args, boolean dumpAll) {
14500        String innerPrefix = prefix + "  ";
14501        synchronized (this) {
14502            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14503                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14504                    pw.print(" pid=");
14505                    if (r.app != null) pw.println(r.app.pid);
14506                    else pw.println("(not running)");
14507            if (dumpAll) {
14508                r.dump(pw, innerPrefix);
14509            }
14510        }
14511        if (r.app != null && r.app.thread != null) {
14512            // flush anything that is already in the PrintWriter since the thread is going
14513            // to write to the file descriptor directly
14514            pw.flush();
14515            try {
14516                TransferPipe tp = new TransferPipe();
14517                try {
14518                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14519                            r.appToken, innerPrefix, args);
14520                    tp.go(fd);
14521                } finally {
14522                    tp.kill();
14523                }
14524            } catch (IOException e) {
14525                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14526            } catch (RemoteException e) {
14527                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14528            }
14529        }
14530    }
14531
14532    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14533            int opti, boolean dumpAll, String dumpPackage) {
14534        boolean needSep = false;
14535        boolean onlyHistory = false;
14536        boolean printedAnything = false;
14537
14538        if ("history".equals(dumpPackage)) {
14539            if (opti < args.length && "-s".equals(args[opti])) {
14540                dumpAll = false;
14541            }
14542            onlyHistory = true;
14543            dumpPackage = null;
14544        }
14545
14546        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14547        if (!onlyHistory && dumpAll) {
14548            if (mRegisteredReceivers.size() > 0) {
14549                boolean printed = false;
14550                Iterator it = mRegisteredReceivers.values().iterator();
14551                while (it.hasNext()) {
14552                    ReceiverList r = (ReceiverList)it.next();
14553                    if (dumpPackage != null && (r.app == null ||
14554                            !dumpPackage.equals(r.app.info.packageName))) {
14555                        continue;
14556                    }
14557                    if (!printed) {
14558                        pw.println("  Registered Receivers:");
14559                        needSep = true;
14560                        printed = true;
14561                        printedAnything = true;
14562                    }
14563                    pw.print("  * "); pw.println(r);
14564                    r.dump(pw, "    ");
14565                }
14566            }
14567
14568            if (mReceiverResolver.dump(pw, needSep ?
14569                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14570                    "    ", dumpPackage, false, false)) {
14571                needSep = true;
14572                printedAnything = true;
14573            }
14574        }
14575
14576        for (BroadcastQueue q : mBroadcastQueues) {
14577            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14578            printedAnything |= needSep;
14579        }
14580
14581        needSep = true;
14582
14583        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14584            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14585                if (needSep) {
14586                    pw.println();
14587                }
14588                needSep = true;
14589                printedAnything = true;
14590                pw.print("  Sticky broadcasts for user ");
14591                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14592                StringBuilder sb = new StringBuilder(128);
14593                for (Map.Entry<String, ArrayList<Intent>> ent
14594                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14595                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14596                    if (dumpAll) {
14597                        pw.println(":");
14598                        ArrayList<Intent> intents = ent.getValue();
14599                        final int N = intents.size();
14600                        for (int i=0; i<N; i++) {
14601                            sb.setLength(0);
14602                            sb.append("    Intent: ");
14603                            intents.get(i).toShortString(sb, false, true, false, false);
14604                            pw.println(sb.toString());
14605                            Bundle bundle = intents.get(i).getExtras();
14606                            if (bundle != null) {
14607                                pw.print("      ");
14608                                pw.println(bundle.toString());
14609                            }
14610                        }
14611                    } else {
14612                        pw.println("");
14613                    }
14614                }
14615            }
14616        }
14617
14618        if (!onlyHistory && dumpAll) {
14619            pw.println();
14620            for (BroadcastQueue queue : mBroadcastQueues) {
14621                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14622                        + queue.mBroadcastsScheduled);
14623            }
14624            pw.println("  mHandler:");
14625            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14626            needSep = true;
14627            printedAnything = true;
14628        }
14629
14630        if (!printedAnything) {
14631            pw.println("  (nothing)");
14632        }
14633    }
14634
14635    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14636            int opti, boolean dumpAll, String dumpPackage) {
14637        boolean needSep;
14638        boolean printedAnything = false;
14639
14640        ItemMatcher matcher = new ItemMatcher();
14641        matcher.build(args, opti);
14642
14643        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14644
14645        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14646        printedAnything |= needSep;
14647
14648        if (mLaunchingProviders.size() > 0) {
14649            boolean printed = false;
14650            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14651                ContentProviderRecord r = mLaunchingProviders.get(i);
14652                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14653                    continue;
14654                }
14655                if (!printed) {
14656                    if (needSep) pw.println();
14657                    needSep = true;
14658                    pw.println("  Launching content providers:");
14659                    printed = true;
14660                    printedAnything = true;
14661                }
14662                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14663                        pw.println(r);
14664            }
14665        }
14666
14667        if (!printedAnything) {
14668            pw.println("  (nothing)");
14669        }
14670    }
14671
14672    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14673            int opti, boolean dumpAll, String dumpPackage) {
14674        boolean needSep = false;
14675        boolean printedAnything = false;
14676
14677        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14678
14679        if (mGrantedUriPermissions.size() > 0) {
14680            boolean printed = false;
14681            int dumpUid = -2;
14682            if (dumpPackage != null) {
14683                try {
14684                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14685                            MATCH_UNINSTALLED_PACKAGES, 0);
14686                } catch (NameNotFoundException e) {
14687                    dumpUid = -1;
14688                }
14689            }
14690            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14691                int uid = mGrantedUriPermissions.keyAt(i);
14692                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14693                    continue;
14694                }
14695                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14696                if (!printed) {
14697                    if (needSep) pw.println();
14698                    needSep = true;
14699                    pw.println("  Granted Uri Permissions:");
14700                    printed = true;
14701                    printedAnything = true;
14702                }
14703                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14704                for (UriPermission perm : perms.values()) {
14705                    pw.print("    "); pw.println(perm);
14706                    if (dumpAll) {
14707                        perm.dump(pw, "      ");
14708                    }
14709                }
14710            }
14711        }
14712
14713        if (!printedAnything) {
14714            pw.println("  (nothing)");
14715        }
14716    }
14717
14718    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14719            int opti, boolean dumpAll, String dumpPackage) {
14720        boolean printed = false;
14721
14722        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14723
14724        if (mIntentSenderRecords.size() > 0) {
14725            Iterator<WeakReference<PendingIntentRecord>> it
14726                    = mIntentSenderRecords.values().iterator();
14727            while (it.hasNext()) {
14728                WeakReference<PendingIntentRecord> ref = it.next();
14729                PendingIntentRecord rec = ref != null ? ref.get(): null;
14730                if (dumpPackage != null && (rec == null
14731                        || !dumpPackage.equals(rec.key.packageName))) {
14732                    continue;
14733                }
14734                printed = true;
14735                if (rec != null) {
14736                    pw.print("  * "); pw.println(rec);
14737                    if (dumpAll) {
14738                        rec.dump(pw, "    ");
14739                    }
14740                } else {
14741                    pw.print("  * "); pw.println(ref);
14742                }
14743            }
14744        }
14745
14746        if (!printed) {
14747            pw.println("  (nothing)");
14748        }
14749    }
14750
14751    private static final int dumpProcessList(PrintWriter pw,
14752            ActivityManagerService service, List list,
14753            String prefix, String normalLabel, String persistentLabel,
14754            String dumpPackage) {
14755        int numPers = 0;
14756        final int N = list.size()-1;
14757        for (int i=N; i>=0; i--) {
14758            ProcessRecord r = (ProcessRecord)list.get(i);
14759            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14760                continue;
14761            }
14762            pw.println(String.format("%s%s #%2d: %s",
14763                    prefix, (r.persistent ? persistentLabel : normalLabel),
14764                    i, r.toString()));
14765            if (r.persistent) {
14766                numPers++;
14767            }
14768        }
14769        return numPers;
14770    }
14771
14772    private static final boolean dumpProcessOomList(PrintWriter pw,
14773            ActivityManagerService service, List<ProcessRecord> origList,
14774            String prefix, String normalLabel, String persistentLabel,
14775            boolean inclDetails, String dumpPackage) {
14776
14777        ArrayList<Pair<ProcessRecord, Integer>> list
14778                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14779        for (int i=0; i<origList.size(); i++) {
14780            ProcessRecord r = origList.get(i);
14781            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14782                continue;
14783            }
14784            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14785        }
14786
14787        if (list.size() <= 0) {
14788            return false;
14789        }
14790
14791        Comparator<Pair<ProcessRecord, Integer>> comparator
14792                = new Comparator<Pair<ProcessRecord, Integer>>() {
14793            @Override
14794            public int compare(Pair<ProcessRecord, Integer> object1,
14795                    Pair<ProcessRecord, Integer> object2) {
14796                if (object1.first.setAdj != object2.first.setAdj) {
14797                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14798                }
14799                if (object1.first.setProcState != object2.first.setProcState) {
14800                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14801                }
14802                if (object1.second.intValue() != object2.second.intValue()) {
14803                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14804                }
14805                return 0;
14806            }
14807        };
14808
14809        Collections.sort(list, comparator);
14810
14811        final long curRealtime = SystemClock.elapsedRealtime();
14812        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14813        final long curUptime = SystemClock.uptimeMillis();
14814        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14815
14816        for (int i=list.size()-1; i>=0; i--) {
14817            ProcessRecord r = list.get(i).first;
14818            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14819            char schedGroup;
14820            switch (r.setSchedGroup) {
14821                case ProcessList.SCHED_GROUP_BACKGROUND:
14822                    schedGroup = 'B';
14823                    break;
14824                case ProcessList.SCHED_GROUP_DEFAULT:
14825                    schedGroup = 'F';
14826                    break;
14827                case ProcessList.SCHED_GROUP_TOP_APP:
14828                    schedGroup = 'T';
14829                    break;
14830                default:
14831                    schedGroup = '?';
14832                    break;
14833            }
14834            char foreground;
14835            if (r.foregroundActivities) {
14836                foreground = 'A';
14837            } else if (r.foregroundServices) {
14838                foreground = 'S';
14839            } else {
14840                foreground = ' ';
14841            }
14842            String procState = ProcessList.makeProcStateString(r.curProcState);
14843            pw.print(prefix);
14844            pw.print(r.persistent ? persistentLabel : normalLabel);
14845            pw.print(" #");
14846            int num = (origList.size()-1)-list.get(i).second;
14847            if (num < 10) pw.print(' ');
14848            pw.print(num);
14849            pw.print(": ");
14850            pw.print(oomAdj);
14851            pw.print(' ');
14852            pw.print(schedGroup);
14853            pw.print('/');
14854            pw.print(foreground);
14855            pw.print('/');
14856            pw.print(procState);
14857            pw.print(" trm:");
14858            if (r.trimMemoryLevel < 10) pw.print(' ');
14859            pw.print(r.trimMemoryLevel);
14860            pw.print(' ');
14861            pw.print(r.toShortString());
14862            pw.print(" (");
14863            pw.print(r.adjType);
14864            pw.println(')');
14865            if (r.adjSource != null || r.adjTarget != null) {
14866                pw.print(prefix);
14867                pw.print("    ");
14868                if (r.adjTarget instanceof ComponentName) {
14869                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14870                } else if (r.adjTarget != null) {
14871                    pw.print(r.adjTarget.toString());
14872                } else {
14873                    pw.print("{null}");
14874                }
14875                pw.print("<=");
14876                if (r.adjSource instanceof ProcessRecord) {
14877                    pw.print("Proc{");
14878                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14879                    pw.println("}");
14880                } else if (r.adjSource != null) {
14881                    pw.println(r.adjSource.toString());
14882                } else {
14883                    pw.println("{null}");
14884                }
14885            }
14886            if (inclDetails) {
14887                pw.print(prefix);
14888                pw.print("    ");
14889                pw.print("oom: max="); pw.print(r.maxAdj);
14890                pw.print(" curRaw="); pw.print(r.curRawAdj);
14891                pw.print(" setRaw="); pw.print(r.setRawAdj);
14892                pw.print(" cur="); pw.print(r.curAdj);
14893                pw.print(" set="); pw.println(r.setAdj);
14894                pw.print(prefix);
14895                pw.print("    ");
14896                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14897                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14898                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14899                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14900                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14901                pw.println();
14902                pw.print(prefix);
14903                pw.print("    ");
14904                pw.print("cached="); pw.print(r.cached);
14905                pw.print(" empty="); pw.print(r.empty);
14906                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14907
14908                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14909                    if (r.lastWakeTime != 0) {
14910                        long wtime;
14911                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14912                        synchronized (stats) {
14913                            wtime = stats.getProcessWakeTime(r.info.uid,
14914                                    r.pid, curRealtime);
14915                        }
14916                        long timeUsed = wtime - r.lastWakeTime;
14917                        pw.print(prefix);
14918                        pw.print("    ");
14919                        pw.print("keep awake over ");
14920                        TimeUtils.formatDuration(realtimeSince, pw);
14921                        pw.print(" used ");
14922                        TimeUtils.formatDuration(timeUsed, pw);
14923                        pw.print(" (");
14924                        pw.print((timeUsed*100)/realtimeSince);
14925                        pw.println("%)");
14926                    }
14927                    if (r.lastCpuTime != 0) {
14928                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14929                        pw.print(prefix);
14930                        pw.print("    ");
14931                        pw.print("run cpu over ");
14932                        TimeUtils.formatDuration(uptimeSince, pw);
14933                        pw.print(" used ");
14934                        TimeUtils.formatDuration(timeUsed, pw);
14935                        pw.print(" (");
14936                        pw.print((timeUsed*100)/uptimeSince);
14937                        pw.println("%)");
14938                    }
14939                }
14940            }
14941        }
14942        return true;
14943    }
14944
14945    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14946            String[] args) {
14947        ArrayList<ProcessRecord> procs;
14948        synchronized (this) {
14949            if (args != null && args.length > start
14950                    && args[start].charAt(0) != '-') {
14951                procs = new ArrayList<ProcessRecord>();
14952                int pid = -1;
14953                try {
14954                    pid = Integer.parseInt(args[start]);
14955                } catch (NumberFormatException e) {
14956                }
14957                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14958                    ProcessRecord proc = mLruProcesses.get(i);
14959                    if (proc.pid == pid) {
14960                        procs.add(proc);
14961                    } else if (allPkgs && proc.pkgList != null
14962                            && proc.pkgList.containsKey(args[start])) {
14963                        procs.add(proc);
14964                    } else if (proc.processName.equals(args[start])) {
14965                        procs.add(proc);
14966                    }
14967                }
14968                if (procs.size() <= 0) {
14969                    return null;
14970                }
14971            } else {
14972                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14973            }
14974        }
14975        return procs;
14976    }
14977
14978    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14979            PrintWriter pw, String[] args) {
14980        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14981        if (procs == null) {
14982            pw.println("No process found for: " + args[0]);
14983            return;
14984        }
14985
14986        long uptime = SystemClock.uptimeMillis();
14987        long realtime = SystemClock.elapsedRealtime();
14988        pw.println("Applications Graphics Acceleration Info:");
14989        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14990
14991        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14992            ProcessRecord r = procs.get(i);
14993            if (r.thread != null) {
14994                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14995                pw.flush();
14996                try {
14997                    TransferPipe tp = new TransferPipe();
14998                    try {
14999                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15000                        tp.go(fd);
15001                    } finally {
15002                        tp.kill();
15003                    }
15004                } catch (IOException e) {
15005                    pw.println("Failure while dumping the app: " + r);
15006                    pw.flush();
15007                } catch (RemoteException e) {
15008                    pw.println("Got a RemoteException while dumping the app " + r);
15009                    pw.flush();
15010                }
15011            }
15012        }
15013    }
15014
15015    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15016        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15017        if (procs == null) {
15018            pw.println("No process found for: " + args[0]);
15019            return;
15020        }
15021
15022        pw.println("Applications Database Info:");
15023
15024        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15025            ProcessRecord r = procs.get(i);
15026            if (r.thread != null) {
15027                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15028                pw.flush();
15029                try {
15030                    TransferPipe tp = new TransferPipe();
15031                    try {
15032                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15033                        tp.go(fd);
15034                    } finally {
15035                        tp.kill();
15036                    }
15037                } catch (IOException e) {
15038                    pw.println("Failure while dumping the app: " + r);
15039                    pw.flush();
15040                } catch (RemoteException e) {
15041                    pw.println("Got a RemoteException while dumping the app " + r);
15042                    pw.flush();
15043                }
15044            }
15045        }
15046    }
15047
15048    final static class MemItem {
15049        final boolean isProc;
15050        final String label;
15051        final String shortLabel;
15052        final long pss;
15053        final long swapPss;
15054        final int id;
15055        final boolean hasActivities;
15056        ArrayList<MemItem> subitems;
15057
15058        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15059                boolean _hasActivities) {
15060            isProc = true;
15061            label = _label;
15062            shortLabel = _shortLabel;
15063            pss = _pss;
15064            swapPss = _swapPss;
15065            id = _id;
15066            hasActivities = _hasActivities;
15067        }
15068
15069        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15070            isProc = false;
15071            label = _label;
15072            shortLabel = _shortLabel;
15073            pss = _pss;
15074            swapPss = _swapPss;
15075            id = _id;
15076            hasActivities = false;
15077        }
15078    }
15079
15080    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15081            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15082        if (sort && !isCompact) {
15083            Collections.sort(items, new Comparator<MemItem>() {
15084                @Override
15085                public int compare(MemItem lhs, MemItem rhs) {
15086                    if (lhs.pss < rhs.pss) {
15087                        return 1;
15088                    } else if (lhs.pss > rhs.pss) {
15089                        return -1;
15090                    }
15091                    return 0;
15092                }
15093            });
15094        }
15095
15096        for (int i=0; i<items.size(); i++) {
15097            MemItem mi = items.get(i);
15098            if (!isCompact) {
15099                if (dumpSwapPss) {
15100                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15101                            mi.label, stringifyKBSize(mi.swapPss));
15102                } else {
15103                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15104                }
15105            } else if (mi.isProc) {
15106                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15107                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15108                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15109                pw.println(mi.hasActivities ? ",a" : ",e");
15110            } else {
15111                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15112                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15113            }
15114            if (mi.subitems != null) {
15115                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15116                        true, isCompact, dumpSwapPss);
15117            }
15118        }
15119    }
15120
15121    // These are in KB.
15122    static final long[] DUMP_MEM_BUCKETS = new long[] {
15123        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15124        120*1024, 160*1024, 200*1024,
15125        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15126        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15127    };
15128
15129    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15130            boolean stackLike) {
15131        int start = label.lastIndexOf('.');
15132        if (start >= 0) start++;
15133        else start = 0;
15134        int end = label.length();
15135        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15136            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15137                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15138                out.append(bucket);
15139                out.append(stackLike ? "MB." : "MB ");
15140                out.append(label, start, end);
15141                return;
15142            }
15143        }
15144        out.append(memKB/1024);
15145        out.append(stackLike ? "MB." : "MB ");
15146        out.append(label, start, end);
15147    }
15148
15149    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15150            ProcessList.NATIVE_ADJ,
15151            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15152            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15153            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15154            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15155            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15156            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15157    };
15158    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15159            "Native",
15160            "System", "Persistent", "Persistent Service", "Foreground",
15161            "Visible", "Perceptible",
15162            "Heavy Weight", "Backup",
15163            "A Services", "Home",
15164            "Previous", "B Services", "Cached"
15165    };
15166    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15167            "native",
15168            "sys", "pers", "persvc", "fore",
15169            "vis", "percept",
15170            "heavy", "backup",
15171            "servicea", "home",
15172            "prev", "serviceb", "cached"
15173    };
15174
15175    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15176            long realtime, boolean isCheckinRequest, boolean isCompact) {
15177        if (isCompact) {
15178            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15179        }
15180        if (isCheckinRequest || isCompact) {
15181            // short checkin version
15182            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15183        } else {
15184            pw.println("Applications Memory Usage (in Kilobytes):");
15185            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15186        }
15187    }
15188
15189    private static final int KSM_SHARED = 0;
15190    private static final int KSM_SHARING = 1;
15191    private static final int KSM_UNSHARED = 2;
15192    private static final int KSM_VOLATILE = 3;
15193
15194    private final long[] getKsmInfo() {
15195        long[] longOut = new long[4];
15196        final int[] SINGLE_LONG_FORMAT = new int[] {
15197            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15198        };
15199        long[] longTmp = new long[1];
15200        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15201                SINGLE_LONG_FORMAT, null, longTmp, null);
15202        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15203        longTmp[0] = 0;
15204        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15205                SINGLE_LONG_FORMAT, null, longTmp, null);
15206        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15207        longTmp[0] = 0;
15208        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15209                SINGLE_LONG_FORMAT, null, longTmp, null);
15210        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15211        longTmp[0] = 0;
15212        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15213                SINGLE_LONG_FORMAT, null, longTmp, null);
15214        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15215        return longOut;
15216    }
15217
15218    private static String stringifySize(long size, int order) {
15219        Locale locale = Locale.US;
15220        switch (order) {
15221            case 1:
15222                return String.format(locale, "%,13d", size);
15223            case 1024:
15224                return String.format(locale, "%,9dK", size / 1024);
15225            case 1024 * 1024:
15226                return String.format(locale, "%,5dM", size / 1024 / 1024);
15227            case 1024 * 1024 * 1024:
15228                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15229            default:
15230                throw new IllegalArgumentException("Invalid size order");
15231        }
15232    }
15233
15234    private static String stringifyKBSize(long size) {
15235        return stringifySize(size * 1024, 1024);
15236    }
15237
15238    // Update this version number in case you change the 'compact' format
15239    private static final int MEMINFO_COMPACT_VERSION = 1;
15240
15241    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15242            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15243        boolean dumpDetails = false;
15244        boolean dumpFullDetails = false;
15245        boolean dumpDalvik = false;
15246        boolean dumpSummaryOnly = false;
15247        boolean dumpUnreachable = false;
15248        boolean oomOnly = false;
15249        boolean isCompact = false;
15250        boolean localOnly = false;
15251        boolean packages = false;
15252        boolean isCheckinRequest = false;
15253        boolean dumpSwapPss = false;
15254
15255        int opti = 0;
15256        while (opti < args.length) {
15257            String opt = args[opti];
15258            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15259                break;
15260            }
15261            opti++;
15262            if ("-a".equals(opt)) {
15263                dumpDetails = true;
15264                dumpFullDetails = true;
15265                dumpDalvik = true;
15266                dumpSwapPss = true;
15267            } else if ("-d".equals(opt)) {
15268                dumpDalvik = true;
15269            } else if ("-c".equals(opt)) {
15270                isCompact = true;
15271            } else if ("-s".equals(opt)) {
15272                dumpDetails = true;
15273                dumpSummaryOnly = true;
15274            } else if ("-S".equals(opt)) {
15275                dumpSwapPss = true;
15276            } else if ("--unreachable".equals(opt)) {
15277                dumpUnreachable = true;
15278            } else if ("--oom".equals(opt)) {
15279                oomOnly = true;
15280            } else if ("--local".equals(opt)) {
15281                localOnly = true;
15282            } else if ("--package".equals(opt)) {
15283                packages = true;
15284            } else if ("--checkin".equals(opt)) {
15285                isCheckinRequest = true;
15286
15287            } else if ("-h".equals(opt)) {
15288                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15289                pw.println("  -a: include all available information for each process.");
15290                pw.println("  -d: include dalvik details.");
15291                pw.println("  -c: dump in a compact machine-parseable representation.");
15292                pw.println("  -s: dump only summary of application memory usage.");
15293                pw.println("  -S: dump also SwapPss.");
15294                pw.println("  --oom: only show processes organized by oom adj.");
15295                pw.println("  --local: only collect details locally, don't call process.");
15296                pw.println("  --package: interpret process arg as package, dumping all");
15297                pw.println("             processes that have loaded that package.");
15298                pw.println("  --checkin: dump data for a checkin");
15299                pw.println("If [process] is specified it can be the name or ");
15300                pw.println("pid of a specific process to dump.");
15301                return;
15302            } else {
15303                pw.println("Unknown argument: " + opt + "; use -h for help");
15304            }
15305        }
15306
15307        long uptime = SystemClock.uptimeMillis();
15308        long realtime = SystemClock.elapsedRealtime();
15309        final long[] tmpLong = new long[1];
15310
15311        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15312        if (procs == null) {
15313            // No Java processes.  Maybe they want to print a native process.
15314            if (args != null && args.length > opti
15315                    && args[opti].charAt(0) != '-') {
15316                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15317                        = new ArrayList<ProcessCpuTracker.Stats>();
15318                updateCpuStatsNow();
15319                int findPid = -1;
15320                try {
15321                    findPid = Integer.parseInt(args[opti]);
15322                } catch (NumberFormatException e) {
15323                }
15324                synchronized (mProcessCpuTracker) {
15325                    final int N = mProcessCpuTracker.countStats();
15326                    for (int i=0; i<N; i++) {
15327                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15328                        if (st.pid == findPid || (st.baseName != null
15329                                && st.baseName.equals(args[opti]))) {
15330                            nativeProcs.add(st);
15331                        }
15332                    }
15333                }
15334                if (nativeProcs.size() > 0) {
15335                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15336                            isCompact);
15337                    Debug.MemoryInfo mi = null;
15338                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15339                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15340                        final int pid = r.pid;
15341                        if (!isCheckinRequest && dumpDetails) {
15342                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15343                        }
15344                        if (mi == null) {
15345                            mi = new Debug.MemoryInfo();
15346                        }
15347                        if (dumpDetails || (!brief && !oomOnly)) {
15348                            Debug.getMemoryInfo(pid, mi);
15349                        } else {
15350                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15351                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15352                        }
15353                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15354                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15355                        if (isCheckinRequest) {
15356                            pw.println();
15357                        }
15358                    }
15359                    return;
15360                }
15361            }
15362            pw.println("No process found for: " + args[opti]);
15363            return;
15364        }
15365
15366        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15367            dumpDetails = true;
15368        }
15369
15370        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15371
15372        String[] innerArgs = new String[args.length-opti];
15373        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15374
15375        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15376        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15377        long nativePss = 0;
15378        long nativeSwapPss = 0;
15379        long dalvikPss = 0;
15380        long dalvikSwapPss = 0;
15381        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15382                EmptyArray.LONG;
15383        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15384                EmptyArray.LONG;
15385        long otherPss = 0;
15386        long otherSwapPss = 0;
15387        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15388        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15389
15390        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15391        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15392        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15393                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15394
15395        long totalPss = 0;
15396        long totalSwapPss = 0;
15397        long cachedPss = 0;
15398        long cachedSwapPss = 0;
15399        boolean hasSwapPss = false;
15400
15401        Debug.MemoryInfo mi = null;
15402        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15403            final ProcessRecord r = procs.get(i);
15404            final IApplicationThread thread;
15405            final int pid;
15406            final int oomAdj;
15407            final boolean hasActivities;
15408            synchronized (this) {
15409                thread = r.thread;
15410                pid = r.pid;
15411                oomAdj = r.getSetAdjWithServices();
15412                hasActivities = r.activities.size() > 0;
15413            }
15414            if (thread != null) {
15415                if (!isCheckinRequest && dumpDetails) {
15416                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15417                }
15418                if (mi == null) {
15419                    mi = new Debug.MemoryInfo();
15420                }
15421                if (dumpDetails || (!brief && !oomOnly)) {
15422                    Debug.getMemoryInfo(pid, mi);
15423                    hasSwapPss = mi.hasSwappedOutPss;
15424                } else {
15425                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15426                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15427                }
15428                if (dumpDetails) {
15429                    if (localOnly) {
15430                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15431                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15432                        if (isCheckinRequest) {
15433                            pw.println();
15434                        }
15435                    } else {
15436                        try {
15437                            pw.flush();
15438                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15439                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15440                        } catch (RemoteException e) {
15441                            if (!isCheckinRequest) {
15442                                pw.println("Got RemoteException!");
15443                                pw.flush();
15444                            }
15445                        }
15446                    }
15447                }
15448
15449                final long myTotalPss = mi.getTotalPss();
15450                final long myTotalUss = mi.getTotalUss();
15451                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15452
15453                synchronized (this) {
15454                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15455                        // Record this for posterity if the process has been stable.
15456                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15457                    }
15458                }
15459
15460                if (!isCheckinRequest && mi != null) {
15461                    totalPss += myTotalPss;
15462                    totalSwapPss += myTotalSwapPss;
15463                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15464                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15465                            myTotalSwapPss, pid, hasActivities);
15466                    procMems.add(pssItem);
15467                    procMemsMap.put(pid, pssItem);
15468
15469                    nativePss += mi.nativePss;
15470                    nativeSwapPss += mi.nativeSwappedOutPss;
15471                    dalvikPss += mi.dalvikPss;
15472                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15473                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15474                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15475                        dalvikSubitemSwapPss[j] +=
15476                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15477                    }
15478                    otherPss += mi.otherPss;
15479                    otherSwapPss += mi.otherSwappedOutPss;
15480                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15481                        long mem = mi.getOtherPss(j);
15482                        miscPss[j] += mem;
15483                        otherPss -= mem;
15484                        mem = mi.getOtherSwappedOutPss(j);
15485                        miscSwapPss[j] += mem;
15486                        otherSwapPss -= mem;
15487                    }
15488
15489                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15490                        cachedPss += myTotalPss;
15491                        cachedSwapPss += myTotalSwapPss;
15492                    }
15493
15494                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15495                        if (oomIndex == (oomPss.length - 1)
15496                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15497                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15498                            oomPss[oomIndex] += myTotalPss;
15499                            oomSwapPss[oomIndex] += myTotalSwapPss;
15500                            if (oomProcs[oomIndex] == null) {
15501                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15502                            }
15503                            oomProcs[oomIndex].add(pssItem);
15504                            break;
15505                        }
15506                    }
15507                }
15508            }
15509        }
15510
15511        long nativeProcTotalPss = 0;
15512
15513        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15514            // If we are showing aggregations, also look for native processes to
15515            // include so that our aggregations are more accurate.
15516            updateCpuStatsNow();
15517            mi = null;
15518            synchronized (mProcessCpuTracker) {
15519                final int N = mProcessCpuTracker.countStats();
15520                for (int i=0; i<N; i++) {
15521                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15522                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15523                        if (mi == null) {
15524                            mi = new Debug.MemoryInfo();
15525                        }
15526                        if (!brief && !oomOnly) {
15527                            Debug.getMemoryInfo(st.pid, mi);
15528                        } else {
15529                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15530                            mi.nativePrivateDirty = (int)tmpLong[0];
15531                        }
15532
15533                        final long myTotalPss = mi.getTotalPss();
15534                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15535                        totalPss += myTotalPss;
15536                        nativeProcTotalPss += myTotalPss;
15537
15538                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15539                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15540                        procMems.add(pssItem);
15541
15542                        nativePss += mi.nativePss;
15543                        nativeSwapPss += mi.nativeSwappedOutPss;
15544                        dalvikPss += mi.dalvikPss;
15545                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15546                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15547                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15548                            dalvikSubitemSwapPss[j] +=
15549                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15550                        }
15551                        otherPss += mi.otherPss;
15552                        otherSwapPss += mi.otherSwappedOutPss;
15553                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15554                            long mem = mi.getOtherPss(j);
15555                            miscPss[j] += mem;
15556                            otherPss -= mem;
15557                            mem = mi.getOtherSwappedOutPss(j);
15558                            miscSwapPss[j] += mem;
15559                            otherSwapPss -= mem;
15560                        }
15561                        oomPss[0] += myTotalPss;
15562                        oomSwapPss[0] += myTotalSwapPss;
15563                        if (oomProcs[0] == null) {
15564                            oomProcs[0] = new ArrayList<MemItem>();
15565                        }
15566                        oomProcs[0].add(pssItem);
15567                    }
15568                }
15569            }
15570
15571            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15572
15573            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15574            final MemItem dalvikItem =
15575                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15576            if (dalvikSubitemPss.length > 0) {
15577                dalvikItem.subitems = new ArrayList<MemItem>();
15578                for (int j=0; j<dalvikSubitemPss.length; j++) {
15579                    final String name = Debug.MemoryInfo.getOtherLabel(
15580                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15581                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15582                                    dalvikSubitemSwapPss[j], j));
15583                }
15584            }
15585            catMems.add(dalvikItem);
15586            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15587            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15588                String label = Debug.MemoryInfo.getOtherLabel(j);
15589                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15590            }
15591
15592            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15593            for (int j=0; j<oomPss.length; j++) {
15594                if (oomPss[j] != 0) {
15595                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15596                            : DUMP_MEM_OOM_LABEL[j];
15597                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15598                            DUMP_MEM_OOM_ADJ[j]);
15599                    item.subitems = oomProcs[j];
15600                    oomMems.add(item);
15601                }
15602            }
15603
15604            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15605            if (!brief && !oomOnly && !isCompact) {
15606                pw.println();
15607                pw.println("Total PSS by process:");
15608                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15609                pw.println();
15610            }
15611            if (!isCompact) {
15612                pw.println("Total PSS by OOM adjustment:");
15613            }
15614            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15615            if (!brief && !oomOnly) {
15616                PrintWriter out = categoryPw != null ? categoryPw : pw;
15617                if (!isCompact) {
15618                    out.println();
15619                    out.println("Total PSS by category:");
15620                }
15621                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15622            }
15623            if (!isCompact) {
15624                pw.println();
15625            }
15626            MemInfoReader memInfo = new MemInfoReader();
15627            memInfo.readMemInfo();
15628            if (nativeProcTotalPss > 0) {
15629                synchronized (this) {
15630                    final long cachedKb = memInfo.getCachedSizeKb();
15631                    final long freeKb = memInfo.getFreeSizeKb();
15632                    final long zramKb = memInfo.getZramTotalSizeKb();
15633                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15634                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15635                            kernelKb*1024, nativeProcTotalPss*1024);
15636                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15637                            nativeProcTotalPss);
15638                }
15639            }
15640            if (!brief) {
15641                if (!isCompact) {
15642                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15643                    pw.print(" (status ");
15644                    switch (mLastMemoryLevel) {
15645                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15646                            pw.println("normal)");
15647                            break;
15648                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15649                            pw.println("moderate)");
15650                            break;
15651                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15652                            pw.println("low)");
15653                            break;
15654                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15655                            pw.println("critical)");
15656                            break;
15657                        default:
15658                            pw.print(mLastMemoryLevel);
15659                            pw.println(")");
15660                            break;
15661                    }
15662                    pw.print(" Free RAM: ");
15663                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15664                            + memInfo.getFreeSizeKb()));
15665                    pw.print(" (");
15666                    pw.print(stringifyKBSize(cachedPss));
15667                    pw.print(" cached pss + ");
15668                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15669                    pw.print(" cached kernel + ");
15670                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15671                    pw.println(" free)");
15672                } else {
15673                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15674                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15675                            + memInfo.getFreeSizeKb()); pw.print(",");
15676                    pw.println(totalPss - cachedPss);
15677                }
15678            }
15679            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15680                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15681                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15682            if (!isCompact) {
15683                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15684                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15685                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15686                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15687                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15688            } else {
15689                pw.print("lostram,"); pw.println(lostRAM);
15690            }
15691            if (!brief) {
15692                if (memInfo.getZramTotalSizeKb() != 0) {
15693                    if (!isCompact) {
15694                        pw.print("     ZRAM: ");
15695                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15696                                pw.print(" physical used for ");
15697                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15698                                        - memInfo.getSwapFreeSizeKb()));
15699                                pw.print(" in swap (");
15700                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15701                                pw.println(" total swap)");
15702                    } else {
15703                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15704                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15705                                pw.println(memInfo.getSwapFreeSizeKb());
15706                    }
15707                }
15708                final long[] ksm = getKsmInfo();
15709                if (!isCompact) {
15710                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15711                            || ksm[KSM_VOLATILE] != 0) {
15712                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15713                                pw.print(" saved from shared ");
15714                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15715                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15716                                pw.print(" unshared; ");
15717                                pw.print(stringifyKBSize(
15718                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15719                    }
15720                    pw.print("   Tuning: ");
15721                    pw.print(ActivityManager.staticGetMemoryClass());
15722                    pw.print(" (large ");
15723                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15724                    pw.print("), oom ");
15725                    pw.print(stringifySize(
15726                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15727                    pw.print(", restore limit ");
15728                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15729                    if (ActivityManager.isLowRamDeviceStatic()) {
15730                        pw.print(" (low-ram)");
15731                    }
15732                    if (ActivityManager.isHighEndGfx()) {
15733                        pw.print(" (high-end-gfx)");
15734                    }
15735                    pw.println();
15736                } else {
15737                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15738                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15739                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15740                    pw.print("tuning,");
15741                    pw.print(ActivityManager.staticGetMemoryClass());
15742                    pw.print(',');
15743                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15744                    pw.print(',');
15745                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15746                    if (ActivityManager.isLowRamDeviceStatic()) {
15747                        pw.print(",low-ram");
15748                    }
15749                    if (ActivityManager.isHighEndGfx()) {
15750                        pw.print(",high-end-gfx");
15751                    }
15752                    pw.println();
15753                }
15754            }
15755        }
15756    }
15757
15758    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15759            long memtrack, String name) {
15760        sb.append("  ");
15761        sb.append(ProcessList.makeOomAdjString(oomAdj));
15762        sb.append(' ');
15763        sb.append(ProcessList.makeProcStateString(procState));
15764        sb.append(' ');
15765        ProcessList.appendRamKb(sb, pss);
15766        sb.append(": ");
15767        sb.append(name);
15768        if (memtrack > 0) {
15769            sb.append(" (");
15770            sb.append(stringifyKBSize(memtrack));
15771            sb.append(" memtrack)");
15772        }
15773    }
15774
15775    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15776        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15777        sb.append(" (pid ");
15778        sb.append(mi.pid);
15779        sb.append(") ");
15780        sb.append(mi.adjType);
15781        sb.append('\n');
15782        if (mi.adjReason != null) {
15783            sb.append("                      ");
15784            sb.append(mi.adjReason);
15785            sb.append('\n');
15786        }
15787    }
15788
15789    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15790        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15791        for (int i=0, N=memInfos.size(); i<N; i++) {
15792            ProcessMemInfo mi = memInfos.get(i);
15793            infoMap.put(mi.pid, mi);
15794        }
15795        updateCpuStatsNow();
15796        long[] memtrackTmp = new long[1];
15797        synchronized (mProcessCpuTracker) {
15798            final int N = mProcessCpuTracker.countStats();
15799            for (int i=0; i<N; i++) {
15800                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15801                if (st.vsize > 0) {
15802                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15803                    if (pss > 0) {
15804                        if (infoMap.indexOfKey(st.pid) < 0) {
15805                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15806                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15807                            mi.pss = pss;
15808                            mi.memtrack = memtrackTmp[0];
15809                            memInfos.add(mi);
15810                        }
15811                    }
15812                }
15813            }
15814        }
15815
15816        long totalPss = 0;
15817        long totalMemtrack = 0;
15818        for (int i=0, N=memInfos.size(); i<N; i++) {
15819            ProcessMemInfo mi = memInfos.get(i);
15820            if (mi.pss == 0) {
15821                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15822                mi.memtrack = memtrackTmp[0];
15823            }
15824            totalPss += mi.pss;
15825            totalMemtrack += mi.memtrack;
15826        }
15827        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15828            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15829                if (lhs.oomAdj != rhs.oomAdj) {
15830                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15831                }
15832                if (lhs.pss != rhs.pss) {
15833                    return lhs.pss < rhs.pss ? 1 : -1;
15834                }
15835                return 0;
15836            }
15837        });
15838
15839        StringBuilder tag = new StringBuilder(128);
15840        StringBuilder stack = new StringBuilder(128);
15841        tag.append("Low on memory -- ");
15842        appendMemBucket(tag, totalPss, "total", false);
15843        appendMemBucket(stack, totalPss, "total", true);
15844
15845        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15846        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15847        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15848
15849        boolean firstLine = true;
15850        int lastOomAdj = Integer.MIN_VALUE;
15851        long extraNativeRam = 0;
15852        long extraNativeMemtrack = 0;
15853        long cachedPss = 0;
15854        for (int i=0, N=memInfos.size(); i<N; i++) {
15855            ProcessMemInfo mi = memInfos.get(i);
15856
15857            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15858                cachedPss += mi.pss;
15859            }
15860
15861            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15862                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15863                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15864                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15865                if (lastOomAdj != mi.oomAdj) {
15866                    lastOomAdj = mi.oomAdj;
15867                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15868                        tag.append(" / ");
15869                    }
15870                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15871                        if (firstLine) {
15872                            stack.append(":");
15873                            firstLine = false;
15874                        }
15875                        stack.append("\n\t at ");
15876                    } else {
15877                        stack.append("$");
15878                    }
15879                } else {
15880                    tag.append(" ");
15881                    stack.append("$");
15882                }
15883                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15884                    appendMemBucket(tag, mi.pss, mi.name, false);
15885                }
15886                appendMemBucket(stack, mi.pss, mi.name, true);
15887                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15888                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15889                    stack.append("(");
15890                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15891                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15892                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15893                            stack.append(":");
15894                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15895                        }
15896                    }
15897                    stack.append(")");
15898                }
15899            }
15900
15901            appendMemInfo(fullNativeBuilder, mi);
15902            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15903                // The short form only has native processes that are >= 512K.
15904                if (mi.pss >= 512) {
15905                    appendMemInfo(shortNativeBuilder, mi);
15906                } else {
15907                    extraNativeRam += mi.pss;
15908                    extraNativeMemtrack += mi.memtrack;
15909                }
15910            } else {
15911                // Short form has all other details, but if we have collected RAM
15912                // from smaller native processes let's dump a summary of that.
15913                if (extraNativeRam > 0) {
15914                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15915                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15916                    shortNativeBuilder.append('\n');
15917                    extraNativeRam = 0;
15918                }
15919                appendMemInfo(fullJavaBuilder, mi);
15920            }
15921        }
15922
15923        fullJavaBuilder.append("           ");
15924        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15925        fullJavaBuilder.append(": TOTAL");
15926        if (totalMemtrack > 0) {
15927            fullJavaBuilder.append(" (");
15928            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15929            fullJavaBuilder.append(" memtrack)");
15930        } else {
15931        }
15932        fullJavaBuilder.append("\n");
15933
15934        MemInfoReader memInfo = new MemInfoReader();
15935        memInfo.readMemInfo();
15936        final long[] infos = memInfo.getRawInfo();
15937
15938        StringBuilder memInfoBuilder = new StringBuilder(1024);
15939        Debug.getMemInfo(infos);
15940        memInfoBuilder.append("  MemInfo: ");
15941        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15942        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15943        memInfoBuilder.append(stringifyKBSize(
15944                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15945        memInfoBuilder.append(stringifyKBSize(
15946                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15947        memInfoBuilder.append(stringifyKBSize(
15948                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15949        memInfoBuilder.append("           ");
15950        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15951        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15952        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15953        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15954        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15955            memInfoBuilder.append("  ZRAM: ");
15956            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15957            memInfoBuilder.append(" RAM, ");
15958            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15959            memInfoBuilder.append(" swap total, ");
15960            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15961            memInfoBuilder.append(" swap free\n");
15962        }
15963        final long[] ksm = getKsmInfo();
15964        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15965                || ksm[KSM_VOLATILE] != 0) {
15966            memInfoBuilder.append("  KSM: ");
15967            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15968            memInfoBuilder.append(" saved from shared ");
15969            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15970            memInfoBuilder.append("\n       ");
15971            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15972            memInfoBuilder.append(" unshared; ");
15973            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15974            memInfoBuilder.append(" volatile\n");
15975        }
15976        memInfoBuilder.append("  Free RAM: ");
15977        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15978                + memInfo.getFreeSizeKb()));
15979        memInfoBuilder.append("\n");
15980        memInfoBuilder.append("  Used RAM: ");
15981        memInfoBuilder.append(stringifyKBSize(
15982                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15983        memInfoBuilder.append("\n");
15984        memInfoBuilder.append("  Lost RAM: ");
15985        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15986                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15987                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
15988        memInfoBuilder.append("\n");
15989        Slog.i(TAG, "Low on memory:");
15990        Slog.i(TAG, shortNativeBuilder.toString());
15991        Slog.i(TAG, fullJavaBuilder.toString());
15992        Slog.i(TAG, memInfoBuilder.toString());
15993
15994        StringBuilder dropBuilder = new StringBuilder(1024);
15995        /*
15996        StringWriter oomSw = new StringWriter();
15997        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15998        StringWriter catSw = new StringWriter();
15999        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16000        String[] emptyArgs = new String[] { };
16001        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16002        oomPw.flush();
16003        String oomString = oomSw.toString();
16004        */
16005        dropBuilder.append("Low on memory:");
16006        dropBuilder.append(stack);
16007        dropBuilder.append('\n');
16008        dropBuilder.append(fullNativeBuilder);
16009        dropBuilder.append(fullJavaBuilder);
16010        dropBuilder.append('\n');
16011        dropBuilder.append(memInfoBuilder);
16012        dropBuilder.append('\n');
16013        /*
16014        dropBuilder.append(oomString);
16015        dropBuilder.append('\n');
16016        */
16017        StringWriter catSw = new StringWriter();
16018        synchronized (ActivityManagerService.this) {
16019            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16020            String[] emptyArgs = new String[] { };
16021            catPw.println();
16022            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16023            catPw.println();
16024            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16025                    false, false, null);
16026            catPw.println();
16027            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16028            catPw.flush();
16029        }
16030        dropBuilder.append(catSw.toString());
16031        addErrorToDropBox("lowmem", null, "system_server", null,
16032                null, tag.toString(), dropBuilder.toString(), null, null);
16033        //Slog.i(TAG, "Sent to dropbox:");
16034        //Slog.i(TAG, dropBuilder.toString());
16035        synchronized (ActivityManagerService.this) {
16036            long now = SystemClock.uptimeMillis();
16037            if (mLastMemUsageReportTime < now) {
16038                mLastMemUsageReportTime = now;
16039            }
16040        }
16041    }
16042
16043    /**
16044     * Searches array of arguments for the specified string
16045     * @param args array of argument strings
16046     * @param value value to search for
16047     * @return true if the value is contained in the array
16048     */
16049    private static boolean scanArgs(String[] args, String value) {
16050        if (args != null) {
16051            for (String arg : args) {
16052                if (value.equals(arg)) {
16053                    return true;
16054                }
16055            }
16056        }
16057        return false;
16058    }
16059
16060    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16061            ContentProviderRecord cpr, boolean always) {
16062        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16063
16064        if (!inLaunching || always) {
16065            synchronized (cpr) {
16066                cpr.launchingApp = null;
16067                cpr.notifyAll();
16068            }
16069            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16070            String names[] = cpr.info.authority.split(";");
16071            for (int j = 0; j < names.length; j++) {
16072                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16073            }
16074        }
16075
16076        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16077            ContentProviderConnection conn = cpr.connections.get(i);
16078            if (conn.waiting) {
16079                // If this connection is waiting for the provider, then we don't
16080                // need to mess with its process unless we are always removing
16081                // or for some reason the provider is not currently launching.
16082                if (inLaunching && !always) {
16083                    continue;
16084                }
16085            }
16086            ProcessRecord capp = conn.client;
16087            conn.dead = true;
16088            if (conn.stableCount > 0) {
16089                if (!capp.persistent && capp.thread != null
16090                        && capp.pid != 0
16091                        && capp.pid != MY_PID) {
16092                    capp.kill("depends on provider "
16093                            + cpr.name.flattenToShortString()
16094                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16095                }
16096            } else if (capp.thread != null && conn.provider.provider != null) {
16097                try {
16098                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16099                } catch (RemoteException e) {
16100                }
16101                // In the protocol here, we don't expect the client to correctly
16102                // clean up this connection, we'll just remove it.
16103                cpr.connections.remove(i);
16104                if (conn.client.conProviders.remove(conn)) {
16105                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16106                }
16107            }
16108        }
16109
16110        if (inLaunching && always) {
16111            mLaunchingProviders.remove(cpr);
16112        }
16113        return inLaunching;
16114    }
16115
16116    /**
16117     * Main code for cleaning up a process when it has gone away.  This is
16118     * called both as a result of the process dying, or directly when stopping
16119     * a process when running in single process mode.
16120     *
16121     * @return Returns true if the given process has been restarted, so the
16122     * app that was passed in must remain on the process lists.
16123     */
16124    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16125            boolean restarting, boolean allowRestart, int index) {
16126        if (index >= 0) {
16127            removeLruProcessLocked(app);
16128            ProcessList.remove(app.pid);
16129        }
16130
16131        mProcessesToGc.remove(app);
16132        mPendingPssProcesses.remove(app);
16133
16134        // Dismiss any open dialogs.
16135        if (app.crashDialog != null && !app.forceCrashReport) {
16136            app.crashDialog.dismiss();
16137            app.crashDialog = null;
16138        }
16139        if (app.anrDialog != null) {
16140            app.anrDialog.dismiss();
16141            app.anrDialog = null;
16142        }
16143        if (app.waitDialog != null) {
16144            app.waitDialog.dismiss();
16145            app.waitDialog = null;
16146        }
16147
16148        app.crashing = false;
16149        app.notResponding = false;
16150
16151        app.resetPackageList(mProcessStats);
16152        app.unlinkDeathRecipient();
16153        app.makeInactive(mProcessStats);
16154        app.waitingToKill = null;
16155        app.forcingToForeground = null;
16156        updateProcessForegroundLocked(app, false, false);
16157        app.foregroundActivities = false;
16158        app.hasShownUi = false;
16159        app.treatLikeActivity = false;
16160        app.hasAboveClient = false;
16161        app.hasClientActivities = false;
16162
16163        mServices.killServicesLocked(app, allowRestart);
16164
16165        boolean restart = false;
16166
16167        // Remove published content providers.
16168        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16169            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16170            final boolean always = app.bad || !allowRestart;
16171            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16172            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16173                // We left the provider in the launching list, need to
16174                // restart it.
16175                restart = true;
16176            }
16177
16178            cpr.provider = null;
16179            cpr.proc = null;
16180        }
16181        app.pubProviders.clear();
16182
16183        // Take care of any launching providers waiting for this process.
16184        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16185            restart = true;
16186        }
16187
16188        // Unregister from connected content providers.
16189        if (!app.conProviders.isEmpty()) {
16190            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16191                ContentProviderConnection conn = app.conProviders.get(i);
16192                conn.provider.connections.remove(conn);
16193                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16194                        conn.provider.name);
16195            }
16196            app.conProviders.clear();
16197        }
16198
16199        // At this point there may be remaining entries in mLaunchingProviders
16200        // where we were the only one waiting, so they are no longer of use.
16201        // Look for these and clean up if found.
16202        // XXX Commented out for now.  Trying to figure out a way to reproduce
16203        // the actual situation to identify what is actually going on.
16204        if (false) {
16205            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16206                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16207                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16208                    synchronized (cpr) {
16209                        cpr.launchingApp = null;
16210                        cpr.notifyAll();
16211                    }
16212                }
16213            }
16214        }
16215
16216        skipCurrentReceiverLocked(app);
16217
16218        // Unregister any receivers.
16219        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16220            removeReceiverLocked(app.receivers.valueAt(i));
16221        }
16222        app.receivers.clear();
16223
16224        // If the app is undergoing backup, tell the backup manager about it
16225        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16226            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16227                    + mBackupTarget.appInfo + " died during backup");
16228            try {
16229                IBackupManager bm = IBackupManager.Stub.asInterface(
16230                        ServiceManager.getService(Context.BACKUP_SERVICE));
16231                bm.agentDisconnected(app.info.packageName);
16232            } catch (RemoteException e) {
16233                // can't happen; backup manager is local
16234            }
16235        }
16236
16237        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16238            ProcessChangeItem item = mPendingProcessChanges.get(i);
16239            if (item.pid == app.pid) {
16240                mPendingProcessChanges.remove(i);
16241                mAvailProcessChanges.add(item);
16242            }
16243        }
16244        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16245                null).sendToTarget();
16246
16247        // If the caller is restarting this app, then leave it in its
16248        // current lists and let the caller take care of it.
16249        if (restarting) {
16250            return false;
16251        }
16252
16253        if (!app.persistent || app.isolated) {
16254            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16255                    "Removing non-persistent process during cleanup: " + app);
16256            removeProcessNameLocked(app.processName, app.uid);
16257            if (mHeavyWeightProcess == app) {
16258                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16259                        mHeavyWeightProcess.userId, 0));
16260                mHeavyWeightProcess = null;
16261            }
16262        } else if (!app.removed) {
16263            // This app is persistent, so we need to keep its record around.
16264            // If it is not already on the pending app list, add it there
16265            // and start a new process for it.
16266            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16267                mPersistentStartingProcesses.add(app);
16268                restart = true;
16269            }
16270        }
16271        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16272                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16273        mProcessesOnHold.remove(app);
16274
16275        if (app == mHomeProcess) {
16276            mHomeProcess = null;
16277        }
16278        if (app == mPreviousProcess) {
16279            mPreviousProcess = null;
16280        }
16281
16282        if (restart && !app.isolated) {
16283            // We have components that still need to be running in the
16284            // process, so re-launch it.
16285            if (index < 0) {
16286                ProcessList.remove(app.pid);
16287            }
16288            addProcessNameLocked(app);
16289            startProcessLocked(app, "restart", app.processName);
16290            return true;
16291        } else if (app.pid > 0 && app.pid != MY_PID) {
16292            // Goodbye!
16293            boolean removed;
16294            synchronized (mPidsSelfLocked) {
16295                mPidsSelfLocked.remove(app.pid);
16296                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16297            }
16298            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16299            if (app.isolated) {
16300                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16301            }
16302            app.setPid(0);
16303        }
16304        return false;
16305    }
16306
16307    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16308        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16309            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16310            if (cpr.launchingApp == app) {
16311                return true;
16312            }
16313        }
16314        return false;
16315    }
16316
16317    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16318        // Look through the content providers we are waiting to have launched,
16319        // and if any run in this process then either schedule a restart of
16320        // the process or kill the client waiting for it if this process has
16321        // gone bad.
16322        boolean restart = false;
16323        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16324            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16325            if (cpr.launchingApp == app) {
16326                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16327                    restart = true;
16328                } else {
16329                    removeDyingProviderLocked(app, cpr, true);
16330                }
16331            }
16332        }
16333        return restart;
16334    }
16335
16336    // =========================================================
16337    // SERVICES
16338    // =========================================================
16339
16340    @Override
16341    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16342            int flags) {
16343        enforceNotIsolatedCaller("getServices");
16344        synchronized (this) {
16345            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16346        }
16347    }
16348
16349    @Override
16350    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16351        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16352        synchronized (this) {
16353            return mServices.getRunningServiceControlPanelLocked(name);
16354        }
16355    }
16356
16357    @Override
16358    public ComponentName startService(IApplicationThread caller, Intent service,
16359            String resolvedType, String callingPackage, int userId)
16360            throws TransactionTooLargeException {
16361        enforceNotIsolatedCaller("startService");
16362        // Refuse possible leaked file descriptors
16363        if (service != null && service.hasFileDescriptors() == true) {
16364            throw new IllegalArgumentException("File descriptors passed in Intent");
16365        }
16366
16367        if (callingPackage == null) {
16368            throw new IllegalArgumentException("callingPackage cannot be null");
16369        }
16370
16371        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16372                "startService: " + service + " type=" + resolvedType);
16373        synchronized(this) {
16374            final int callingPid = Binder.getCallingPid();
16375            final int callingUid = Binder.getCallingUid();
16376            final long origId = Binder.clearCallingIdentity();
16377            ComponentName res = mServices.startServiceLocked(caller, service,
16378                    resolvedType, callingPid, callingUid, callingPackage, userId);
16379            Binder.restoreCallingIdentity(origId);
16380            return res;
16381        }
16382    }
16383
16384    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16385            String callingPackage, int userId)
16386            throws TransactionTooLargeException {
16387        synchronized(this) {
16388            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16389                    "startServiceInPackage: " + service + " type=" + resolvedType);
16390            final long origId = Binder.clearCallingIdentity();
16391            ComponentName res = mServices.startServiceLocked(null, service,
16392                    resolvedType, -1, uid, callingPackage, userId);
16393            Binder.restoreCallingIdentity(origId);
16394            return res;
16395        }
16396    }
16397
16398    @Override
16399    public int stopService(IApplicationThread caller, Intent service,
16400            String resolvedType, int userId) {
16401        enforceNotIsolatedCaller("stopService");
16402        // Refuse possible leaked file descriptors
16403        if (service != null && service.hasFileDescriptors() == true) {
16404            throw new IllegalArgumentException("File descriptors passed in Intent");
16405        }
16406
16407        synchronized(this) {
16408            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16409        }
16410    }
16411
16412    @Override
16413    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16414        enforceNotIsolatedCaller("peekService");
16415        // Refuse possible leaked file descriptors
16416        if (service != null && service.hasFileDescriptors() == true) {
16417            throw new IllegalArgumentException("File descriptors passed in Intent");
16418        }
16419
16420        if (callingPackage == null) {
16421            throw new IllegalArgumentException("callingPackage cannot be null");
16422        }
16423
16424        synchronized(this) {
16425            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16426        }
16427    }
16428
16429    @Override
16430    public boolean stopServiceToken(ComponentName className, IBinder token,
16431            int startId) {
16432        synchronized(this) {
16433            return mServices.stopServiceTokenLocked(className, token, startId);
16434        }
16435    }
16436
16437    @Override
16438    public void setServiceForeground(ComponentName className, IBinder token,
16439            int id, Notification notification, boolean removeNotification) {
16440        synchronized(this) {
16441            mServices.setServiceForegroundLocked(className, token, id, notification,
16442                    removeNotification);
16443        }
16444    }
16445
16446    @Override
16447    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16448            boolean requireFull, String name, String callerPackage) {
16449        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16450                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16451    }
16452
16453    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16454            String className, int flags) {
16455        boolean result = false;
16456        // For apps that don't have pre-defined UIDs, check for permission
16457        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16458            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16459                if (ActivityManager.checkUidPermission(
16460                        INTERACT_ACROSS_USERS,
16461                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16462                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16463                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16464                            + " requests FLAG_SINGLE_USER, but app does not hold "
16465                            + INTERACT_ACROSS_USERS;
16466                    Slog.w(TAG, msg);
16467                    throw new SecurityException(msg);
16468                }
16469                // Permission passed
16470                result = true;
16471            }
16472        } else if ("system".equals(componentProcessName)) {
16473            result = true;
16474        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16475            // Phone app and persistent apps are allowed to export singleuser providers.
16476            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16477                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16478        }
16479        if (DEBUG_MU) Slog.v(TAG_MU,
16480                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16481                + Integer.toHexString(flags) + ") = " + result);
16482        return result;
16483    }
16484
16485    /**
16486     * Checks to see if the caller is in the same app as the singleton
16487     * component, or the component is in a special app. It allows special apps
16488     * to export singleton components but prevents exporting singleton
16489     * components for regular apps.
16490     */
16491    boolean isValidSingletonCall(int callingUid, int componentUid) {
16492        int componentAppId = UserHandle.getAppId(componentUid);
16493        return UserHandle.isSameApp(callingUid, componentUid)
16494                || componentAppId == Process.SYSTEM_UID
16495                || componentAppId == Process.PHONE_UID
16496                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16497                        == PackageManager.PERMISSION_GRANTED;
16498    }
16499
16500    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16501            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16502            int userId) throws TransactionTooLargeException {
16503        enforceNotIsolatedCaller("bindService");
16504
16505        // Refuse possible leaked file descriptors
16506        if (service != null && service.hasFileDescriptors() == true) {
16507            throw new IllegalArgumentException("File descriptors passed in Intent");
16508        }
16509
16510        if (callingPackage == null) {
16511            throw new IllegalArgumentException("callingPackage cannot be null");
16512        }
16513
16514        synchronized(this) {
16515            return mServices.bindServiceLocked(caller, token, service,
16516                    resolvedType, connection, flags, callingPackage, userId);
16517        }
16518    }
16519
16520    public boolean unbindService(IServiceConnection connection) {
16521        synchronized (this) {
16522            return mServices.unbindServiceLocked(connection);
16523        }
16524    }
16525
16526    public void publishService(IBinder token, Intent intent, IBinder service) {
16527        // Refuse possible leaked file descriptors
16528        if (intent != null && intent.hasFileDescriptors() == true) {
16529            throw new IllegalArgumentException("File descriptors passed in Intent");
16530        }
16531
16532        synchronized(this) {
16533            if (!(token instanceof ServiceRecord)) {
16534                throw new IllegalArgumentException("Invalid service token");
16535            }
16536            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16537        }
16538    }
16539
16540    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16541        // Refuse possible leaked file descriptors
16542        if (intent != null && intent.hasFileDescriptors() == true) {
16543            throw new IllegalArgumentException("File descriptors passed in Intent");
16544        }
16545
16546        synchronized(this) {
16547            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16548        }
16549    }
16550
16551    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16552        synchronized(this) {
16553            if (!(token instanceof ServiceRecord)) {
16554                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16555                throw new IllegalArgumentException("Invalid service token");
16556            }
16557            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16558        }
16559    }
16560
16561    // =========================================================
16562    // BACKUP AND RESTORE
16563    // =========================================================
16564
16565    // Cause the target app to be launched if necessary and its backup agent
16566    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16567    // activity manager to announce its creation.
16568    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16569        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16570                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16571        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16572
16573        synchronized(this) {
16574            // !!! TODO: currently no check here that we're already bound
16575            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16576            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16577            synchronized (stats) {
16578                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16579            }
16580
16581            // Backup agent is now in use, its package can't be stopped.
16582            try {
16583                AppGlobals.getPackageManager().setPackageStoppedState(
16584                        app.packageName, false, UserHandle.getUserId(app.uid));
16585            } catch (RemoteException e) {
16586            } catch (IllegalArgumentException e) {
16587                Slog.w(TAG, "Failed trying to unstop package "
16588                        + app.packageName + ": " + e);
16589            }
16590
16591            BackupRecord r = new BackupRecord(ss, app, backupMode);
16592            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16593                    ? new ComponentName(app.packageName, app.backupAgentName)
16594                    : new ComponentName("android", "FullBackupAgent");
16595            // startProcessLocked() returns existing proc's record if it's already running
16596            ProcessRecord proc = startProcessLocked(app.processName, app,
16597                    false, 0, "backup", hostingName, false, false, false);
16598            if (proc == null) {
16599                Slog.e(TAG, "Unable to start backup agent process " + r);
16600                return false;
16601            }
16602
16603            r.app = proc;
16604            mBackupTarget = r;
16605            mBackupAppName = app.packageName;
16606
16607            // Try not to kill the process during backup
16608            updateOomAdjLocked(proc);
16609
16610            // If the process is already attached, schedule the creation of the backup agent now.
16611            // If it is not yet live, this will be done when it attaches to the framework.
16612            if (proc.thread != null) {
16613                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16614                try {
16615                    proc.thread.scheduleCreateBackupAgent(app,
16616                            compatibilityInfoForPackageLocked(app), backupMode);
16617                } catch (RemoteException e) {
16618                    // Will time out on the backup manager side
16619                }
16620            } else {
16621                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16622            }
16623            // Invariants: at this point, the target app process exists and the application
16624            // is either already running or in the process of coming up.  mBackupTarget and
16625            // mBackupAppName describe the app, so that when it binds back to the AM we
16626            // know that it's scheduled for a backup-agent operation.
16627        }
16628
16629        return true;
16630    }
16631
16632    @Override
16633    public void clearPendingBackup() {
16634        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16635        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16636
16637        synchronized (this) {
16638            mBackupTarget = null;
16639            mBackupAppName = null;
16640        }
16641    }
16642
16643    // A backup agent has just come up
16644    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16645        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16646                + " = " + agent);
16647
16648        synchronized(this) {
16649            if (!agentPackageName.equals(mBackupAppName)) {
16650                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16651                return;
16652            }
16653        }
16654
16655        long oldIdent = Binder.clearCallingIdentity();
16656        try {
16657            IBackupManager bm = IBackupManager.Stub.asInterface(
16658                    ServiceManager.getService(Context.BACKUP_SERVICE));
16659            bm.agentConnected(agentPackageName, agent);
16660        } catch (RemoteException e) {
16661            // can't happen; the backup manager service is local
16662        } catch (Exception e) {
16663            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16664            e.printStackTrace();
16665        } finally {
16666            Binder.restoreCallingIdentity(oldIdent);
16667        }
16668    }
16669
16670    // done with this agent
16671    public void unbindBackupAgent(ApplicationInfo appInfo) {
16672        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16673        if (appInfo == null) {
16674            Slog.w(TAG, "unbind backup agent for null app");
16675            return;
16676        }
16677
16678        synchronized(this) {
16679            try {
16680                if (mBackupAppName == null) {
16681                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16682                    return;
16683                }
16684
16685                if (!mBackupAppName.equals(appInfo.packageName)) {
16686                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16687                    return;
16688                }
16689
16690                // Not backing this app up any more; reset its OOM adjustment
16691                final ProcessRecord proc = mBackupTarget.app;
16692                updateOomAdjLocked(proc);
16693
16694                // If the app crashed during backup, 'thread' will be null here
16695                if (proc.thread != null) {
16696                    try {
16697                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16698                                compatibilityInfoForPackageLocked(appInfo));
16699                    } catch (Exception e) {
16700                        Slog.e(TAG, "Exception when unbinding backup agent:");
16701                        e.printStackTrace();
16702                    }
16703                }
16704            } finally {
16705                mBackupTarget = null;
16706                mBackupAppName = null;
16707            }
16708        }
16709    }
16710    // =========================================================
16711    // BROADCASTS
16712    // =========================================================
16713
16714    boolean isPendingBroadcastProcessLocked(int pid) {
16715        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16716                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16717    }
16718
16719    void skipPendingBroadcastLocked(int pid) {
16720            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16721            for (BroadcastQueue queue : mBroadcastQueues) {
16722                queue.skipPendingBroadcastLocked(pid);
16723            }
16724    }
16725
16726    // The app just attached; send any pending broadcasts that it should receive
16727    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16728        boolean didSomething = false;
16729        for (BroadcastQueue queue : mBroadcastQueues) {
16730            didSomething |= queue.sendPendingBroadcastsLocked(app);
16731        }
16732        return didSomething;
16733    }
16734
16735    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16736            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16737        enforceNotIsolatedCaller("registerReceiver");
16738        ArrayList<Intent> stickyIntents = null;
16739        ProcessRecord callerApp = null;
16740        int callingUid;
16741        int callingPid;
16742        synchronized(this) {
16743            if (caller != null) {
16744                callerApp = getRecordForAppLocked(caller);
16745                if (callerApp == null) {
16746                    throw new SecurityException(
16747                            "Unable to find app for caller " + caller
16748                            + " (pid=" + Binder.getCallingPid()
16749                            + ") when registering receiver " + receiver);
16750                }
16751                if (callerApp.info.uid != Process.SYSTEM_UID &&
16752                        !callerApp.pkgList.containsKey(callerPackage) &&
16753                        !"android".equals(callerPackage)) {
16754                    throw new SecurityException("Given caller package " + callerPackage
16755                            + " is not running in process " + callerApp);
16756                }
16757                callingUid = callerApp.info.uid;
16758                callingPid = callerApp.pid;
16759            } else {
16760                callerPackage = null;
16761                callingUid = Binder.getCallingUid();
16762                callingPid = Binder.getCallingPid();
16763            }
16764
16765            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16766                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16767
16768            Iterator<String> actions = filter.actionsIterator();
16769            if (actions == null) {
16770                ArrayList<String> noAction = new ArrayList<String>(1);
16771                noAction.add(null);
16772                actions = noAction.iterator();
16773            }
16774
16775            // Collect stickies of users
16776            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16777            while (actions.hasNext()) {
16778                String action = actions.next();
16779                for (int id : userIds) {
16780                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16781                    if (stickies != null) {
16782                        ArrayList<Intent> intents = stickies.get(action);
16783                        if (intents != null) {
16784                            if (stickyIntents == null) {
16785                                stickyIntents = new ArrayList<Intent>();
16786                            }
16787                            stickyIntents.addAll(intents);
16788                        }
16789                    }
16790                }
16791            }
16792        }
16793
16794        ArrayList<Intent> allSticky = null;
16795        if (stickyIntents != null) {
16796            final ContentResolver resolver = mContext.getContentResolver();
16797            // Look for any matching sticky broadcasts...
16798            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16799                Intent intent = stickyIntents.get(i);
16800                // If intent has scheme "content", it will need to acccess
16801                // provider that needs to lock mProviderMap in ActivityThread
16802                // and also it may need to wait application response, so we
16803                // cannot lock ActivityManagerService here.
16804                if (filter.match(resolver, intent, true, TAG) >= 0) {
16805                    if (allSticky == null) {
16806                        allSticky = new ArrayList<Intent>();
16807                    }
16808                    allSticky.add(intent);
16809                }
16810            }
16811        }
16812
16813        // The first sticky in the list is returned directly back to the client.
16814        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16815        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16816        if (receiver == null) {
16817            return sticky;
16818        }
16819
16820        synchronized (this) {
16821            if (callerApp != null && (callerApp.thread == null
16822                    || callerApp.thread.asBinder() != caller.asBinder())) {
16823                // Original caller already died
16824                return null;
16825            }
16826            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16827            if (rl == null) {
16828                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16829                        userId, receiver);
16830                if (rl.app != null) {
16831                    rl.app.receivers.add(rl);
16832                } else {
16833                    try {
16834                        receiver.asBinder().linkToDeath(rl, 0);
16835                    } catch (RemoteException e) {
16836                        return sticky;
16837                    }
16838                    rl.linkedToDeath = true;
16839                }
16840                mRegisteredReceivers.put(receiver.asBinder(), rl);
16841            } else if (rl.uid != callingUid) {
16842                throw new IllegalArgumentException(
16843                        "Receiver requested to register for uid " + callingUid
16844                        + " was previously registered for uid " + rl.uid);
16845            } else if (rl.pid != callingPid) {
16846                throw new IllegalArgumentException(
16847                        "Receiver requested to register for pid " + callingPid
16848                        + " was previously registered for pid " + rl.pid);
16849            } else if (rl.userId != userId) {
16850                throw new IllegalArgumentException(
16851                        "Receiver requested to register for user " + userId
16852                        + " was previously registered for user " + rl.userId);
16853            }
16854            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16855                    permission, callingUid, userId);
16856            rl.add(bf);
16857            if (!bf.debugCheck()) {
16858                Slog.w(TAG, "==> For Dynamic broadcast");
16859            }
16860            mReceiverResolver.addFilter(bf);
16861
16862            // Enqueue broadcasts for all existing stickies that match
16863            // this filter.
16864            if (allSticky != null) {
16865                ArrayList receivers = new ArrayList();
16866                receivers.add(bf);
16867
16868                final int stickyCount = allSticky.size();
16869                for (int i = 0; i < stickyCount; i++) {
16870                    Intent intent = allSticky.get(i);
16871                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16872                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16873                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16874                            null, 0, null, null, false, true, true, -1);
16875                    queue.enqueueParallelBroadcastLocked(r);
16876                    queue.scheduleBroadcastsLocked();
16877                }
16878            }
16879
16880            return sticky;
16881        }
16882    }
16883
16884    public void unregisterReceiver(IIntentReceiver receiver) {
16885        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16886
16887        final long origId = Binder.clearCallingIdentity();
16888        try {
16889            boolean doTrim = false;
16890
16891            synchronized(this) {
16892                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16893                if (rl != null) {
16894                    final BroadcastRecord r = rl.curBroadcast;
16895                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16896                        final boolean doNext = r.queue.finishReceiverLocked(
16897                                r, r.resultCode, r.resultData, r.resultExtras,
16898                                r.resultAbort, false);
16899                        if (doNext) {
16900                            doTrim = true;
16901                            r.queue.processNextBroadcast(false);
16902                        }
16903                    }
16904
16905                    if (rl.app != null) {
16906                        rl.app.receivers.remove(rl);
16907                    }
16908                    removeReceiverLocked(rl);
16909                    if (rl.linkedToDeath) {
16910                        rl.linkedToDeath = false;
16911                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16912                    }
16913                }
16914            }
16915
16916            // If we actually concluded any broadcasts, we might now be able
16917            // to trim the recipients' apps from our working set
16918            if (doTrim) {
16919                trimApplications();
16920                return;
16921            }
16922
16923        } finally {
16924            Binder.restoreCallingIdentity(origId);
16925        }
16926    }
16927
16928    void removeReceiverLocked(ReceiverList rl) {
16929        mRegisteredReceivers.remove(rl.receiver.asBinder());
16930        for (int i = rl.size() - 1; i >= 0; i--) {
16931            mReceiverResolver.removeFilter(rl.get(i));
16932        }
16933    }
16934
16935    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16936        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16937            ProcessRecord r = mLruProcesses.get(i);
16938            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16939                try {
16940                    r.thread.dispatchPackageBroadcast(cmd, packages);
16941                } catch (RemoteException ex) {
16942                }
16943            }
16944        }
16945    }
16946
16947    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16948            int callingUid, int[] users) {
16949        // TODO: come back and remove this assumption to triage all broadcasts
16950        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16951
16952        List<ResolveInfo> receivers = null;
16953        try {
16954            HashSet<ComponentName> singleUserReceivers = null;
16955            boolean scannedFirstReceivers = false;
16956            for (int user : users) {
16957                // Skip users that have Shell restrictions, with exception of always permitted
16958                // Shell broadcasts
16959                if (callingUid == Process.SHELL_UID
16960                        && mUserController.hasUserRestriction(
16961                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
16962                        && !isPermittedShellBroadcast(intent)) {
16963                    continue;
16964                }
16965                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16966                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
16967                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16968                    // If this is not the system user, we need to check for
16969                    // any receivers that should be filtered out.
16970                    for (int i=0; i<newReceivers.size(); i++) {
16971                        ResolveInfo ri = newReceivers.get(i);
16972                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16973                            newReceivers.remove(i);
16974                            i--;
16975                        }
16976                    }
16977                }
16978                if (newReceivers != null && newReceivers.size() == 0) {
16979                    newReceivers = null;
16980                }
16981                if (receivers == null) {
16982                    receivers = newReceivers;
16983                } else if (newReceivers != null) {
16984                    // We need to concatenate the additional receivers
16985                    // found with what we have do far.  This would be easy,
16986                    // but we also need to de-dup any receivers that are
16987                    // singleUser.
16988                    if (!scannedFirstReceivers) {
16989                        // Collect any single user receivers we had already retrieved.
16990                        scannedFirstReceivers = true;
16991                        for (int i=0; i<receivers.size(); i++) {
16992                            ResolveInfo ri = receivers.get(i);
16993                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16994                                ComponentName cn = new ComponentName(
16995                                        ri.activityInfo.packageName, ri.activityInfo.name);
16996                                if (singleUserReceivers == null) {
16997                                    singleUserReceivers = new HashSet<ComponentName>();
16998                                }
16999                                singleUserReceivers.add(cn);
17000                            }
17001                        }
17002                    }
17003                    // Add the new results to the existing results, tracking
17004                    // and de-dupping single user receivers.
17005                    for (int i=0; i<newReceivers.size(); i++) {
17006                        ResolveInfo ri = newReceivers.get(i);
17007                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17008                            ComponentName cn = new ComponentName(
17009                                    ri.activityInfo.packageName, ri.activityInfo.name);
17010                            if (singleUserReceivers == null) {
17011                                singleUserReceivers = new HashSet<ComponentName>();
17012                            }
17013                            if (!singleUserReceivers.contains(cn)) {
17014                                singleUserReceivers.add(cn);
17015                                receivers.add(ri);
17016                            }
17017                        } else {
17018                            receivers.add(ri);
17019                        }
17020                    }
17021                }
17022            }
17023        } catch (RemoteException ex) {
17024            // pm is in same process, this will never happen.
17025        }
17026        return receivers;
17027    }
17028
17029    private boolean isPermittedShellBroadcast(Intent intent) {
17030        // remote bugreport should always be allowed to be taken
17031        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17032    }
17033
17034    final int broadcastIntentLocked(ProcessRecord callerApp,
17035            String callerPackage, Intent intent, String resolvedType,
17036            IIntentReceiver resultTo, int resultCode, String resultData,
17037            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17038            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17039        intent = new Intent(intent);
17040
17041        // By default broadcasts do not go to stopped apps.
17042        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17043
17044        // If we have not finished booting, don't allow this to launch new processes.
17045        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17046            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17047        }
17048
17049        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17050                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17051                + " ordered=" + ordered + " userid=" + userId);
17052        if ((resultTo != null) && !ordered) {
17053            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17054        }
17055
17056        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17057                ALLOW_NON_FULL, "broadcast", callerPackage);
17058
17059        // Make sure that the user who is receiving this broadcast is running.
17060        // If not, we will just skip it. Make an exception for shutdown broadcasts
17061        // and upgrade steps.
17062
17063        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17064            if ((callingUid != Process.SYSTEM_UID
17065                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17066                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17067                Slog.w(TAG, "Skipping broadcast of " + intent
17068                        + ": user " + userId + " is stopped");
17069                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17070            }
17071        }
17072
17073        BroadcastOptions brOptions = null;
17074        if (bOptions != null) {
17075            brOptions = new BroadcastOptions(bOptions);
17076            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17077                // See if the caller is allowed to do this.  Note we are checking against
17078                // the actual real caller (not whoever provided the operation as say a
17079                // PendingIntent), because that who is actually supplied the arguments.
17080                if (checkComponentPermission(
17081                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17082                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17083                        != PackageManager.PERMISSION_GRANTED) {
17084                    String msg = "Permission Denial: " + intent.getAction()
17085                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17086                            + ", uid=" + callingUid + ")"
17087                            + " requires "
17088                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17089                    Slog.w(TAG, msg);
17090                    throw new SecurityException(msg);
17091                }
17092            }
17093        }
17094
17095        // Verify that protected broadcasts are only being sent by system code,
17096        // and that system code is only sending protected broadcasts.
17097        final String action = intent.getAction();
17098        final boolean isProtectedBroadcast;
17099        try {
17100            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17101        } catch (RemoteException e) {
17102            Slog.w(TAG, "Remote exception", e);
17103            return ActivityManager.BROADCAST_SUCCESS;
17104        }
17105
17106        final boolean isCallerSystem;
17107        switch (UserHandle.getAppId(callingUid)) {
17108            case Process.ROOT_UID:
17109            case Process.SYSTEM_UID:
17110            case Process.PHONE_UID:
17111            case Process.BLUETOOTH_UID:
17112            case Process.NFC_UID:
17113                isCallerSystem = true;
17114                break;
17115            default:
17116                isCallerSystem = (callerApp != null) && callerApp.persistent;
17117                break;
17118        }
17119
17120        if (isCallerSystem) {
17121            if (isProtectedBroadcast
17122                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17123                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17124                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17125                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17126                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17127                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17128                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17129                // Broadcast is either protected, or it's a public action that
17130                // we've relaxed, so it's fine for system internals to send.
17131            } else {
17132                // The vast majority of broadcasts sent from system internals
17133                // should be protected to avoid security holes, so yell loudly
17134                // to ensure we examine these cases.
17135                Log.wtf(TAG, "Sending non-protected broadcast " + action
17136                        + " from system", new Throwable());
17137            }
17138
17139        } else {
17140            if (isProtectedBroadcast) {
17141                String msg = "Permission Denial: not allowed to send broadcast "
17142                        + action + " from pid="
17143                        + callingPid + ", uid=" + callingUid;
17144                Slog.w(TAG, msg);
17145                throw new SecurityException(msg);
17146
17147            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17148                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17149                // Special case for compatibility: we don't want apps to send this,
17150                // but historically it has not been protected and apps may be using it
17151                // to poke their own app widget.  So, instead of making it protected,
17152                // just limit it to the caller.
17153                if (callerApp == null) {
17154                    String msg = "Permission Denial: not allowed to send broadcast "
17155                            + action + " from unknown caller.";
17156                    Slog.w(TAG, msg);
17157                    throw new SecurityException(msg);
17158                } else if (intent.getComponent() != null) {
17159                    // They are good enough to send to an explicit component...  verify
17160                    // it is being sent to the calling app.
17161                    if (!intent.getComponent().getPackageName().equals(
17162                            callerApp.info.packageName)) {
17163                        String msg = "Permission Denial: not allowed to send broadcast "
17164                                + action + " to "
17165                                + intent.getComponent().getPackageName() + " from "
17166                                + callerApp.info.packageName;
17167                        Slog.w(TAG, msg);
17168                        throw new SecurityException(msg);
17169                    }
17170                } else {
17171                    // Limit broadcast to their own package.
17172                    intent.setPackage(callerApp.info.packageName);
17173                }
17174            }
17175        }
17176
17177        if (action != null) {
17178            switch (action) {
17179                case Intent.ACTION_UID_REMOVED:
17180                case Intent.ACTION_PACKAGE_REMOVED:
17181                case Intent.ACTION_PACKAGE_CHANGED:
17182                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17183                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17184                case Intent.ACTION_PACKAGES_SUSPENDED:
17185                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17186                    // Handle special intents: if this broadcast is from the package
17187                    // manager about a package being removed, we need to remove all of
17188                    // its activities from the history stack.
17189                    if (checkComponentPermission(
17190                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17191                            callingPid, callingUid, -1, true)
17192                            != PackageManager.PERMISSION_GRANTED) {
17193                        String msg = "Permission Denial: " + intent.getAction()
17194                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17195                                + ", uid=" + callingUid + ")"
17196                                + " requires "
17197                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17198                        Slog.w(TAG, msg);
17199                        throw new SecurityException(msg);
17200                    }
17201                    switch (action) {
17202                        case Intent.ACTION_UID_REMOVED:
17203                            final Bundle intentExtras = intent.getExtras();
17204                            final int uid = intentExtras != null
17205                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17206                            if (uid >= 0) {
17207                                mBatteryStatsService.removeUid(uid);
17208                                mAppOpsService.uidRemoved(uid);
17209                            }
17210                            break;
17211                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17212                            // If resources are unavailable just force stop all those packages
17213                            // and flush the attribute cache as well.
17214                            String list[] =
17215                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17216                            if (list != null && list.length > 0) {
17217                                for (int i = 0; i < list.length; i++) {
17218                                    forceStopPackageLocked(list[i], -1, false, true, true,
17219                                            false, false, userId, "storage unmount");
17220                                }
17221                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17222                                sendPackageBroadcastLocked(
17223                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17224                                        userId);
17225                            }
17226                            break;
17227                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17228                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17229                            break;
17230                        case Intent.ACTION_PACKAGE_REMOVED:
17231                        case Intent.ACTION_PACKAGE_CHANGED:
17232                            Uri data = intent.getData();
17233                            String ssp;
17234                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17235                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17236                                final boolean replacing =
17237                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17238                                final boolean killProcess =
17239                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17240                                final boolean fullUninstall = removed && !replacing;
17241                                if (killProcess) {
17242                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17243                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17244                                            false, true, true, false, fullUninstall, userId,
17245                                            removed ? "pkg removed" : "pkg changed");
17246                                }
17247                                if (removed) {
17248                                    final int cmd = killProcess
17249                                            ? IApplicationThread.PACKAGE_REMOVED
17250                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17251                                    sendPackageBroadcastLocked(cmd,
17252                                            new String[] {ssp}, userId);
17253                                    if (fullUninstall) {
17254                                        mAppOpsService.packageRemoved(
17255                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17256
17257                                        // Remove all permissions granted from/to this package
17258                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17259
17260                                        removeTasksByPackageNameLocked(ssp, userId);
17261                                        mBatteryStatsService.notePackageUninstalled(ssp);
17262                                    }
17263                                } else {
17264                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17265                                            intent.getStringArrayExtra(
17266                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17267                                }
17268                            }
17269                            break;
17270                        case Intent.ACTION_PACKAGES_SUSPENDED:
17271                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17272                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17273                                    intent.getAction());
17274                            final String[] packageNames = intent.getStringArrayExtra(
17275                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17276                            final int userHandle = intent.getIntExtra(
17277                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17278
17279                            synchronized(ActivityManagerService.this) {
17280                                mRecentTasks.onPackagesSuspendedChanged(
17281                                        packageNames, suspended, userHandle);
17282                            }
17283                            break;
17284                    }
17285                    break;
17286                case Intent.ACTION_PACKAGE_REPLACED:
17287                {
17288                    final Uri data = intent.getData();
17289                    final String ssp;
17290                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17291                        final ApplicationInfo aInfo =
17292                                getPackageManagerInternalLocked().getApplicationInfo(
17293                                        ssp,
17294                                        userId);
17295                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17296                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17297                                new String[] {ssp}, userId);
17298                    }
17299                    break;
17300                }
17301                case Intent.ACTION_PACKAGE_ADDED:
17302                {
17303                    // Special case for adding a package: by default turn on compatibility mode.
17304                    Uri data = intent.getData();
17305                    String ssp;
17306                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17307                        final boolean replacing =
17308                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17309                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17310
17311                        try {
17312                            ApplicationInfo ai = AppGlobals.getPackageManager().
17313                                    getApplicationInfo(ssp, 0, 0);
17314                            mBatteryStatsService.notePackageInstalled(ssp,
17315                                    ai != null ? ai.versionCode : 0);
17316                        } catch (RemoteException e) {
17317                        }
17318                    }
17319                    break;
17320                }
17321                case Intent.ACTION_TIMEZONE_CHANGED:
17322                    // If this is the time zone changed action, queue up a message that will reset
17323                    // the timezone of all currently running processes. This message will get
17324                    // queued up before the broadcast happens.
17325                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17326                    break;
17327                case Intent.ACTION_TIME_CHANGED:
17328                    // If the user set the time, let all running processes know.
17329                    final int is24Hour =
17330                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17331                                    : 0;
17332                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17333                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17334                    synchronized (stats) {
17335                        stats.noteCurrentTimeChangedLocked();
17336                    }
17337                    break;
17338                case Intent.ACTION_CLEAR_DNS_CACHE:
17339                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17340                    break;
17341                case Proxy.PROXY_CHANGE_ACTION:
17342                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17343                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17344                    break;
17345                case android.hardware.Camera.ACTION_NEW_PICTURE:
17346                case android.hardware.Camera.ACTION_NEW_VIDEO:
17347                    // These broadcasts are no longer allowed by the system, since they can
17348                    // cause significant thrashing at a crictical point (using the camera).
17349                    // Apps should use JobScehduler to monitor for media provider changes.
17350                    Slog.w(TAG, action + " no longer allowed; dropping from "
17351                            + UserHandle.formatUid(callingUid));
17352                    // Lie; we don't want to crash the app.
17353                    return ActivityManager.BROADCAST_SUCCESS;
17354            }
17355        }
17356
17357        // Add to the sticky list if requested.
17358        if (sticky) {
17359            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17360                    callingPid, callingUid)
17361                    != PackageManager.PERMISSION_GRANTED) {
17362                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17363                        + callingPid + ", uid=" + callingUid
17364                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17365                Slog.w(TAG, msg);
17366                throw new SecurityException(msg);
17367            }
17368            if (requiredPermissions != null && requiredPermissions.length > 0) {
17369                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17370                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17371                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17372            }
17373            if (intent.getComponent() != null) {
17374                throw new SecurityException(
17375                        "Sticky broadcasts can't target a specific component");
17376            }
17377            // We use userId directly here, since the "all" target is maintained
17378            // as a separate set of sticky broadcasts.
17379            if (userId != UserHandle.USER_ALL) {
17380                // But first, if this is not a broadcast to all users, then
17381                // make sure it doesn't conflict with an existing broadcast to
17382                // all users.
17383                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17384                        UserHandle.USER_ALL);
17385                if (stickies != null) {
17386                    ArrayList<Intent> list = stickies.get(intent.getAction());
17387                    if (list != null) {
17388                        int N = list.size();
17389                        int i;
17390                        for (i=0; i<N; i++) {
17391                            if (intent.filterEquals(list.get(i))) {
17392                                throw new IllegalArgumentException(
17393                                        "Sticky broadcast " + intent + " for user "
17394                                        + userId + " conflicts with existing global broadcast");
17395                            }
17396                        }
17397                    }
17398                }
17399            }
17400            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17401            if (stickies == null) {
17402                stickies = new ArrayMap<>();
17403                mStickyBroadcasts.put(userId, stickies);
17404            }
17405            ArrayList<Intent> list = stickies.get(intent.getAction());
17406            if (list == null) {
17407                list = new ArrayList<>();
17408                stickies.put(intent.getAction(), list);
17409            }
17410            final int stickiesCount = list.size();
17411            int i;
17412            for (i = 0; i < stickiesCount; i++) {
17413                if (intent.filterEquals(list.get(i))) {
17414                    // This sticky already exists, replace it.
17415                    list.set(i, new Intent(intent));
17416                    break;
17417                }
17418            }
17419            if (i >= stickiesCount) {
17420                list.add(new Intent(intent));
17421            }
17422        }
17423
17424        int[] users;
17425        if (userId == UserHandle.USER_ALL) {
17426            // Caller wants broadcast to go to all started users.
17427            users = mUserController.getStartedUserArrayLocked();
17428        } else {
17429            // Caller wants broadcast to go to one specific user.
17430            users = new int[] {userId};
17431        }
17432
17433        // Figure out who all will receive this broadcast.
17434        List receivers = null;
17435        List<BroadcastFilter> registeredReceivers = null;
17436        // Need to resolve the intent to interested receivers...
17437        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17438                 == 0) {
17439            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17440        }
17441        if (intent.getComponent() == null) {
17442            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17443                // Query one target user at a time, excluding shell-restricted users
17444                for (int i = 0; i < users.length; i++) {
17445                    if (mUserController.hasUserRestriction(
17446                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17447                        continue;
17448                    }
17449                    List<BroadcastFilter> registeredReceiversForUser =
17450                            mReceiverResolver.queryIntent(intent,
17451                                    resolvedType, false, users[i]);
17452                    if (registeredReceivers == null) {
17453                        registeredReceivers = registeredReceiversForUser;
17454                    } else if (registeredReceiversForUser != null) {
17455                        registeredReceivers.addAll(registeredReceiversForUser);
17456                    }
17457                }
17458            } else {
17459                registeredReceivers = mReceiverResolver.queryIntent(intent,
17460                        resolvedType, false, userId);
17461            }
17462        }
17463
17464        final boolean replacePending =
17465                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17466
17467        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17468                + " replacePending=" + replacePending);
17469
17470        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17471        if (!ordered && NR > 0) {
17472            // If we are not serializing this broadcast, then send the
17473            // registered receivers separately so they don't wait for the
17474            // components to be launched.
17475            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17476            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17477                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17478                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17479                    resultExtras, ordered, sticky, false, userId);
17480            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17481            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17482            if (!replaced) {
17483                queue.enqueueParallelBroadcastLocked(r);
17484                queue.scheduleBroadcastsLocked();
17485            }
17486            registeredReceivers = null;
17487            NR = 0;
17488        }
17489
17490        // Merge into one list.
17491        int ir = 0;
17492        if (receivers != null) {
17493            // A special case for PACKAGE_ADDED: do not allow the package
17494            // being added to see this broadcast.  This prevents them from
17495            // using this as a back door to get run as soon as they are
17496            // installed.  Maybe in the future we want to have a special install
17497            // broadcast or such for apps, but we'd like to deliberately make
17498            // this decision.
17499            String skipPackages[] = null;
17500            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17501                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17502                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17503                Uri data = intent.getData();
17504                if (data != null) {
17505                    String pkgName = data.getSchemeSpecificPart();
17506                    if (pkgName != null) {
17507                        skipPackages = new String[] { pkgName };
17508                    }
17509                }
17510            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17511                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17512            }
17513            if (skipPackages != null && (skipPackages.length > 0)) {
17514                for (String skipPackage : skipPackages) {
17515                    if (skipPackage != null) {
17516                        int NT = receivers.size();
17517                        for (int it=0; it<NT; it++) {
17518                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17519                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17520                                receivers.remove(it);
17521                                it--;
17522                                NT--;
17523                            }
17524                        }
17525                    }
17526                }
17527            }
17528
17529            int NT = receivers != null ? receivers.size() : 0;
17530            int it = 0;
17531            ResolveInfo curt = null;
17532            BroadcastFilter curr = null;
17533            while (it < NT && ir < NR) {
17534                if (curt == null) {
17535                    curt = (ResolveInfo)receivers.get(it);
17536                }
17537                if (curr == null) {
17538                    curr = registeredReceivers.get(ir);
17539                }
17540                if (curr.getPriority() >= curt.priority) {
17541                    // Insert this broadcast record into the final list.
17542                    receivers.add(it, curr);
17543                    ir++;
17544                    curr = null;
17545                    it++;
17546                    NT++;
17547                } else {
17548                    // Skip to the next ResolveInfo in the final list.
17549                    it++;
17550                    curt = null;
17551                }
17552            }
17553        }
17554        while (ir < NR) {
17555            if (receivers == null) {
17556                receivers = new ArrayList();
17557            }
17558            receivers.add(registeredReceivers.get(ir));
17559            ir++;
17560        }
17561
17562        if ((receivers != null && receivers.size() > 0)
17563                || resultTo != null) {
17564            BroadcastQueue queue = broadcastQueueForIntent(intent);
17565            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17566                    callerPackage, callingPid, callingUid, resolvedType,
17567                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17568                    resultData, resultExtras, ordered, sticky, false, userId);
17569
17570            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17571                    + ": prev had " + queue.mOrderedBroadcasts.size());
17572            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17573                    "Enqueueing broadcast " + r.intent.getAction());
17574
17575            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17576            if (!replaced) {
17577                queue.enqueueOrderedBroadcastLocked(r);
17578                queue.scheduleBroadcastsLocked();
17579            }
17580        }
17581
17582        return ActivityManager.BROADCAST_SUCCESS;
17583    }
17584
17585    final Intent verifyBroadcastLocked(Intent intent) {
17586        // Refuse possible leaked file descriptors
17587        if (intent != null && intent.hasFileDescriptors() == true) {
17588            throw new IllegalArgumentException("File descriptors passed in Intent");
17589        }
17590
17591        int flags = intent.getFlags();
17592
17593        if (!mProcessesReady) {
17594            // if the caller really truly claims to know what they're doing, go
17595            // ahead and allow the broadcast without launching any receivers
17596            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17597                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17598            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17599                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17600                        + " before boot completion");
17601                throw new IllegalStateException("Cannot broadcast before boot completed");
17602            }
17603        }
17604
17605        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17606            throw new IllegalArgumentException(
17607                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17608        }
17609
17610        return intent;
17611    }
17612
17613    public final int broadcastIntent(IApplicationThread caller,
17614            Intent intent, String resolvedType, IIntentReceiver resultTo,
17615            int resultCode, String resultData, Bundle resultExtras,
17616            String[] requiredPermissions, int appOp, Bundle bOptions,
17617            boolean serialized, boolean sticky, int userId) {
17618        enforceNotIsolatedCaller("broadcastIntent");
17619        synchronized(this) {
17620            intent = verifyBroadcastLocked(intent);
17621
17622            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17623            final int callingPid = Binder.getCallingPid();
17624            final int callingUid = Binder.getCallingUid();
17625            final long origId = Binder.clearCallingIdentity();
17626            int res = broadcastIntentLocked(callerApp,
17627                    callerApp != null ? callerApp.info.packageName : null,
17628                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17629                    requiredPermissions, appOp, null, serialized, sticky,
17630                    callingPid, callingUid, userId);
17631            Binder.restoreCallingIdentity(origId);
17632            return res;
17633        }
17634    }
17635
17636
17637    int broadcastIntentInPackage(String packageName, int uid,
17638            Intent intent, String resolvedType, IIntentReceiver resultTo,
17639            int resultCode, String resultData, Bundle resultExtras,
17640            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17641            int userId) {
17642        synchronized(this) {
17643            intent = verifyBroadcastLocked(intent);
17644
17645            final long origId = Binder.clearCallingIdentity();
17646            String[] requiredPermissions = requiredPermission == null ? null
17647                    : new String[] {requiredPermission};
17648            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17649                    resultTo, resultCode, resultData, resultExtras,
17650                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17651                    sticky, -1, uid, userId);
17652            Binder.restoreCallingIdentity(origId);
17653            return res;
17654        }
17655    }
17656
17657    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17658        // Refuse possible leaked file descriptors
17659        if (intent != null && intent.hasFileDescriptors() == true) {
17660            throw new IllegalArgumentException("File descriptors passed in Intent");
17661        }
17662
17663        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17664                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17665
17666        synchronized(this) {
17667            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17668                    != PackageManager.PERMISSION_GRANTED) {
17669                String msg = "Permission Denial: unbroadcastIntent() from pid="
17670                        + Binder.getCallingPid()
17671                        + ", uid=" + Binder.getCallingUid()
17672                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17673                Slog.w(TAG, msg);
17674                throw new SecurityException(msg);
17675            }
17676            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17677            if (stickies != null) {
17678                ArrayList<Intent> list = stickies.get(intent.getAction());
17679                if (list != null) {
17680                    int N = list.size();
17681                    int i;
17682                    for (i=0; i<N; i++) {
17683                        if (intent.filterEquals(list.get(i))) {
17684                            list.remove(i);
17685                            break;
17686                        }
17687                    }
17688                    if (list.size() <= 0) {
17689                        stickies.remove(intent.getAction());
17690                    }
17691                }
17692                if (stickies.size() <= 0) {
17693                    mStickyBroadcasts.remove(userId);
17694                }
17695            }
17696        }
17697    }
17698
17699    void backgroundServicesFinishedLocked(int userId) {
17700        for (BroadcastQueue queue : mBroadcastQueues) {
17701            queue.backgroundServicesFinishedLocked(userId);
17702        }
17703    }
17704
17705    public void finishReceiver(IBinder who, int resultCode, String resultData,
17706            Bundle resultExtras, boolean resultAbort, int flags) {
17707        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17708
17709        // Refuse possible leaked file descriptors
17710        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17711            throw new IllegalArgumentException("File descriptors passed in Bundle");
17712        }
17713
17714        final long origId = Binder.clearCallingIdentity();
17715        try {
17716            boolean doNext = false;
17717            BroadcastRecord r;
17718
17719            synchronized(this) {
17720                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17721                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17722                r = queue.getMatchingOrderedReceiver(who);
17723                if (r != null) {
17724                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17725                        resultData, resultExtras, resultAbort, true);
17726                }
17727            }
17728
17729            if (doNext) {
17730                r.queue.processNextBroadcast(false);
17731            }
17732            trimApplications();
17733        } finally {
17734            Binder.restoreCallingIdentity(origId);
17735        }
17736    }
17737
17738    // =========================================================
17739    // INSTRUMENTATION
17740    // =========================================================
17741
17742    public boolean startInstrumentation(ComponentName className,
17743            String profileFile, int flags, Bundle arguments,
17744            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17745            int userId, String abiOverride) {
17746        enforceNotIsolatedCaller("startInstrumentation");
17747        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17748                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17749        // Refuse possible leaked file descriptors
17750        if (arguments != null && arguments.hasFileDescriptors()) {
17751            throw new IllegalArgumentException("File descriptors passed in Bundle");
17752        }
17753
17754        synchronized(this) {
17755            InstrumentationInfo ii = null;
17756            ApplicationInfo ai = null;
17757            try {
17758                ii = mContext.getPackageManager().getInstrumentationInfo(
17759                    className, STOCK_PM_FLAGS);
17760                ai = AppGlobals.getPackageManager().getApplicationInfo(
17761                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17762            } catch (PackageManager.NameNotFoundException e) {
17763            } catch (RemoteException e) {
17764            }
17765            if (ii == null) {
17766                reportStartInstrumentationFailureLocked(watcher, className,
17767                        "Unable to find instrumentation info for: " + className);
17768                return false;
17769            }
17770            if (ai == null) {
17771                reportStartInstrumentationFailureLocked(watcher, className,
17772                        "Unable to find instrumentation target package: " + ii.targetPackage);
17773                return false;
17774            }
17775            if (!ai.hasCode()) {
17776                reportStartInstrumentationFailureLocked(watcher, className,
17777                        "Instrumentation target has no code: " + ii.targetPackage);
17778                return false;
17779            }
17780
17781            int match = mContext.getPackageManager().checkSignatures(
17782                    ii.targetPackage, ii.packageName);
17783            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17784                String msg = "Permission Denial: starting instrumentation "
17785                        + className + " from pid="
17786                        + Binder.getCallingPid()
17787                        + ", uid=" + Binder.getCallingPid()
17788                        + " not allowed because package " + ii.packageName
17789                        + " does not have a signature matching the target "
17790                        + ii.targetPackage;
17791                reportStartInstrumentationFailureLocked(watcher, className, msg);
17792                throw new SecurityException(msg);
17793            }
17794
17795            final long origId = Binder.clearCallingIdentity();
17796            // Instrumentation can kill and relaunch even persistent processes
17797            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17798                    "start instr");
17799            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17800            app.instrumentationClass = className;
17801            app.instrumentationInfo = ai;
17802            app.instrumentationProfileFile = profileFile;
17803            app.instrumentationArguments = arguments;
17804            app.instrumentationWatcher = watcher;
17805            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17806            app.instrumentationResultClass = className;
17807            Binder.restoreCallingIdentity(origId);
17808        }
17809
17810        return true;
17811    }
17812
17813    /**
17814     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17815     * error to the logs, but if somebody is watching, send the report there too.  This enables
17816     * the "am" command to report errors with more information.
17817     *
17818     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17819     * @param cn The component name of the instrumentation.
17820     * @param report The error report.
17821     */
17822    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17823            ComponentName cn, String report) {
17824        Slog.w(TAG, report);
17825        if (watcher != null) {
17826            Bundle results = new Bundle();
17827            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17828            results.putString("Error", report);
17829            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17830        }
17831    }
17832
17833    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17834        if (app.instrumentationWatcher != null) {
17835            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17836                    app.instrumentationClass, resultCode, results);
17837        }
17838
17839        // Can't call out of the system process with a lock held, so post a message.
17840        if (app.instrumentationUiAutomationConnection != null) {
17841            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17842                    app.instrumentationUiAutomationConnection).sendToTarget();
17843        }
17844
17845        app.instrumentationWatcher = null;
17846        app.instrumentationUiAutomationConnection = null;
17847        app.instrumentationClass = null;
17848        app.instrumentationInfo = null;
17849        app.instrumentationProfileFile = null;
17850        app.instrumentationArguments = null;
17851
17852        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17853                "finished inst");
17854    }
17855
17856    public void finishInstrumentation(IApplicationThread target,
17857            int resultCode, Bundle results) {
17858        int userId = UserHandle.getCallingUserId();
17859        // Refuse possible leaked file descriptors
17860        if (results != null && results.hasFileDescriptors()) {
17861            throw new IllegalArgumentException("File descriptors passed in Intent");
17862        }
17863
17864        synchronized(this) {
17865            ProcessRecord app = getRecordForAppLocked(target);
17866            if (app == null) {
17867                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17868                return;
17869            }
17870            final long origId = Binder.clearCallingIdentity();
17871            finishInstrumentationLocked(app, resultCode, results);
17872            Binder.restoreCallingIdentity(origId);
17873        }
17874    }
17875
17876    // =========================================================
17877    // CONFIGURATION
17878    // =========================================================
17879
17880    public ConfigurationInfo getDeviceConfigurationInfo() {
17881        ConfigurationInfo config = new ConfigurationInfo();
17882        synchronized (this) {
17883            config.reqTouchScreen = mConfiguration.touchscreen;
17884            config.reqKeyboardType = mConfiguration.keyboard;
17885            config.reqNavigation = mConfiguration.navigation;
17886            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17887                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17888                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17889            }
17890            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17891                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17892                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17893            }
17894            config.reqGlEsVersion = GL_ES_VERSION;
17895        }
17896        return config;
17897    }
17898
17899    ActivityStack getFocusedStack() {
17900        return mStackSupervisor.getFocusedStack();
17901    }
17902
17903    @Override
17904    public int getFocusedStackId() throws RemoteException {
17905        ActivityStack focusedStack = getFocusedStack();
17906        if (focusedStack != null) {
17907            return focusedStack.getStackId();
17908        }
17909        return -1;
17910    }
17911
17912    public Configuration getConfiguration() {
17913        Configuration ci;
17914        synchronized(this) {
17915            ci = new Configuration(mConfiguration);
17916            ci.userSetLocale = false;
17917        }
17918        return ci;
17919    }
17920
17921    @Override
17922    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17923        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17924        synchronized (this) {
17925            mSuppressResizeConfigChanges = suppress;
17926        }
17927    }
17928
17929    @Override
17930    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17931        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17932        if (fromStackId == HOME_STACK_ID) {
17933            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17934        }
17935        synchronized (this) {
17936            final long origId = Binder.clearCallingIdentity();
17937            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
17938            if (stack != null) {
17939                mWindowManager.deferSurfaceLayout();
17940                try {
17941                    if (fromStackId == DOCKED_STACK_ID) {
17942
17943                        // We are moving all tasks from the docked stack to the fullscreen stack,
17944                        // which is dismissing the docked stack, so resize all other stacks to
17945                        // fullscreen here already so we don't end up with resize trashing.
17946                        for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
17947                            if (StackId.isResizeableByDockedStack(i)) {
17948                                ActivityStack otherStack = mStackSupervisor.getStack(i);
17949                                if (otherStack != null) {
17950                                    mStackSupervisor.resizeStackLocked(i,
17951                                            null, null, null, PRESERVE_WINDOWS,
17952                                            true /* allowResizeInDockedMode */);
17953                                }
17954                            }
17955                        }
17956                    }
17957                    final ArrayList<TaskRecord> tasks = stack.getAllTasks();
17958                    final int size = tasks.size();
17959                    if (onTop) {
17960                        for (int i = 0; i < size; i++) {
17961                            mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
17962                                    FULLSCREEN_WORKSPACE_STACK_ID, onTop, !FORCE_FOCUS,
17963                                    "moveTasksToFullscreenStack", ANIMATE);
17964                        }
17965                    } else {
17966                        for (int i = size - 1; i >= 0; i--) {
17967                            mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
17968                                    FULLSCREEN_WORKSPACE_STACK_ID, 0);
17969                        }
17970                    }
17971                } finally {
17972                    mWindowManager.continueSurfaceLayout();
17973                }
17974
17975            }
17976            Binder.restoreCallingIdentity(origId);
17977        }
17978    }
17979
17980    @Override
17981    public void updatePersistentConfiguration(Configuration values) {
17982        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17983                "updateConfiguration()");
17984        enforceWriteSettingsPermission("updateConfiguration()");
17985        if (values == null) {
17986            throw new NullPointerException("Configuration must not be null");
17987        }
17988
17989        int userId = UserHandle.getCallingUserId();
17990
17991        synchronized(this) {
17992            final long origId = Binder.clearCallingIdentity();
17993            updateConfigurationLocked(values, null, false, true, userId);
17994            Binder.restoreCallingIdentity(origId);
17995        }
17996    }
17997
17998    private void updateFontScaleIfNeeded() {
17999        final int currentUserId;
18000        synchronized(this) {
18001            currentUserId = mUserController.getCurrentUserIdLocked();
18002        }
18003        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18004                FONT_SCALE, 1.0f, currentUserId);
18005        if (mConfiguration.fontScale != scaleFactor) {
18006            final Configuration configuration = mWindowManager.computeNewConfiguration();
18007            configuration.fontScale = scaleFactor;
18008            updatePersistentConfiguration(configuration);
18009        }
18010    }
18011
18012    private void enforceWriteSettingsPermission(String func) {
18013        int uid = Binder.getCallingUid();
18014        if (uid == Process.ROOT_UID) {
18015            return;
18016        }
18017
18018        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18019                Settings.getPackageNameForUid(mContext, uid), false)) {
18020            return;
18021        }
18022
18023        String msg = "Permission Denial: " + func + " from pid="
18024                + Binder.getCallingPid()
18025                + ", uid=" + uid
18026                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18027        Slog.w(TAG, msg);
18028        throw new SecurityException(msg);
18029    }
18030
18031    public void updateConfiguration(Configuration values) {
18032        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18033                "updateConfiguration()");
18034
18035        synchronized(this) {
18036            if (values == null && mWindowManager != null) {
18037                // sentinel: fetch the current configuration from the window manager
18038                values = mWindowManager.computeNewConfiguration();
18039            }
18040
18041            if (mWindowManager != null) {
18042                mProcessList.applyDisplaySize(mWindowManager);
18043            }
18044
18045            final long origId = Binder.clearCallingIdentity();
18046            if (values != null) {
18047                Settings.System.clearConfiguration(values);
18048            }
18049            updateConfigurationLocked(values, null, false);
18050            Binder.restoreCallingIdentity(origId);
18051        }
18052    }
18053
18054    void updateUserConfigurationLocked() {
18055        Configuration configuration = new Configuration(mConfiguration);
18056        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18057                mUserController.getCurrentUserIdLocked());
18058        updateConfigurationLocked(configuration, null, false);
18059    }
18060
18061    boolean updateConfigurationLocked(Configuration values,
18062            ActivityRecord starting, boolean initLocale) {
18063        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18064        return updateConfigurationLocked(values, starting, initLocale, false,
18065                UserHandle.USER_NULL);
18066    }
18067
18068    // To cache the list of supported system locales
18069    private String[] mSupportedSystemLocales = null;
18070
18071    /**
18072     * Do either or both things: (1) change the current configuration, and (2)
18073     * make sure the given activity is running with the (now) current
18074     * configuration.  Returns true if the activity has been left running, or
18075     * false if <var>starting</var> is being destroyed to match the new
18076     * configuration.
18077     *
18078     * @param userId is only used when persistent parameter is set to true to persist configuration
18079     *               for that particular user
18080     */
18081    private boolean updateConfigurationLocked(Configuration values,
18082            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18083        int changes = 0;
18084
18085        if (mWindowManager != null) {
18086            mWindowManager.deferSurfaceLayout();
18087        }
18088        if (values != null) {
18089            Configuration newConfig = new Configuration(mConfiguration);
18090            changes = newConfig.updateFrom(values);
18091            if (changes != 0) {
18092                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18093                        "Updating configuration to: " + values);
18094
18095                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18096
18097                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18098                    final Locale locale;
18099                    if (values.getLocales().size() == 1) {
18100                        // This is an optimization to avoid the JNI call when the result of
18101                        // getFirstMatch() does not depend on the supported locales.
18102                        locale = values.getLocales().get(0);
18103                    } else {
18104                        if (mSupportedSystemLocales == null) {
18105                            mSupportedSystemLocales =
18106                                    Resources.getSystem().getAssets().getLocales();
18107                        }
18108                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18109                    }
18110                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18111                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18112                            locale));
18113                }
18114
18115                mConfigurationSeq++;
18116                if (mConfigurationSeq <= 0) {
18117                    mConfigurationSeq = 1;
18118                }
18119                newConfig.seq = mConfigurationSeq;
18120                mConfiguration = newConfig;
18121                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18122                mUsageStatsService.reportConfigurationChange(newConfig,
18123                        mUserController.getCurrentUserIdLocked());
18124                //mUsageStatsService.noteStartConfig(newConfig);
18125
18126                final Configuration configCopy = new Configuration(mConfiguration);
18127
18128                // TODO: If our config changes, should we auto dismiss any currently
18129                // showing dialogs?
18130                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18131
18132                AttributeCache ac = AttributeCache.instance();
18133                if (ac != null) {
18134                    ac.updateConfiguration(configCopy);
18135                }
18136
18137                // Make sure all resources in our process are updated
18138                // right now, so that anyone who is going to retrieve
18139                // resource values after we return will be sure to get
18140                // the new ones.  This is especially important during
18141                // boot, where the first config change needs to guarantee
18142                // all resources have that config before following boot
18143                // code is executed.
18144                mSystemThread.applyConfigurationToResources(configCopy);
18145
18146                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18147                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18148                    msg.obj = new Configuration(configCopy);
18149                    msg.arg1 = userId;
18150                    mHandler.sendMessage(msg);
18151                }
18152
18153                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18154                if (isDensityChange) {
18155                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18156                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18157                }
18158
18159                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18160                    ProcessRecord app = mLruProcesses.get(i);
18161                    try {
18162                        if (app.thread != null) {
18163                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18164                                    + app.processName + " new config " + mConfiguration);
18165                            app.thread.scheduleConfigurationChanged(configCopy);
18166                        }
18167                    } catch (Exception e) {
18168                    }
18169                }
18170                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18171                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18172                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18173                        | Intent.FLAG_RECEIVER_FOREGROUND);
18174                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18175                        null, AppOpsManager.OP_NONE, null, false, false,
18176                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18177                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18178                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18179                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18180                    if (!mProcessesReady) {
18181                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18182                    }
18183                    broadcastIntentLocked(null, null, intent,
18184                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18185                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18186                }
18187            }
18188            // Update the configuration with WM first and check if any of the stacks need to be
18189            // resized due to the configuration change. If so, resize the stacks now and do any
18190            // relaunches if necessary. This way we don't need to relaunch again below in
18191            // ensureActivityConfigurationLocked().
18192            if (mWindowManager != null) {
18193                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18194                if (resizedStacks != null) {
18195                    for (int stackId : resizedStacks) {
18196                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18197                        mStackSupervisor.resizeStackLocked(
18198                                stackId, newBounds, null, null, false, false);
18199                    }
18200                }
18201            }
18202        }
18203
18204        boolean kept = true;
18205        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18206        // mainStack is null during startup.
18207        if (mainStack != null) {
18208            if (changes != 0 && starting == null) {
18209                // If the configuration changed, and the caller is not already
18210                // in the process of starting an activity, then find the top
18211                // activity to check if its configuration needs to change.
18212                starting = mainStack.topRunningActivityLocked();
18213            }
18214
18215            if (starting != null) {
18216                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18217                // And we need to make sure at this point that all other activities
18218                // are made visible with the correct configuration.
18219                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18220                        !PRESERVE_WINDOWS);
18221            }
18222        }
18223        if (mWindowManager != null) {
18224            mWindowManager.continueSurfaceLayout();
18225        }
18226        return kept;
18227    }
18228
18229    /**
18230     * Decide based on the configuration whether we should shouw the ANR,
18231     * crash, etc dialogs.  The idea is that if there is no affordnace to
18232     * press the on-screen buttons, we shouldn't show the dialog.
18233     *
18234     * A thought: SystemUI might also want to get told about this, the Power
18235     * dialog / global actions also might want different behaviors.
18236     */
18237    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18238        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18239                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18240                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18241        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18242                                    == Configuration.UI_MODE_TYPE_CAR);
18243        return inputMethodExists && uiIsNotCarType && !inVrMode;
18244    }
18245
18246    @Override
18247    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18248        synchronized (this) {
18249            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18250            if (srec != null) {
18251                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18252            }
18253        }
18254        return false;
18255    }
18256
18257    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18258            Intent resultData) {
18259
18260        synchronized (this) {
18261            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18262            if (r != null) {
18263                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18264            }
18265            return false;
18266        }
18267    }
18268
18269    public int getLaunchedFromUid(IBinder activityToken) {
18270        ActivityRecord srec;
18271        synchronized (this) {
18272            srec = ActivityRecord.forTokenLocked(activityToken);
18273        }
18274        if (srec == null) {
18275            return -1;
18276        }
18277        return srec.launchedFromUid;
18278    }
18279
18280    public String getLaunchedFromPackage(IBinder activityToken) {
18281        ActivityRecord srec;
18282        synchronized (this) {
18283            srec = ActivityRecord.forTokenLocked(activityToken);
18284        }
18285        if (srec == null) {
18286            return null;
18287        }
18288        return srec.launchedFromPackage;
18289    }
18290
18291    // =========================================================
18292    // LIFETIME MANAGEMENT
18293    // =========================================================
18294
18295    // Returns which broadcast queue the app is the current [or imminent] receiver
18296    // on, or 'null' if the app is not an active broadcast recipient.
18297    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18298        BroadcastRecord r = app.curReceiver;
18299        if (r != null) {
18300            return r.queue;
18301        }
18302
18303        // It's not the current receiver, but it might be starting up to become one
18304        synchronized (this) {
18305            for (BroadcastQueue queue : mBroadcastQueues) {
18306                r = queue.mPendingBroadcast;
18307                if (r != null && r.curApp == app) {
18308                    // found it; report which queue it's in
18309                    return queue;
18310                }
18311            }
18312        }
18313
18314        return null;
18315    }
18316
18317    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18318            int targetUid, ComponentName targetComponent, String targetProcess) {
18319        if (!mTrackingAssociations) {
18320            return null;
18321        }
18322        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18323                = mAssociations.get(targetUid);
18324        if (components == null) {
18325            components = new ArrayMap<>();
18326            mAssociations.put(targetUid, components);
18327        }
18328        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18329        if (sourceUids == null) {
18330            sourceUids = new SparseArray<>();
18331            components.put(targetComponent, sourceUids);
18332        }
18333        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18334        if (sourceProcesses == null) {
18335            sourceProcesses = new ArrayMap<>();
18336            sourceUids.put(sourceUid, sourceProcesses);
18337        }
18338        Association ass = sourceProcesses.get(sourceProcess);
18339        if (ass == null) {
18340            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18341                    targetProcess);
18342            sourceProcesses.put(sourceProcess, ass);
18343        }
18344        ass.mCount++;
18345        ass.mNesting++;
18346        if (ass.mNesting == 1) {
18347            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18348            ass.mLastState = sourceState;
18349        }
18350        return ass;
18351    }
18352
18353    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18354            ComponentName targetComponent) {
18355        if (!mTrackingAssociations) {
18356            return;
18357        }
18358        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18359                = mAssociations.get(targetUid);
18360        if (components == null) {
18361            return;
18362        }
18363        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18364        if (sourceUids == null) {
18365            return;
18366        }
18367        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18368        if (sourceProcesses == null) {
18369            return;
18370        }
18371        Association ass = sourceProcesses.get(sourceProcess);
18372        if (ass == null || ass.mNesting <= 0) {
18373            return;
18374        }
18375        ass.mNesting--;
18376        if (ass.mNesting == 0) {
18377            long uptime = SystemClock.uptimeMillis();
18378            ass.mTime += uptime - ass.mStartTime;
18379            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18380                    += uptime - ass.mLastStateUptime;
18381            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18382        }
18383    }
18384
18385    private void noteUidProcessState(final int uid, final int state) {
18386        mBatteryStatsService.noteUidProcessState(uid, state);
18387        if (mTrackingAssociations) {
18388            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18389                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18390                        = mAssociations.valueAt(i1);
18391                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18392                    SparseArray<ArrayMap<String, Association>> sourceUids
18393                            = targetComponents.valueAt(i2);
18394                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18395                    if (sourceProcesses != null) {
18396                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18397                            Association ass = sourceProcesses.valueAt(i4);
18398                            if (ass.mNesting >= 1) {
18399                                // currently associated
18400                                long uptime = SystemClock.uptimeMillis();
18401                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18402                                        += uptime - ass.mLastStateUptime;
18403                                ass.mLastState = state;
18404                                ass.mLastStateUptime = uptime;
18405                            }
18406                        }
18407                    }
18408                }
18409            }
18410        }
18411    }
18412
18413    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18414            boolean doingAll, long now) {
18415        if (mAdjSeq == app.adjSeq) {
18416            // This adjustment has already been computed.
18417            return app.curRawAdj;
18418        }
18419
18420        if (app.thread == null) {
18421            app.adjSeq = mAdjSeq;
18422            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18423            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18424            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18425        }
18426
18427        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18428        app.adjSource = null;
18429        app.adjTarget = null;
18430        app.empty = false;
18431        app.cached = false;
18432
18433        final int activitiesSize = app.activities.size();
18434
18435        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18436            // The max adjustment doesn't allow this app to be anything
18437            // below foreground, so it is not worth doing work for it.
18438            app.adjType = "fixed";
18439            app.adjSeq = mAdjSeq;
18440            app.curRawAdj = app.maxAdj;
18441            app.foregroundActivities = false;
18442            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18443            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18444            // System processes can do UI, and when they do we want to have
18445            // them trim their memory after the user leaves the UI.  To
18446            // facilitate this, here we need to determine whether or not it
18447            // is currently showing UI.
18448            app.systemNoUi = true;
18449            if (app == TOP_APP) {
18450                app.systemNoUi = false;
18451            } else if (activitiesSize > 0) {
18452                for (int j = 0; j < activitiesSize; j++) {
18453                    final ActivityRecord r = app.activities.get(j);
18454                    if (r.visible) {
18455                        app.systemNoUi = false;
18456                    }
18457                }
18458            }
18459            if (!app.systemNoUi) {
18460                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18461            }
18462            return (app.curAdj=app.maxAdj);
18463        }
18464
18465        app.systemNoUi = false;
18466
18467        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18468
18469        // Determine the importance of the process, starting with most
18470        // important to least, and assign an appropriate OOM adjustment.
18471        int adj;
18472        int schedGroup;
18473        int procState;
18474        boolean foregroundActivities = false;
18475        BroadcastQueue queue;
18476        if (app == TOP_APP) {
18477            // The last app on the list is the foreground app.
18478            adj = ProcessList.FOREGROUND_APP_ADJ;
18479            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18480            app.adjType = "top-activity";
18481            foregroundActivities = true;
18482            procState = PROCESS_STATE_CUR_TOP;
18483        } else if (app.instrumentationClass != null) {
18484            // Don't want to kill running instrumentation.
18485            adj = ProcessList.FOREGROUND_APP_ADJ;
18486            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18487            app.adjType = "instrumentation";
18488            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18489        } else if ((queue = isReceivingBroadcast(app)) != null) {
18490            // An app that is currently receiving a broadcast also
18491            // counts as being in the foreground for OOM killer purposes.
18492            // It's placed in a sched group based on the nature of the
18493            // broadcast as reflected by which queue it's active in.
18494            adj = ProcessList.FOREGROUND_APP_ADJ;
18495            schedGroup = (queue == mFgBroadcastQueue)
18496                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18497            app.adjType = "broadcast";
18498            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18499        } else if (app.executingServices.size() > 0) {
18500            // An app that is currently executing a service callback also
18501            // counts as being in the foreground.
18502            adj = ProcessList.FOREGROUND_APP_ADJ;
18503            schedGroup = app.execServicesFg ?
18504                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18505            app.adjType = "exec-service";
18506            procState = ActivityManager.PROCESS_STATE_SERVICE;
18507            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18508        } else {
18509            // As far as we know the process is empty.  We may change our mind later.
18510            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18511            // At this point we don't actually know the adjustment.  Use the cached adj
18512            // value that the caller wants us to.
18513            adj = cachedAdj;
18514            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18515            app.cached = true;
18516            app.empty = true;
18517            app.adjType = "cch-empty";
18518        }
18519
18520        // Examine all activities if not already foreground.
18521        if (!foregroundActivities && activitiesSize > 0) {
18522            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18523            for (int j = 0; j < activitiesSize; j++) {
18524                final ActivityRecord r = app.activities.get(j);
18525                if (r.app != app) {
18526                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18527                            + " instead of expected " + app);
18528                    if (r.app == null || (r.app.uid == app.uid)) {
18529                        // Only fix things up when they look sane
18530                        r.app = app;
18531                    } else {
18532                        continue;
18533                    }
18534                }
18535                if (r.visible) {
18536                    // App has a visible activity; only upgrade adjustment.
18537                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18538                        adj = ProcessList.VISIBLE_APP_ADJ;
18539                        app.adjType = "visible";
18540                    }
18541                    if (procState > PROCESS_STATE_CUR_TOP) {
18542                        procState = PROCESS_STATE_CUR_TOP;
18543                    }
18544                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18545                    app.cached = false;
18546                    app.empty = false;
18547                    foregroundActivities = true;
18548                    if (r.task != null && minLayer > 0) {
18549                        final int layer = r.task.mLayerRank;
18550                        if (layer >= 0 && minLayer > layer) {
18551                            minLayer = layer;
18552                        }
18553                    }
18554                    break;
18555                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18556                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18557                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18558                        app.adjType = "pausing";
18559                    }
18560                    if (procState > PROCESS_STATE_CUR_TOP) {
18561                        procState = PROCESS_STATE_CUR_TOP;
18562                    }
18563                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18564                    app.cached = false;
18565                    app.empty = false;
18566                    foregroundActivities = true;
18567                } else if (r.state == ActivityState.STOPPING) {
18568                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18569                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18570                        app.adjType = "stopping";
18571                    }
18572                    // For the process state, we will at this point consider the
18573                    // process to be cached.  It will be cached either as an activity
18574                    // or empty depending on whether the activity is finishing.  We do
18575                    // this so that we can treat the process as cached for purposes of
18576                    // memory trimming (determing current memory level, trim command to
18577                    // send to process) since there can be an arbitrary number of stopping
18578                    // processes and they should soon all go into the cached state.
18579                    if (!r.finishing) {
18580                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18581                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18582                        }
18583                    }
18584                    app.cached = false;
18585                    app.empty = false;
18586                    foregroundActivities = true;
18587                } else {
18588                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18589                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18590                        app.adjType = "cch-act";
18591                    }
18592                }
18593            }
18594            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18595                adj += minLayer;
18596            }
18597        }
18598
18599        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18600                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18601            if (app.foregroundServices) {
18602                // The user is aware of this app, so make it visible.
18603                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18604                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18605                app.cached = false;
18606                app.adjType = "fg-service";
18607                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18608            } else if (app.forcingToForeground != null) {
18609                // The user is aware of this app, so make it visible.
18610                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18611                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18612                app.cached = false;
18613                app.adjType = "force-fg";
18614                app.adjSource = app.forcingToForeground;
18615                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18616            }
18617        }
18618
18619        if (app == mHeavyWeightProcess) {
18620            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18621                // We don't want to kill the current heavy-weight process.
18622                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18623                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18624                app.cached = false;
18625                app.adjType = "heavy";
18626            }
18627            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18628                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18629            }
18630        }
18631
18632        if (app == mHomeProcess) {
18633            if (adj > ProcessList.HOME_APP_ADJ) {
18634                // This process is hosting what we currently consider to be the
18635                // home app, so we don't want to let it go into the background.
18636                adj = ProcessList.HOME_APP_ADJ;
18637                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18638                app.cached = false;
18639                app.adjType = "home";
18640            }
18641            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18642                procState = ActivityManager.PROCESS_STATE_HOME;
18643            }
18644        }
18645
18646        if (app == mPreviousProcess && app.activities.size() > 0) {
18647            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18648                // This was the previous process that showed UI to the user.
18649                // We want to try to keep it around more aggressively, to give
18650                // a good experience around switching between two apps.
18651                adj = ProcessList.PREVIOUS_APP_ADJ;
18652                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18653                app.cached = false;
18654                app.adjType = "previous";
18655            }
18656            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18657                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18658            }
18659        }
18660
18661        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18662                + " reason=" + app.adjType);
18663
18664        // By default, we use the computed adjustment.  It may be changed if
18665        // there are applications dependent on our services or providers, but
18666        // this gives us a baseline and makes sure we don't get into an
18667        // infinite recursion.
18668        app.adjSeq = mAdjSeq;
18669        app.curRawAdj = adj;
18670        app.hasStartedServices = false;
18671
18672        if (mBackupTarget != null && app == mBackupTarget.app) {
18673            // If possible we want to avoid killing apps while they're being backed up
18674            if (adj > ProcessList.BACKUP_APP_ADJ) {
18675                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18676                adj = ProcessList.BACKUP_APP_ADJ;
18677                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18678                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18679                }
18680                app.adjType = "backup";
18681                app.cached = false;
18682            }
18683            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18684                procState = ActivityManager.PROCESS_STATE_BACKUP;
18685            }
18686        }
18687
18688        boolean mayBeTop = false;
18689
18690        for (int is = app.services.size()-1;
18691                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18692                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18693                        || procState > ActivityManager.PROCESS_STATE_TOP);
18694                is--) {
18695            ServiceRecord s = app.services.valueAt(is);
18696            if (s.startRequested) {
18697                app.hasStartedServices = true;
18698                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18699                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18700                }
18701                if (app.hasShownUi && app != mHomeProcess) {
18702                    // If this process has shown some UI, let it immediately
18703                    // go to the LRU list because it may be pretty heavy with
18704                    // UI stuff.  We'll tag it with a label just to help
18705                    // debug and understand what is going on.
18706                    if (adj > ProcessList.SERVICE_ADJ) {
18707                        app.adjType = "cch-started-ui-services";
18708                    }
18709                } else {
18710                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18711                        // This service has seen some activity within
18712                        // recent memory, so we will keep its process ahead
18713                        // of the background processes.
18714                        if (adj > ProcessList.SERVICE_ADJ) {
18715                            adj = ProcessList.SERVICE_ADJ;
18716                            app.adjType = "started-services";
18717                            app.cached = false;
18718                        }
18719                    }
18720                    // If we have let the service slide into the background
18721                    // state, still have some text describing what it is doing
18722                    // even though the service no longer has an impact.
18723                    if (adj > ProcessList.SERVICE_ADJ) {
18724                        app.adjType = "cch-started-services";
18725                    }
18726                }
18727            }
18728            for (int conni = s.connections.size()-1;
18729                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18730                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18731                            || procState > ActivityManager.PROCESS_STATE_TOP);
18732                    conni--) {
18733                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18734                for (int i = 0;
18735                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18736                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18737                                || procState > ActivityManager.PROCESS_STATE_TOP);
18738                        i++) {
18739                    // XXX should compute this based on the max of
18740                    // all connected clients.
18741                    ConnectionRecord cr = clist.get(i);
18742                    if (cr.binding.client == app) {
18743                        // Binding to ourself is not interesting.
18744                        continue;
18745                    }
18746                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18747                        ProcessRecord client = cr.binding.client;
18748                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18749                                TOP_APP, doingAll, now);
18750                        int clientProcState = client.curProcState;
18751                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18752                            // If the other app is cached for any reason, for purposes here
18753                            // we are going to consider it empty.  The specific cached state
18754                            // doesn't propagate except under certain conditions.
18755                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18756                        }
18757                        String adjType = null;
18758                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18759                            // Not doing bind OOM management, so treat
18760                            // this guy more like a started service.
18761                            if (app.hasShownUi && app != mHomeProcess) {
18762                                // If this process has shown some UI, let it immediately
18763                                // go to the LRU list because it may be pretty heavy with
18764                                // UI stuff.  We'll tag it with a label just to help
18765                                // debug and understand what is going on.
18766                                if (adj > clientAdj) {
18767                                    adjType = "cch-bound-ui-services";
18768                                }
18769                                app.cached = false;
18770                                clientAdj = adj;
18771                                clientProcState = procState;
18772                            } else {
18773                                if (now >= (s.lastActivity
18774                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18775                                    // This service has not seen activity within
18776                                    // recent memory, so allow it to drop to the
18777                                    // LRU list if there is no other reason to keep
18778                                    // it around.  We'll also tag it with a label just
18779                                    // to help debug and undertand what is going on.
18780                                    if (adj > clientAdj) {
18781                                        adjType = "cch-bound-services";
18782                                    }
18783                                    clientAdj = adj;
18784                                }
18785                            }
18786                        }
18787                        if (adj > clientAdj) {
18788                            // If this process has recently shown UI, and
18789                            // the process that is binding to it is less
18790                            // important than being visible, then we don't
18791                            // care about the binding as much as we care
18792                            // about letting this process get into the LRU
18793                            // list to be killed and restarted if needed for
18794                            // memory.
18795                            if (app.hasShownUi && app != mHomeProcess
18796                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18797                                adjType = "cch-bound-ui-services";
18798                            } else {
18799                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18800                                        |Context.BIND_IMPORTANT)) != 0) {
18801                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18802                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18803                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18804                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18805                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18806                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18807                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18808                                    adj = clientAdj;
18809                                } else {
18810                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18811                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18812                                    }
18813                                }
18814                                if (!client.cached) {
18815                                    app.cached = false;
18816                                }
18817                                adjType = "service";
18818                            }
18819                        }
18820                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18821                            // This will treat important bound services identically to
18822                            // the top app, which may behave differently than generic
18823                            // foreground work.
18824                            if (client.curSchedGroup > schedGroup) {
18825                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18826                                    schedGroup = client.curSchedGroup;
18827                                } else {
18828                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18829                                }
18830                            }
18831                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18832                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18833                                    // Special handling of clients who are in the top state.
18834                                    // We *may* want to consider this process to be in the
18835                                    // top state as well, but only if there is not another
18836                                    // reason for it to be running.  Being on the top is a
18837                                    // special state, meaning you are specifically running
18838                                    // for the current top app.  If the process is already
18839                                    // running in the background for some other reason, it
18840                                    // is more important to continue considering it to be
18841                                    // in the background state.
18842                                    mayBeTop = true;
18843                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18844                                } else {
18845                                    // Special handling for above-top states (persistent
18846                                    // processes).  These should not bring the current process
18847                                    // into the top state, since they are not on top.  Instead
18848                                    // give them the best state after that.
18849                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18850                                        clientProcState =
18851                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18852                                    } else if (mWakefulness
18853                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18854                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18855                                                    != 0) {
18856                                        clientProcState =
18857                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18858                                    } else {
18859                                        clientProcState =
18860                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18861                                    }
18862                                }
18863                            }
18864                        } else {
18865                            if (clientProcState <
18866                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18867                                clientProcState =
18868                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18869                            }
18870                        }
18871                        if (procState > clientProcState) {
18872                            procState = clientProcState;
18873                        }
18874                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18875                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18876                            app.pendingUiClean = true;
18877                        }
18878                        if (adjType != null) {
18879                            app.adjType = adjType;
18880                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18881                                    .REASON_SERVICE_IN_USE;
18882                            app.adjSource = cr.binding.client;
18883                            app.adjSourceProcState = clientProcState;
18884                            app.adjTarget = s.name;
18885                        }
18886                    }
18887                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18888                        app.treatLikeActivity = true;
18889                    }
18890                    final ActivityRecord a = cr.activity;
18891                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18892                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18893                            (a.visible || a.state == ActivityState.RESUMED ||
18894                             a.state == ActivityState.PAUSING)) {
18895                            adj = ProcessList.FOREGROUND_APP_ADJ;
18896                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18897                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18898                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18899                                } else {
18900                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18901                                }
18902                            }
18903                            app.cached = false;
18904                            app.adjType = "service";
18905                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18906                                    .REASON_SERVICE_IN_USE;
18907                            app.adjSource = a;
18908                            app.adjSourceProcState = procState;
18909                            app.adjTarget = s.name;
18910                        }
18911                    }
18912                }
18913            }
18914        }
18915
18916        for (int provi = app.pubProviders.size()-1;
18917                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18918                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18919                        || procState > ActivityManager.PROCESS_STATE_TOP);
18920                provi--) {
18921            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18922            for (int i = cpr.connections.size()-1;
18923                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18924                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18925                            || procState > ActivityManager.PROCESS_STATE_TOP);
18926                    i--) {
18927                ContentProviderConnection conn = cpr.connections.get(i);
18928                ProcessRecord client = conn.client;
18929                if (client == app) {
18930                    // Being our own client is not interesting.
18931                    continue;
18932                }
18933                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18934                int clientProcState = client.curProcState;
18935                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18936                    // If the other app is cached for any reason, for purposes here
18937                    // we are going to consider it empty.
18938                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18939                }
18940                if (adj > clientAdj) {
18941                    if (app.hasShownUi && app != mHomeProcess
18942                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18943                        app.adjType = "cch-ui-provider";
18944                    } else {
18945                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18946                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18947                        app.adjType = "provider";
18948                    }
18949                    app.cached &= client.cached;
18950                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18951                            .REASON_PROVIDER_IN_USE;
18952                    app.adjSource = client;
18953                    app.adjSourceProcState = clientProcState;
18954                    app.adjTarget = cpr.name;
18955                }
18956                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18957                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18958                        // Special handling of clients who are in the top state.
18959                        // We *may* want to consider this process to be in the
18960                        // top state as well, but only if there is not another
18961                        // reason for it to be running.  Being on the top is a
18962                        // special state, meaning you are specifically running
18963                        // for the current top app.  If the process is already
18964                        // running in the background for some other reason, it
18965                        // is more important to continue considering it to be
18966                        // in the background state.
18967                        mayBeTop = true;
18968                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18969                    } else {
18970                        // Special handling for above-top states (persistent
18971                        // processes).  These should not bring the current process
18972                        // into the top state, since they are not on top.  Instead
18973                        // give them the best state after that.
18974                        clientProcState =
18975                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18976                    }
18977                }
18978                if (procState > clientProcState) {
18979                    procState = clientProcState;
18980                }
18981                if (client.curSchedGroup > schedGroup) {
18982                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18983                }
18984            }
18985            // If the provider has external (non-framework) process
18986            // dependencies, ensure that its adjustment is at least
18987            // FOREGROUND_APP_ADJ.
18988            if (cpr.hasExternalProcessHandles()) {
18989                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18990                    adj = ProcessList.FOREGROUND_APP_ADJ;
18991                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18992                    app.cached = false;
18993                    app.adjType = "provider";
18994                    app.adjTarget = cpr.name;
18995                }
18996                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18997                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18998                }
18999            }
19000        }
19001
19002        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19003            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19004                adj = ProcessList.PREVIOUS_APP_ADJ;
19005                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19006                app.cached = false;
19007                app.adjType = "provider";
19008            }
19009            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19010                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19011            }
19012        }
19013
19014        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19015            // A client of one of our services or providers is in the top state.  We
19016            // *may* want to be in the top state, but not if we are already running in
19017            // the background for some other reason.  For the decision here, we are going
19018            // to pick out a few specific states that we want to remain in when a client
19019            // is top (states that tend to be longer-term) and otherwise allow it to go
19020            // to the top state.
19021            switch (procState) {
19022                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19023                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19024                case ActivityManager.PROCESS_STATE_SERVICE:
19025                    // These all are longer-term states, so pull them up to the top
19026                    // of the background states, but not all the way to the top state.
19027                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19028                    break;
19029                default:
19030                    // Otherwise, top is a better choice, so take it.
19031                    procState = ActivityManager.PROCESS_STATE_TOP;
19032                    break;
19033            }
19034        }
19035
19036        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19037            if (app.hasClientActivities) {
19038                // This is a cached process, but with client activities.  Mark it so.
19039                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19040                app.adjType = "cch-client-act";
19041            } else if (app.treatLikeActivity) {
19042                // This is a cached process, but somebody wants us to treat it like it has
19043                // an activity, okay!
19044                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19045                app.adjType = "cch-as-act";
19046            }
19047        }
19048
19049        if (adj == ProcessList.SERVICE_ADJ) {
19050            if (doingAll) {
19051                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19052                mNewNumServiceProcs++;
19053                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19054                if (!app.serviceb) {
19055                    // This service isn't far enough down on the LRU list to
19056                    // normally be a B service, but if we are low on RAM and it
19057                    // is large we want to force it down since we would prefer to
19058                    // keep launcher over it.
19059                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19060                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19061                        app.serviceHighRam = true;
19062                        app.serviceb = true;
19063                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19064                    } else {
19065                        mNewNumAServiceProcs++;
19066                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19067                    }
19068                } else {
19069                    app.serviceHighRam = false;
19070                }
19071            }
19072            if (app.serviceb) {
19073                adj = ProcessList.SERVICE_B_ADJ;
19074            }
19075        }
19076
19077        app.curRawAdj = adj;
19078
19079        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19080        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19081        if (adj > app.maxAdj) {
19082            adj = app.maxAdj;
19083            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19084                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19085            }
19086        }
19087
19088        // Do final modification to adj.  Everything we do between here and applying
19089        // the final setAdj must be done in this function, because we will also use
19090        // it when computing the final cached adj later.  Note that we don't need to
19091        // worry about this for max adj above, since max adj will always be used to
19092        // keep it out of the cached vaues.
19093        app.curAdj = app.modifyRawOomAdj(adj);
19094        app.curSchedGroup = schedGroup;
19095        app.curProcState = procState;
19096        app.foregroundActivities = foregroundActivities;
19097
19098        return app.curRawAdj;
19099    }
19100
19101    /**
19102     * Record new PSS sample for a process.
19103     */
19104    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19105            long now) {
19106        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19107                swapPss * 1024);
19108        proc.lastPssTime = now;
19109        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19110        if (DEBUG_PSS) Slog.d(TAG_PSS,
19111                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19112                + " state=" + ProcessList.makeProcStateString(procState));
19113        if (proc.initialIdlePss == 0) {
19114            proc.initialIdlePss = pss;
19115        }
19116        proc.lastPss = pss;
19117        proc.lastSwapPss = swapPss;
19118        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19119            proc.lastCachedPss = pss;
19120            proc.lastCachedSwapPss = swapPss;
19121        }
19122
19123        final SparseArray<Pair<Long, String>> watchUids
19124                = mMemWatchProcesses.getMap().get(proc.processName);
19125        Long check = null;
19126        if (watchUids != null) {
19127            Pair<Long, String> val = watchUids.get(proc.uid);
19128            if (val == null) {
19129                val = watchUids.get(0);
19130            }
19131            if (val != null) {
19132                check = val.first;
19133            }
19134        }
19135        if (check != null) {
19136            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19137                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19138                if (!isDebuggable) {
19139                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19140                        isDebuggable = true;
19141                    }
19142                }
19143                if (isDebuggable) {
19144                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19145                    final ProcessRecord myProc = proc;
19146                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19147                    mMemWatchDumpProcName = proc.processName;
19148                    mMemWatchDumpFile = heapdumpFile.toString();
19149                    mMemWatchDumpPid = proc.pid;
19150                    mMemWatchDumpUid = proc.uid;
19151                    BackgroundThread.getHandler().post(new Runnable() {
19152                        @Override
19153                        public void run() {
19154                            revokeUriPermission(ActivityThread.currentActivityThread()
19155                                            .getApplicationThread(),
19156                                    DumpHeapActivity.JAVA_URI,
19157                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19158                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19159                                    UserHandle.myUserId());
19160                            ParcelFileDescriptor fd = null;
19161                            try {
19162                                heapdumpFile.delete();
19163                                fd = ParcelFileDescriptor.open(heapdumpFile,
19164                                        ParcelFileDescriptor.MODE_CREATE |
19165                                                ParcelFileDescriptor.MODE_TRUNCATE |
19166                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19167                                                ParcelFileDescriptor.MODE_APPEND);
19168                                IApplicationThread thread = myProc.thread;
19169                                if (thread != null) {
19170                                    try {
19171                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19172                                                "Requesting dump heap from "
19173                                                + myProc + " to " + heapdumpFile);
19174                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19175                                    } catch (RemoteException e) {
19176                                    }
19177                                }
19178                            } catch (FileNotFoundException e) {
19179                                e.printStackTrace();
19180                            } finally {
19181                                if (fd != null) {
19182                                    try {
19183                                        fd.close();
19184                                    } catch (IOException e) {
19185                                    }
19186                                }
19187                            }
19188                        }
19189                    });
19190                } else {
19191                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19192                            + ", but debugging not enabled");
19193                }
19194            }
19195        }
19196    }
19197
19198    /**
19199     * Schedule PSS collection of a process.
19200     */
19201    void requestPssLocked(ProcessRecord proc, int procState) {
19202        if (mPendingPssProcesses.contains(proc)) {
19203            return;
19204        }
19205        if (mPendingPssProcesses.size() == 0) {
19206            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19207        }
19208        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19209        proc.pssProcState = procState;
19210        mPendingPssProcesses.add(proc);
19211    }
19212
19213    /**
19214     * Schedule PSS collection of all processes.
19215     */
19216    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19217        if (!always) {
19218            if (now < (mLastFullPssTime +
19219                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19220                return;
19221            }
19222        }
19223        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19224        mLastFullPssTime = now;
19225        mFullPssPending = true;
19226        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19227        mPendingPssProcesses.clear();
19228        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19229            ProcessRecord app = mLruProcesses.get(i);
19230            if (app.thread == null
19231                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19232                continue;
19233            }
19234            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19235                app.pssProcState = app.setProcState;
19236                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19237                        mTestPssMode, isSleeping(), now);
19238                mPendingPssProcesses.add(app);
19239            }
19240        }
19241        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19242    }
19243
19244    public void setTestPssMode(boolean enabled) {
19245        synchronized (this) {
19246            mTestPssMode = enabled;
19247            if (enabled) {
19248                // Whenever we enable the mode, we want to take a snapshot all of current
19249                // process mem use.
19250                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19251            }
19252        }
19253    }
19254
19255    /**
19256     * Ask a given process to GC right now.
19257     */
19258    final void performAppGcLocked(ProcessRecord app) {
19259        try {
19260            app.lastRequestedGc = SystemClock.uptimeMillis();
19261            if (app.thread != null) {
19262                if (app.reportLowMemory) {
19263                    app.reportLowMemory = false;
19264                    app.thread.scheduleLowMemory();
19265                } else {
19266                    app.thread.processInBackground();
19267                }
19268            }
19269        } catch (Exception e) {
19270            // whatever.
19271        }
19272    }
19273
19274    /**
19275     * Returns true if things are idle enough to perform GCs.
19276     */
19277    private final boolean canGcNowLocked() {
19278        boolean processingBroadcasts = false;
19279        for (BroadcastQueue q : mBroadcastQueues) {
19280            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19281                processingBroadcasts = true;
19282            }
19283        }
19284        return !processingBroadcasts
19285                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19286    }
19287
19288    /**
19289     * Perform GCs on all processes that are waiting for it, but only
19290     * if things are idle.
19291     */
19292    final void performAppGcsLocked() {
19293        final int N = mProcessesToGc.size();
19294        if (N <= 0) {
19295            return;
19296        }
19297        if (canGcNowLocked()) {
19298            while (mProcessesToGc.size() > 0) {
19299                ProcessRecord proc = mProcessesToGc.remove(0);
19300                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19301                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19302                            <= SystemClock.uptimeMillis()) {
19303                        // To avoid spamming the system, we will GC processes one
19304                        // at a time, waiting a few seconds between each.
19305                        performAppGcLocked(proc);
19306                        scheduleAppGcsLocked();
19307                        return;
19308                    } else {
19309                        // It hasn't been long enough since we last GCed this
19310                        // process...  put it in the list to wait for its time.
19311                        addProcessToGcListLocked(proc);
19312                        break;
19313                    }
19314                }
19315            }
19316
19317            scheduleAppGcsLocked();
19318        }
19319    }
19320
19321    /**
19322     * If all looks good, perform GCs on all processes waiting for them.
19323     */
19324    final void performAppGcsIfAppropriateLocked() {
19325        if (canGcNowLocked()) {
19326            performAppGcsLocked();
19327            return;
19328        }
19329        // Still not idle, wait some more.
19330        scheduleAppGcsLocked();
19331    }
19332
19333    /**
19334     * Schedule the execution of all pending app GCs.
19335     */
19336    final void scheduleAppGcsLocked() {
19337        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19338
19339        if (mProcessesToGc.size() > 0) {
19340            // Schedule a GC for the time to the next process.
19341            ProcessRecord proc = mProcessesToGc.get(0);
19342            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19343
19344            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19345            long now = SystemClock.uptimeMillis();
19346            if (when < (now+GC_TIMEOUT)) {
19347                when = now + GC_TIMEOUT;
19348            }
19349            mHandler.sendMessageAtTime(msg, when);
19350        }
19351    }
19352
19353    /**
19354     * Add a process to the array of processes waiting to be GCed.  Keeps the
19355     * list in sorted order by the last GC time.  The process can't already be
19356     * on the list.
19357     */
19358    final void addProcessToGcListLocked(ProcessRecord proc) {
19359        boolean added = false;
19360        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19361            if (mProcessesToGc.get(i).lastRequestedGc <
19362                    proc.lastRequestedGc) {
19363                added = true;
19364                mProcessesToGc.add(i+1, proc);
19365                break;
19366            }
19367        }
19368        if (!added) {
19369            mProcessesToGc.add(0, proc);
19370        }
19371    }
19372
19373    /**
19374     * Set up to ask a process to GC itself.  This will either do it
19375     * immediately, or put it on the list of processes to gc the next
19376     * time things are idle.
19377     */
19378    final void scheduleAppGcLocked(ProcessRecord app) {
19379        long now = SystemClock.uptimeMillis();
19380        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19381            return;
19382        }
19383        if (!mProcessesToGc.contains(app)) {
19384            addProcessToGcListLocked(app);
19385            scheduleAppGcsLocked();
19386        }
19387    }
19388
19389    final void checkExcessivePowerUsageLocked(boolean doKills) {
19390        updateCpuStatsNow();
19391
19392        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19393        boolean doWakeKills = doKills;
19394        boolean doCpuKills = doKills;
19395        if (mLastPowerCheckRealtime == 0) {
19396            doWakeKills = false;
19397        }
19398        if (mLastPowerCheckUptime == 0) {
19399            doCpuKills = false;
19400        }
19401        if (stats.isScreenOn()) {
19402            doWakeKills = false;
19403        }
19404        final long curRealtime = SystemClock.elapsedRealtime();
19405        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19406        final long curUptime = SystemClock.uptimeMillis();
19407        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19408        mLastPowerCheckRealtime = curRealtime;
19409        mLastPowerCheckUptime = curUptime;
19410        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19411            doWakeKills = false;
19412        }
19413        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19414            doCpuKills = false;
19415        }
19416        int i = mLruProcesses.size();
19417        while (i > 0) {
19418            i--;
19419            ProcessRecord app = mLruProcesses.get(i);
19420            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19421                long wtime;
19422                synchronized (stats) {
19423                    wtime = stats.getProcessWakeTime(app.info.uid,
19424                            app.pid, curRealtime);
19425                }
19426                long wtimeUsed = wtime - app.lastWakeTime;
19427                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19428                if (DEBUG_POWER) {
19429                    StringBuilder sb = new StringBuilder(128);
19430                    sb.append("Wake for ");
19431                    app.toShortString(sb);
19432                    sb.append(": over ");
19433                    TimeUtils.formatDuration(realtimeSince, sb);
19434                    sb.append(" used ");
19435                    TimeUtils.formatDuration(wtimeUsed, sb);
19436                    sb.append(" (");
19437                    sb.append((wtimeUsed*100)/realtimeSince);
19438                    sb.append("%)");
19439                    Slog.i(TAG_POWER, sb.toString());
19440                    sb.setLength(0);
19441                    sb.append("CPU for ");
19442                    app.toShortString(sb);
19443                    sb.append(": over ");
19444                    TimeUtils.formatDuration(uptimeSince, sb);
19445                    sb.append(" used ");
19446                    TimeUtils.formatDuration(cputimeUsed, sb);
19447                    sb.append(" (");
19448                    sb.append((cputimeUsed*100)/uptimeSince);
19449                    sb.append("%)");
19450                    Slog.i(TAG_POWER, sb.toString());
19451                }
19452                // If a process has held a wake lock for more
19453                // than 50% of the time during this period,
19454                // that sounds bad.  Kill!
19455                if (doWakeKills && realtimeSince > 0
19456                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19457                    synchronized (stats) {
19458                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19459                                realtimeSince, wtimeUsed);
19460                    }
19461                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19462                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19463                } else if (doCpuKills && uptimeSince > 0
19464                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19465                    synchronized (stats) {
19466                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19467                                uptimeSince, cputimeUsed);
19468                    }
19469                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19470                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19471                } else {
19472                    app.lastWakeTime = wtime;
19473                    app.lastCpuTime = app.curCpuTime;
19474                }
19475            }
19476        }
19477    }
19478
19479    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19480            long nowElapsed) {
19481        boolean success = true;
19482
19483        if (app.curRawAdj != app.setRawAdj) {
19484            app.setRawAdj = app.curRawAdj;
19485        }
19486
19487        int changes = 0;
19488
19489        if (app.curAdj != app.setAdj) {
19490            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19491            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19492                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19493                    + app.adjType);
19494            app.setAdj = app.curAdj;
19495        }
19496
19497        if (app.setSchedGroup != app.curSchedGroup) {
19498            app.setSchedGroup = app.curSchedGroup;
19499            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19500                    "Setting sched group of " + app.processName
19501                    + " to " + app.curSchedGroup);
19502            if (app.waitingToKill != null && app.curReceiver == null
19503                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19504                app.kill(app.waitingToKill, true);
19505                success = false;
19506            } else {
19507                int processGroup;
19508                switch (app.curSchedGroup) {
19509                    case ProcessList.SCHED_GROUP_BACKGROUND:
19510                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19511                        break;
19512                    case ProcessList.SCHED_GROUP_TOP_APP:
19513                        processGroup = Process.THREAD_GROUP_TOP_APP;
19514                        break;
19515                    default:
19516                        processGroup = Process.THREAD_GROUP_DEFAULT;
19517                        break;
19518                }
19519                if (true) {
19520                    long oldId = Binder.clearCallingIdentity();
19521                    try {
19522                        Process.setProcessGroup(app.pid, processGroup);
19523                    } catch (Exception e) {
19524                        Slog.w(TAG, "Failed setting process group of " + app.pid
19525                                + " to " + app.curSchedGroup);
19526                        e.printStackTrace();
19527                    } finally {
19528                        Binder.restoreCallingIdentity(oldId);
19529                    }
19530                } else {
19531                    if (app.thread != null) {
19532                        try {
19533                            app.thread.setSchedulingGroup(processGroup);
19534                        } catch (RemoteException e) {
19535                        }
19536                    }
19537                }
19538            }
19539        }
19540        if (app.repForegroundActivities != app.foregroundActivities) {
19541            app.repForegroundActivities = app.foregroundActivities;
19542            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19543        }
19544        if (app.repProcState != app.curProcState) {
19545            app.repProcState = app.curProcState;
19546            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19547            if (app.thread != null) {
19548                try {
19549                    if (false) {
19550                        //RuntimeException h = new RuntimeException("here");
19551                        Slog.i(TAG, "Sending new process state " + app.repProcState
19552                                + " to " + app /*, h*/);
19553                    }
19554                    app.thread.setProcessState(app.repProcState);
19555                } catch (RemoteException e) {
19556                }
19557            }
19558        }
19559        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19560                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19561            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19562                // Experimental code to more aggressively collect pss while
19563                // running test...  the problem is that this tends to collect
19564                // the data right when a process is transitioning between process
19565                // states, which well tend to give noisy data.
19566                long start = SystemClock.uptimeMillis();
19567                long pss = Debug.getPss(app.pid, mTmpLong, null);
19568                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19569                mPendingPssProcesses.remove(app);
19570                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19571                        + " to " + app.curProcState + ": "
19572                        + (SystemClock.uptimeMillis()-start) + "ms");
19573            }
19574            app.lastStateTime = now;
19575            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19576                    mTestPssMode, isSleeping(), now);
19577            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19578                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19579                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19580                    + (app.nextPssTime-now) + ": " + app);
19581        } else {
19582            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19583                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19584                    mTestPssMode)))) {
19585                requestPssLocked(app, app.setProcState);
19586                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19587                        mTestPssMode, isSleeping(), now);
19588            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19589                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19590        }
19591        if (app.setProcState != app.curProcState) {
19592            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19593                    "Proc state change of " + app.processName
19594                            + " to " + app.curProcState);
19595            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19596            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19597            if (setImportant && !curImportant) {
19598                // This app is no longer something we consider important enough to allow to
19599                // use arbitrary amounts of battery power.  Note
19600                // its current wake lock time to later know to kill it if
19601                // it is not behaving well.
19602                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19603                synchronized (stats) {
19604                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19605                            app.pid, nowElapsed);
19606                }
19607                app.lastCpuTime = app.curCpuTime;
19608
19609            }
19610            // Inform UsageStats of important process state change
19611            // Must be called before updating setProcState
19612            maybeUpdateUsageStatsLocked(app, nowElapsed);
19613
19614            app.setProcState = app.curProcState;
19615            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19616                app.notCachedSinceIdle = false;
19617            }
19618            if (!doingAll) {
19619                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19620            } else {
19621                app.procStateChanged = true;
19622            }
19623        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19624                > USAGE_STATS_INTERACTION_INTERVAL) {
19625            // For apps that sit around for a long time in the interactive state, we need
19626            // to report this at least once a day so they don't go idle.
19627            maybeUpdateUsageStatsLocked(app, nowElapsed);
19628        }
19629
19630        if (changes != 0) {
19631            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19632                    "Changes in " + app + ": " + changes);
19633            int i = mPendingProcessChanges.size()-1;
19634            ProcessChangeItem item = null;
19635            while (i >= 0) {
19636                item = mPendingProcessChanges.get(i);
19637                if (item.pid == app.pid) {
19638                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19639                            "Re-using existing item: " + item);
19640                    break;
19641                }
19642                i--;
19643            }
19644            if (i < 0) {
19645                // No existing item in pending changes; need a new one.
19646                final int NA = mAvailProcessChanges.size();
19647                if (NA > 0) {
19648                    item = mAvailProcessChanges.remove(NA-1);
19649                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19650                            "Retrieving available item: " + item);
19651                } else {
19652                    item = new ProcessChangeItem();
19653                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19654                            "Allocating new item: " + item);
19655                }
19656                item.changes = 0;
19657                item.pid = app.pid;
19658                item.uid = app.info.uid;
19659                if (mPendingProcessChanges.size() == 0) {
19660                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19661                            "*** Enqueueing dispatch processes changed!");
19662                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19663                }
19664                mPendingProcessChanges.add(item);
19665            }
19666            item.changes |= changes;
19667            item.processState = app.repProcState;
19668            item.foregroundActivities = app.repForegroundActivities;
19669            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19670                    "Item " + Integer.toHexString(System.identityHashCode(item))
19671                    + " " + app.toShortString() + ": changes=" + item.changes
19672                    + " procState=" + item.processState
19673                    + " foreground=" + item.foregroundActivities
19674                    + " type=" + app.adjType + " source=" + app.adjSource
19675                    + " target=" + app.adjTarget);
19676        }
19677
19678        return success;
19679    }
19680
19681    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19682        final UidRecord.ChangeItem pendingChange;
19683        if (uidRec == null || uidRec.pendingChange == null) {
19684            if (mPendingUidChanges.size() == 0) {
19685                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19686                        "*** Enqueueing dispatch uid changed!");
19687                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19688            }
19689            final int NA = mAvailUidChanges.size();
19690            if (NA > 0) {
19691                pendingChange = mAvailUidChanges.remove(NA-1);
19692                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19693                        "Retrieving available item: " + pendingChange);
19694            } else {
19695                pendingChange = new UidRecord.ChangeItem();
19696                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19697                        "Allocating new item: " + pendingChange);
19698            }
19699            if (uidRec != null) {
19700                uidRec.pendingChange = pendingChange;
19701                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19702                    // If this uid is going away, and we haven't yet reported it is gone,
19703                    // then do so now.
19704                    change = UidRecord.CHANGE_GONE_IDLE;
19705                }
19706            } else if (uid < 0) {
19707                throw new IllegalArgumentException("No UidRecord or uid");
19708            }
19709            pendingChange.uidRecord = uidRec;
19710            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19711            mPendingUidChanges.add(pendingChange);
19712        } else {
19713            pendingChange = uidRec.pendingChange;
19714            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19715                change = UidRecord.CHANGE_GONE_IDLE;
19716            }
19717        }
19718        pendingChange.change = change;
19719        pendingChange.processState = uidRec != null
19720                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19721    }
19722
19723    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19724            String authority) {
19725        if (app == null) return;
19726        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19727            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19728            if (userState == null) return;
19729            final long now = SystemClock.elapsedRealtime();
19730            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19731            if (lastReported == null || lastReported < now - 60 * 1000L) {
19732                mUsageStatsService.reportContentProviderUsage(
19733                        authority, providerPkgName, app.userId);
19734                userState.mProviderLastReportedFg.put(authority, now);
19735            }
19736        }
19737    }
19738
19739    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19740        if (DEBUG_USAGE_STATS) {
19741            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19742                    + "] state changes: old = " + app.setProcState + ", new = "
19743                    + app.curProcState);
19744        }
19745        if (mUsageStatsService == null) {
19746            return;
19747        }
19748        boolean isInteraction;
19749        // To avoid some abuse patterns, we are going to be careful about what we consider
19750        // to be an app interaction.  Being the top activity doesn't count while the display
19751        // is sleeping, nor do short foreground services.
19752        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19753            isInteraction = true;
19754            app.fgInteractionTime = 0;
19755        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19756            if (app.fgInteractionTime == 0) {
19757                app.fgInteractionTime = nowElapsed;
19758                isInteraction = false;
19759            } else {
19760                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19761            }
19762        } else {
19763            isInteraction = app.curProcState
19764                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19765            app.fgInteractionTime = 0;
19766        }
19767        if (isInteraction && (!app.reportedInteraction
19768                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19769            app.interactionEventTime = nowElapsed;
19770            String[] packages = app.getPackageList();
19771            if (packages != null) {
19772                for (int i = 0; i < packages.length; i++) {
19773                    mUsageStatsService.reportEvent(packages[i], app.userId,
19774                            UsageEvents.Event.SYSTEM_INTERACTION);
19775                }
19776            }
19777        }
19778        app.reportedInteraction = isInteraction;
19779        if (!isInteraction) {
19780            app.interactionEventTime = 0;
19781        }
19782    }
19783
19784    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19785        if (proc.thread != null) {
19786            if (proc.baseProcessTracker != null) {
19787                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19788            }
19789        }
19790    }
19791
19792    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19793            ProcessRecord TOP_APP, boolean doingAll, long now) {
19794        if (app.thread == null) {
19795            return false;
19796        }
19797
19798        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19799
19800        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19801    }
19802
19803    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19804            boolean oomAdj) {
19805        if (isForeground != proc.foregroundServices) {
19806            proc.foregroundServices = isForeground;
19807            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19808                    proc.info.uid);
19809            if (isForeground) {
19810                if (curProcs == null) {
19811                    curProcs = new ArrayList<ProcessRecord>();
19812                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19813                }
19814                if (!curProcs.contains(proc)) {
19815                    curProcs.add(proc);
19816                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19817                            proc.info.packageName, proc.info.uid);
19818                }
19819            } else {
19820                if (curProcs != null) {
19821                    if (curProcs.remove(proc)) {
19822                        mBatteryStatsService.noteEvent(
19823                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19824                                proc.info.packageName, proc.info.uid);
19825                        if (curProcs.size() <= 0) {
19826                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19827                        }
19828                    }
19829                }
19830            }
19831            if (oomAdj) {
19832                updateOomAdjLocked();
19833            }
19834        }
19835    }
19836
19837    private final ActivityRecord resumedAppLocked() {
19838        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19839        String pkg;
19840        int uid;
19841        if (act != null) {
19842            pkg = act.packageName;
19843            uid = act.info.applicationInfo.uid;
19844        } else {
19845            pkg = null;
19846            uid = -1;
19847        }
19848        // Has the UID or resumed package name changed?
19849        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19850                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19851            if (mCurResumedPackage != null) {
19852                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19853                        mCurResumedPackage, mCurResumedUid);
19854            }
19855            mCurResumedPackage = pkg;
19856            mCurResumedUid = uid;
19857            if (mCurResumedPackage != null) {
19858                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19859                        mCurResumedPackage, mCurResumedUid);
19860            }
19861        }
19862        return act;
19863    }
19864
19865    final boolean updateOomAdjLocked(ProcessRecord app) {
19866        final ActivityRecord TOP_ACT = resumedAppLocked();
19867        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19868        final boolean wasCached = app.cached;
19869
19870        mAdjSeq++;
19871
19872        // This is the desired cached adjusment we want to tell it to use.
19873        // If our app is currently cached, we know it, and that is it.  Otherwise,
19874        // we don't know it yet, and it needs to now be cached we will then
19875        // need to do a complete oom adj.
19876        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19877                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19878        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19879                SystemClock.uptimeMillis());
19880        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19881            // Changed to/from cached state, so apps after it in the LRU
19882            // list may also be changed.
19883            updateOomAdjLocked();
19884        }
19885        return success;
19886    }
19887
19888    final void updateOomAdjLocked() {
19889        final ActivityRecord TOP_ACT = resumedAppLocked();
19890        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19891        final long now = SystemClock.uptimeMillis();
19892        final long nowElapsed = SystemClock.elapsedRealtime();
19893        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19894        final int N = mLruProcesses.size();
19895
19896        if (false) {
19897            RuntimeException e = new RuntimeException();
19898            e.fillInStackTrace();
19899            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19900        }
19901
19902        // Reset state in all uid records.
19903        for (int i=mActiveUids.size()-1; i>=0; i--) {
19904            final UidRecord uidRec = mActiveUids.valueAt(i);
19905            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19906                    "Starting update of " + uidRec);
19907            uidRec.reset();
19908        }
19909
19910        mStackSupervisor.rankTaskLayersIfNeeded();
19911
19912        mAdjSeq++;
19913        mNewNumServiceProcs = 0;
19914        mNewNumAServiceProcs = 0;
19915
19916        final int emptyProcessLimit;
19917        final int cachedProcessLimit;
19918        if (mProcessLimit <= 0) {
19919            emptyProcessLimit = cachedProcessLimit = 0;
19920        } else if (mProcessLimit == 1) {
19921            emptyProcessLimit = 1;
19922            cachedProcessLimit = 0;
19923        } else {
19924            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19925            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19926        }
19927
19928        // Let's determine how many processes we have running vs.
19929        // how many slots we have for background processes; we may want
19930        // to put multiple processes in a slot of there are enough of
19931        // them.
19932        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19933                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19934        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19935        if (numEmptyProcs > cachedProcessLimit) {
19936            // If there are more empty processes than our limit on cached
19937            // processes, then use the cached process limit for the factor.
19938            // This ensures that the really old empty processes get pushed
19939            // down to the bottom, so if we are running low on memory we will
19940            // have a better chance at keeping around more cached processes
19941            // instead of a gazillion empty processes.
19942            numEmptyProcs = cachedProcessLimit;
19943        }
19944        int emptyFactor = numEmptyProcs/numSlots;
19945        if (emptyFactor < 1) emptyFactor = 1;
19946        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19947        if (cachedFactor < 1) cachedFactor = 1;
19948        int stepCached = 0;
19949        int stepEmpty = 0;
19950        int numCached = 0;
19951        int numEmpty = 0;
19952        int numTrimming = 0;
19953
19954        mNumNonCachedProcs = 0;
19955        mNumCachedHiddenProcs = 0;
19956
19957        // First update the OOM adjustment for each of the
19958        // application processes based on their current state.
19959        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19960        int nextCachedAdj = curCachedAdj+1;
19961        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19962        int nextEmptyAdj = curEmptyAdj+2;
19963        for (int i=N-1; i>=0; i--) {
19964            ProcessRecord app = mLruProcesses.get(i);
19965            if (!app.killedByAm && app.thread != null) {
19966                app.procStateChanged = false;
19967                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19968
19969                // If we haven't yet assigned the final cached adj
19970                // to the process, do that now.
19971                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19972                    switch (app.curProcState) {
19973                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19974                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19975                            // This process is a cached process holding activities...
19976                            // assign it the next cached value for that type, and then
19977                            // step that cached level.
19978                            app.curRawAdj = curCachedAdj;
19979                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19980                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19981                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19982                                    + ")");
19983                            if (curCachedAdj != nextCachedAdj) {
19984                                stepCached++;
19985                                if (stepCached >= cachedFactor) {
19986                                    stepCached = 0;
19987                                    curCachedAdj = nextCachedAdj;
19988                                    nextCachedAdj += 2;
19989                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19990                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19991                                    }
19992                                }
19993                            }
19994                            break;
19995                        default:
19996                            // For everything else, assign next empty cached process
19997                            // level and bump that up.  Note that this means that
19998                            // long-running services that have dropped down to the
19999                            // cached level will be treated as empty (since their process
20000                            // state is still as a service), which is what we want.
20001                            app.curRawAdj = curEmptyAdj;
20002                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20003                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20004                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20005                                    + ")");
20006                            if (curEmptyAdj != nextEmptyAdj) {
20007                                stepEmpty++;
20008                                if (stepEmpty >= emptyFactor) {
20009                                    stepEmpty = 0;
20010                                    curEmptyAdj = nextEmptyAdj;
20011                                    nextEmptyAdj += 2;
20012                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20013                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20014                                    }
20015                                }
20016                            }
20017                            break;
20018                    }
20019                }
20020
20021                applyOomAdjLocked(app, true, now, nowElapsed);
20022
20023                // Count the number of process types.
20024                switch (app.curProcState) {
20025                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20026                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20027                        mNumCachedHiddenProcs++;
20028                        numCached++;
20029                        if (numCached > cachedProcessLimit) {
20030                            app.kill("cached #" + numCached, true);
20031                        }
20032                        break;
20033                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20034                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20035                                && app.lastActivityTime < oldTime) {
20036                            app.kill("empty for "
20037                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20038                                    / 1000) + "s", true);
20039                        } else {
20040                            numEmpty++;
20041                            if (numEmpty > emptyProcessLimit) {
20042                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
20043                            }
20044                        }
20045                        break;
20046                    default:
20047                        mNumNonCachedProcs++;
20048                        break;
20049                }
20050
20051                if (app.isolated && app.services.size() <= 0) {
20052                    // If this is an isolated process, and there are no
20053                    // services running in it, then the process is no longer
20054                    // needed.  We agressively kill these because we can by
20055                    // definition not re-use the same process again, and it is
20056                    // good to avoid having whatever code was running in them
20057                    // left sitting around after no longer needed.
20058                    app.kill("isolated not needed", true);
20059                } else {
20060                    // Keeping this process, update its uid.
20061                    final UidRecord uidRec = app.uidRecord;
20062                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20063                        uidRec.curProcState = app.curProcState;
20064                    }
20065                }
20066
20067                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20068                        && !app.killedByAm) {
20069                    numTrimming++;
20070                }
20071            }
20072        }
20073
20074        mNumServiceProcs = mNewNumServiceProcs;
20075
20076        // Now determine the memory trimming level of background processes.
20077        // Unfortunately we need to start at the back of the list to do this
20078        // properly.  We only do this if the number of background apps we
20079        // are managing to keep around is less than half the maximum we desire;
20080        // if we are keeping a good number around, we'll let them use whatever
20081        // memory they want.
20082        final int numCachedAndEmpty = numCached + numEmpty;
20083        int memFactor;
20084        if (numCached <= ProcessList.TRIM_CACHED_APPS
20085                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20086            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20087                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20088            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20089                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20090            } else {
20091                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20092            }
20093        } else {
20094            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20095        }
20096        // We always allow the memory level to go up (better).  We only allow it to go
20097        // down if we are in a state where that is allowed, *and* the total number of processes
20098        // has gone down since last time.
20099        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20100                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20101                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20102        if (memFactor > mLastMemoryLevel) {
20103            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20104                memFactor = mLastMemoryLevel;
20105                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20106            }
20107        }
20108        mLastMemoryLevel = memFactor;
20109        mLastNumProcesses = mLruProcesses.size();
20110        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20111        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20112        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20113            if (mLowRamStartTime == 0) {
20114                mLowRamStartTime = now;
20115            }
20116            int step = 0;
20117            int fgTrimLevel;
20118            switch (memFactor) {
20119                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20120                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20121                    break;
20122                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20123                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20124                    break;
20125                default:
20126                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20127                    break;
20128            }
20129            int factor = numTrimming/3;
20130            int minFactor = 2;
20131            if (mHomeProcess != null) minFactor++;
20132            if (mPreviousProcess != null) minFactor++;
20133            if (factor < minFactor) factor = minFactor;
20134            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20135            for (int i=N-1; i>=0; i--) {
20136                ProcessRecord app = mLruProcesses.get(i);
20137                if (allChanged || app.procStateChanged) {
20138                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20139                    app.procStateChanged = false;
20140                }
20141                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20142                        && !app.killedByAm) {
20143                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20144                        try {
20145                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20146                                    "Trimming memory of " + app.processName + " to " + curLevel);
20147                            app.thread.scheduleTrimMemory(curLevel);
20148                        } catch (RemoteException e) {
20149                        }
20150                        if (false) {
20151                            // For now we won't do this; our memory trimming seems
20152                            // to be good enough at this point that destroying
20153                            // activities causes more harm than good.
20154                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20155                                    && app != mHomeProcess && app != mPreviousProcess) {
20156                                // Need to do this on its own message because the stack may not
20157                                // be in a consistent state at this point.
20158                                // For these apps we will also finish their activities
20159                                // to help them free memory.
20160                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20161                            }
20162                        }
20163                    }
20164                    app.trimMemoryLevel = curLevel;
20165                    step++;
20166                    if (step >= factor) {
20167                        step = 0;
20168                        switch (curLevel) {
20169                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20170                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20171                                break;
20172                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20173                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20174                                break;
20175                        }
20176                    }
20177                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20178                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20179                            && app.thread != null) {
20180                        try {
20181                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20182                                    "Trimming memory of heavy-weight " + app.processName
20183                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20184                            app.thread.scheduleTrimMemory(
20185                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20186                        } catch (RemoteException e) {
20187                        }
20188                    }
20189                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20190                } else {
20191                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20192                            || app.systemNoUi) && app.pendingUiClean) {
20193                        // If this application is now in the background and it
20194                        // had done UI, then give it the special trim level to
20195                        // have it free UI resources.
20196                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20197                        if (app.trimMemoryLevel < level && app.thread != null) {
20198                            try {
20199                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20200                                        "Trimming memory of bg-ui " + app.processName
20201                                        + " to " + level);
20202                                app.thread.scheduleTrimMemory(level);
20203                            } catch (RemoteException e) {
20204                            }
20205                        }
20206                        app.pendingUiClean = false;
20207                    }
20208                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20209                        try {
20210                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20211                                    "Trimming memory of fg " + app.processName
20212                                    + " to " + fgTrimLevel);
20213                            app.thread.scheduleTrimMemory(fgTrimLevel);
20214                        } catch (RemoteException e) {
20215                        }
20216                    }
20217                    app.trimMemoryLevel = fgTrimLevel;
20218                }
20219            }
20220        } else {
20221            if (mLowRamStartTime != 0) {
20222                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20223                mLowRamStartTime = 0;
20224            }
20225            for (int i=N-1; i>=0; i--) {
20226                ProcessRecord app = mLruProcesses.get(i);
20227                if (allChanged || app.procStateChanged) {
20228                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20229                    app.procStateChanged = false;
20230                }
20231                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20232                        || app.systemNoUi) && app.pendingUiClean) {
20233                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20234                            && app.thread != null) {
20235                        try {
20236                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20237                                    "Trimming memory of ui hidden " + app.processName
20238                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20239                            app.thread.scheduleTrimMemory(
20240                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20241                        } catch (RemoteException e) {
20242                        }
20243                    }
20244                    app.pendingUiClean = false;
20245                }
20246                app.trimMemoryLevel = 0;
20247            }
20248        }
20249
20250        if (mAlwaysFinishActivities) {
20251            // Need to do this on its own message because the stack may not
20252            // be in a consistent state at this point.
20253            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20254        }
20255
20256        if (allChanged) {
20257            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20258        }
20259
20260        // Update from any uid changes.
20261        for (int i=mActiveUids.size()-1; i>=0; i--) {
20262            final UidRecord uidRec = mActiveUids.valueAt(i);
20263            int uidChange = UidRecord.CHANGE_PROCSTATE;
20264            if (uidRec.setProcState != uidRec.curProcState) {
20265                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20266                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20267                        + " to " + uidRec.curProcState);
20268                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20269                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20270                        uidRec.lastBackgroundTime = nowElapsed;
20271                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20272                            // Note: the background settle time is in elapsed realtime, while
20273                            // the handler time base is uptime.  All this means is that we may
20274                            // stop background uids later than we had intended, but that only
20275                            // happens because the device was sleeping so we are okay anyway.
20276                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20277                        }
20278                    }
20279                } else {
20280                    if (uidRec.idle) {
20281                        uidChange = UidRecord.CHANGE_ACTIVE;
20282                        uidRec.idle = false;
20283                    }
20284                    uidRec.lastBackgroundTime = 0;
20285                }
20286                uidRec.setProcState = uidRec.curProcState;
20287                enqueueUidChangeLocked(uidRec, -1, uidChange);
20288                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20289            }
20290        }
20291
20292        if (mProcessStats.shouldWriteNowLocked(now)) {
20293            mHandler.post(new Runnable() {
20294                @Override public void run() {
20295                    synchronized (ActivityManagerService.this) {
20296                        mProcessStats.writeStateAsyncLocked();
20297                    }
20298                }
20299            });
20300        }
20301
20302        if (DEBUG_OOM_ADJ) {
20303            final long duration = SystemClock.uptimeMillis() - now;
20304            if (false) {
20305                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20306                        new RuntimeException("here").fillInStackTrace());
20307            } else {
20308                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20309            }
20310        }
20311    }
20312
20313    final void idleUids() {
20314        synchronized (this) {
20315            final long nowElapsed = SystemClock.elapsedRealtime();
20316            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20317            long nextTime = 0;
20318            for (int i=mActiveUids.size()-1; i>=0; i--) {
20319                final UidRecord uidRec = mActiveUids.valueAt(i);
20320                final long bgTime = uidRec.lastBackgroundTime;
20321                if (bgTime > 0 && !uidRec.idle) {
20322                    if (bgTime <= maxBgTime) {
20323                        uidRec.idle = true;
20324                        doStopUidLocked(uidRec.uid, uidRec);
20325                    } else {
20326                        if (nextTime == 0 || nextTime > bgTime) {
20327                            nextTime = bgTime;
20328                        }
20329                    }
20330                }
20331            }
20332            if (nextTime > 0) {
20333                mHandler.removeMessages(IDLE_UIDS_MSG);
20334                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20335                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20336            }
20337        }
20338    }
20339
20340    final void runInBackgroundDisabled(int uid) {
20341        synchronized (this) {
20342            UidRecord uidRec = mActiveUids.get(uid);
20343            if (uidRec != null) {
20344                // This uid is actually running...  should it be considered background now?
20345                if (uidRec.idle) {
20346                    doStopUidLocked(uidRec.uid, uidRec);
20347                }
20348            } else {
20349                // This uid isn't actually running...  still send a report about it being "stopped".
20350                doStopUidLocked(uid, null);
20351            }
20352        }
20353    }
20354
20355    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20356        mServices.stopInBackgroundLocked(uid);
20357        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20358    }
20359
20360    final void trimApplications() {
20361        synchronized (this) {
20362            int i;
20363
20364            // First remove any unused application processes whose package
20365            // has been removed.
20366            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20367                final ProcessRecord app = mRemovedProcesses.get(i);
20368                if (app.activities.size() == 0
20369                        && app.curReceiver == null && app.services.size() == 0) {
20370                    Slog.i(
20371                        TAG, "Exiting empty application process "
20372                        + app.processName + " ("
20373                        + (app.thread != null ? app.thread.asBinder() : null)
20374                        + ")\n");
20375                    if (app.pid > 0 && app.pid != MY_PID) {
20376                        app.kill("empty", false);
20377                    } else {
20378                        try {
20379                            app.thread.scheduleExit();
20380                        } catch (Exception e) {
20381                            // Ignore exceptions.
20382                        }
20383                    }
20384                    cleanUpApplicationRecordLocked(app, false, true, -1);
20385                    mRemovedProcesses.remove(i);
20386
20387                    if (app.persistent) {
20388                        addAppLocked(app.info, false, null /* ABI override */);
20389                    }
20390                }
20391            }
20392
20393            // Now update the oom adj for all processes.
20394            updateOomAdjLocked();
20395        }
20396    }
20397
20398    /** This method sends the specified signal to each of the persistent apps */
20399    public void signalPersistentProcesses(int sig) throws RemoteException {
20400        if (sig != Process.SIGNAL_USR1) {
20401            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20402        }
20403
20404        synchronized (this) {
20405            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20406                    != PackageManager.PERMISSION_GRANTED) {
20407                throw new SecurityException("Requires permission "
20408                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20409            }
20410
20411            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20412                ProcessRecord r = mLruProcesses.get(i);
20413                if (r.thread != null && r.persistent) {
20414                    Process.sendSignal(r.pid, sig);
20415                }
20416            }
20417        }
20418    }
20419
20420    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20421        if (proc == null || proc == mProfileProc) {
20422            proc = mProfileProc;
20423            profileType = mProfileType;
20424            clearProfilerLocked();
20425        }
20426        if (proc == null) {
20427            return;
20428        }
20429        try {
20430            proc.thread.profilerControl(false, null, profileType);
20431        } catch (RemoteException e) {
20432            throw new IllegalStateException("Process disappeared");
20433        }
20434    }
20435
20436    private void clearProfilerLocked() {
20437        if (mProfileFd != null) {
20438            try {
20439                mProfileFd.close();
20440            } catch (IOException e) {
20441            }
20442        }
20443        mProfileApp = null;
20444        mProfileProc = null;
20445        mProfileFile = null;
20446        mProfileType = 0;
20447        mAutoStopProfiler = false;
20448        mSamplingInterval = 0;
20449    }
20450
20451    public boolean profileControl(String process, int userId, boolean start,
20452            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20453
20454        try {
20455            synchronized (this) {
20456                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20457                // its own permission.
20458                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20459                        != PackageManager.PERMISSION_GRANTED) {
20460                    throw new SecurityException("Requires permission "
20461                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20462                }
20463
20464                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20465                    throw new IllegalArgumentException("null profile info or fd");
20466                }
20467
20468                ProcessRecord proc = null;
20469                if (process != null) {
20470                    proc = findProcessLocked(process, userId, "profileControl");
20471                }
20472
20473                if (start && (proc == null || proc.thread == null)) {
20474                    throw new IllegalArgumentException("Unknown process: " + process);
20475                }
20476
20477                if (start) {
20478                    stopProfilerLocked(null, 0);
20479                    setProfileApp(proc.info, proc.processName, profilerInfo);
20480                    mProfileProc = proc;
20481                    mProfileType = profileType;
20482                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20483                    try {
20484                        fd = fd.dup();
20485                    } catch (IOException e) {
20486                        fd = null;
20487                    }
20488                    profilerInfo.profileFd = fd;
20489                    proc.thread.profilerControl(start, profilerInfo, profileType);
20490                    fd = null;
20491                    mProfileFd = null;
20492                } else {
20493                    stopProfilerLocked(proc, profileType);
20494                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20495                        try {
20496                            profilerInfo.profileFd.close();
20497                        } catch (IOException e) {
20498                        }
20499                    }
20500                }
20501
20502                return true;
20503            }
20504        } catch (RemoteException e) {
20505            throw new IllegalStateException("Process disappeared");
20506        } finally {
20507            if (profilerInfo != null && profilerInfo.profileFd != null) {
20508                try {
20509                    profilerInfo.profileFd.close();
20510                } catch (IOException e) {
20511                }
20512            }
20513        }
20514    }
20515
20516    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20517        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20518                userId, true, ALLOW_FULL_ONLY, callName, null);
20519        ProcessRecord proc = null;
20520        try {
20521            int pid = Integer.parseInt(process);
20522            synchronized (mPidsSelfLocked) {
20523                proc = mPidsSelfLocked.get(pid);
20524            }
20525        } catch (NumberFormatException e) {
20526        }
20527
20528        if (proc == null) {
20529            ArrayMap<String, SparseArray<ProcessRecord>> all
20530                    = mProcessNames.getMap();
20531            SparseArray<ProcessRecord> procs = all.get(process);
20532            if (procs != null && procs.size() > 0) {
20533                proc = procs.valueAt(0);
20534                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20535                    for (int i=1; i<procs.size(); i++) {
20536                        ProcessRecord thisProc = procs.valueAt(i);
20537                        if (thisProc.userId == userId) {
20538                            proc = thisProc;
20539                            break;
20540                        }
20541                    }
20542                }
20543            }
20544        }
20545
20546        return proc;
20547    }
20548
20549    public boolean dumpHeap(String process, int userId, boolean managed,
20550            String path, ParcelFileDescriptor fd) throws RemoteException {
20551
20552        try {
20553            synchronized (this) {
20554                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20555                // its own permission (same as profileControl).
20556                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20557                        != PackageManager.PERMISSION_GRANTED) {
20558                    throw new SecurityException("Requires permission "
20559                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20560                }
20561
20562                if (fd == null) {
20563                    throw new IllegalArgumentException("null fd");
20564                }
20565
20566                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20567                if (proc == null || proc.thread == null) {
20568                    throw new IllegalArgumentException("Unknown process: " + process);
20569                }
20570
20571                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20572                if (!isDebuggable) {
20573                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20574                        throw new SecurityException("Process not debuggable: " + proc);
20575                    }
20576                }
20577
20578                proc.thread.dumpHeap(managed, path, fd);
20579                fd = null;
20580                return true;
20581            }
20582        } catch (RemoteException e) {
20583            throw new IllegalStateException("Process disappeared");
20584        } finally {
20585            if (fd != null) {
20586                try {
20587                    fd.close();
20588                } catch (IOException e) {
20589                }
20590            }
20591        }
20592    }
20593
20594    @Override
20595    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20596            String reportPackage) {
20597        if (processName != null) {
20598            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20599                    "setDumpHeapDebugLimit()");
20600        } else {
20601            synchronized (mPidsSelfLocked) {
20602                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20603                if (proc == null) {
20604                    throw new SecurityException("No process found for calling pid "
20605                            + Binder.getCallingPid());
20606                }
20607                if (!Build.IS_DEBUGGABLE
20608                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20609                    throw new SecurityException("Not running a debuggable build");
20610                }
20611                processName = proc.processName;
20612                uid = proc.uid;
20613                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20614                    throw new SecurityException("Package " + reportPackage + " is not running in "
20615                            + proc);
20616                }
20617            }
20618        }
20619        synchronized (this) {
20620            if (maxMemSize > 0) {
20621                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20622            } else {
20623                if (uid != 0) {
20624                    mMemWatchProcesses.remove(processName, uid);
20625                } else {
20626                    mMemWatchProcesses.getMap().remove(processName);
20627                }
20628            }
20629        }
20630    }
20631
20632    @Override
20633    public void dumpHeapFinished(String path) {
20634        synchronized (this) {
20635            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20636                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20637                        + " does not match last pid " + mMemWatchDumpPid);
20638                return;
20639            }
20640            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20641                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20642                        + " does not match last path " + mMemWatchDumpFile);
20643                return;
20644            }
20645            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20646            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20647        }
20648    }
20649
20650    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20651    public void monitor() {
20652        synchronized (this) { }
20653    }
20654
20655    void onCoreSettingsChange(Bundle settings) {
20656        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20657            ProcessRecord processRecord = mLruProcesses.get(i);
20658            try {
20659                if (processRecord.thread != null) {
20660                    processRecord.thread.setCoreSettings(settings);
20661                }
20662            } catch (RemoteException re) {
20663                /* ignore */
20664            }
20665        }
20666    }
20667
20668    // Multi-user methods
20669
20670    /**
20671     * Start user, if its not already running, but don't bring it to foreground.
20672     */
20673    @Override
20674    public boolean startUserInBackground(final int userId) {
20675        return mUserController.startUser(userId, /* foreground */ false);
20676    }
20677
20678    @Override
20679    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20680        return mUserController.unlockUser(userId, token, secret, new ProgressReporter(0, listener));
20681    }
20682
20683    @Override
20684    public boolean switchUser(final int targetUserId) {
20685        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20686        UserInfo currentUserInfo;
20687        UserInfo targetUserInfo;
20688        synchronized (this) {
20689            int currentUserId = mUserController.getCurrentUserIdLocked();
20690            currentUserInfo = mUserController.getUserInfo(currentUserId);
20691            targetUserInfo = mUserController.getUserInfo(targetUserId);
20692            if (targetUserInfo == null) {
20693                Slog.w(TAG, "No user info for user #" + targetUserId);
20694                return false;
20695            }
20696            if (!targetUserInfo.supportsSwitchTo()) {
20697                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20698                return false;
20699            }
20700            if (targetUserInfo.isManagedProfile()) {
20701                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20702                return false;
20703            }
20704            mUserController.setTargetUserIdLocked(targetUserId);
20705        }
20706        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20707        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20708        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20709        return true;
20710    }
20711
20712    void scheduleStartProfilesLocked() {
20713        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20714            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20715                    DateUtils.SECOND_IN_MILLIS);
20716        }
20717    }
20718
20719    @Override
20720    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20721        return mUserController.stopUser(userId, force, callback);
20722    }
20723
20724    @Override
20725    public UserInfo getCurrentUser() {
20726        return mUserController.getCurrentUser();
20727    }
20728
20729    @Override
20730    public boolean isUserRunning(int userId, int flags) {
20731        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20732                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20733            String msg = "Permission Denial: isUserRunning() from pid="
20734                    + Binder.getCallingPid()
20735                    + ", uid=" + Binder.getCallingUid()
20736                    + " requires " + INTERACT_ACROSS_USERS;
20737            Slog.w(TAG, msg);
20738            throw new SecurityException(msg);
20739        }
20740        synchronized (this) {
20741            return mUserController.isUserRunningLocked(userId, flags);
20742        }
20743    }
20744
20745    @Override
20746    public int[] getRunningUserIds() {
20747        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20748                != PackageManager.PERMISSION_GRANTED) {
20749            String msg = "Permission Denial: isUserRunning() from pid="
20750                    + Binder.getCallingPid()
20751                    + ", uid=" + Binder.getCallingUid()
20752                    + " requires " + INTERACT_ACROSS_USERS;
20753            Slog.w(TAG, msg);
20754            throw new SecurityException(msg);
20755        }
20756        synchronized (this) {
20757            return mUserController.getStartedUserArrayLocked();
20758        }
20759    }
20760
20761    @Override
20762    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20763        mUserController.registerUserSwitchObserver(observer);
20764    }
20765
20766    @Override
20767    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20768        mUserController.unregisterUserSwitchObserver(observer);
20769    }
20770
20771    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20772        if (info == null) return null;
20773        ApplicationInfo newInfo = new ApplicationInfo(info);
20774        newInfo.initForUser(userId);
20775        return newInfo;
20776    }
20777
20778    public boolean isUserStopped(int userId) {
20779        synchronized (this) {
20780            return mUserController.getStartedUserStateLocked(userId) == null;
20781        }
20782    }
20783
20784    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20785        if (aInfo == null
20786                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20787            return aInfo;
20788        }
20789
20790        ActivityInfo info = new ActivityInfo(aInfo);
20791        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20792        return info;
20793    }
20794
20795    private boolean processSanityChecksLocked(ProcessRecord process) {
20796        if (process == null || process.thread == null) {
20797            return false;
20798        }
20799
20800        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20801        if (!isDebuggable) {
20802            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20803                return false;
20804            }
20805        }
20806
20807        return true;
20808    }
20809
20810    public boolean startBinderTracking() throws RemoteException {
20811        synchronized (this) {
20812            mBinderTransactionTrackingEnabled = true;
20813            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20814            // permission (same as profileControl).
20815            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20816                    != PackageManager.PERMISSION_GRANTED) {
20817                throw new SecurityException("Requires permission "
20818                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20819            }
20820
20821            for (int i = 0; i < mLruProcesses.size(); i++) {
20822                ProcessRecord process = mLruProcesses.get(i);
20823                if (!processSanityChecksLocked(process)) {
20824                    continue;
20825                }
20826                try {
20827                    process.thread.startBinderTracking();
20828                } catch (RemoteException e) {
20829                    Log.v(TAG, "Process disappared");
20830                }
20831            }
20832            return true;
20833        }
20834    }
20835
20836    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20837        try {
20838            synchronized (this) {
20839                mBinderTransactionTrackingEnabled = false;
20840                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20841                // permission (same as profileControl).
20842                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20843                        != PackageManager.PERMISSION_GRANTED) {
20844                    throw new SecurityException("Requires permission "
20845                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20846                }
20847
20848                if (fd == null) {
20849                    throw new IllegalArgumentException("null fd");
20850                }
20851
20852                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20853                pw.println("Binder transaction traces for all processes.\n");
20854                for (ProcessRecord process : mLruProcesses) {
20855                    if (!processSanityChecksLocked(process)) {
20856                        continue;
20857                    }
20858
20859                    pw.println("Traces for process: " + process.processName);
20860                    pw.flush();
20861                    try {
20862                        TransferPipe tp = new TransferPipe();
20863                        try {
20864                            process.thread.stopBinderTrackingAndDump(
20865                                    tp.getWriteFd().getFileDescriptor());
20866                            tp.go(fd.getFileDescriptor());
20867                        } finally {
20868                            tp.kill();
20869                        }
20870                    } catch (IOException e) {
20871                        pw.println("Failure while dumping IPC traces from " + process +
20872                                ".  Exception: " + e);
20873                        pw.flush();
20874                    } catch (RemoteException e) {
20875                        pw.println("Got a RemoteException while dumping IPC traces from " +
20876                                process + ".  Exception: " + e);
20877                        pw.flush();
20878                    }
20879                }
20880                fd = null;
20881                return true;
20882            }
20883        } finally {
20884            if (fd != null) {
20885                try {
20886                    fd.close();
20887                } catch (IOException e) {
20888                }
20889            }
20890        }
20891    }
20892
20893    private final class LocalService extends ActivityManagerInternal {
20894        @Override
20895        public void onWakefulnessChanged(int wakefulness) {
20896            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20897        }
20898
20899        @Override
20900        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20901                String processName, String abiOverride, int uid, Runnable crashHandler) {
20902            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20903                    processName, abiOverride, uid, crashHandler);
20904        }
20905
20906        @Override
20907        public SleepToken acquireSleepToken(String tag) {
20908            Preconditions.checkNotNull(tag);
20909
20910            synchronized (ActivityManagerService.this) {
20911                SleepTokenImpl token = new SleepTokenImpl(tag);
20912                mSleepTokens.add(token);
20913                updateSleepIfNeededLocked();
20914                return token;
20915            }
20916        }
20917
20918        @Override
20919        public ComponentName getHomeActivityForUser(int userId) {
20920            synchronized (ActivityManagerService.this) {
20921                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20922                return homeActivity == null ? null : homeActivity.realActivity;
20923            }
20924        }
20925
20926        @Override
20927        public void onUserRemoved(int userId) {
20928            synchronized (ActivityManagerService.this) {
20929                ActivityManagerService.this.onUserStoppedLocked(userId);
20930            }
20931        }
20932
20933        @Override
20934        public void onLocalVoiceInteractionStarted(IBinder activity,
20935                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20936            synchronized (ActivityManagerService.this) {
20937                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20938                        voiceSession, voiceInteractor);
20939            }
20940        }
20941
20942        @Override
20943        public void notifyStartingWindowDrawn() {
20944            synchronized (ActivityManagerService.this) {
20945                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20946            }
20947        }
20948
20949        @Override
20950        public void notifyAppTransitionStarting(int reason) {
20951            synchronized (ActivityManagerService.this) {
20952                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20953            }
20954        }
20955
20956        @Override
20957        public void notifyAppTransitionFinished() {
20958            synchronized (ActivityManagerService.this) {
20959                mStackSupervisor.notifyAppTransitionDone();
20960            }
20961        }
20962
20963        @Override
20964        public void notifyAppTransitionCancelled() {
20965            synchronized (ActivityManagerService.this) {
20966                mStackSupervisor.notifyAppTransitionDone();
20967            }
20968        }
20969
20970        @Override
20971        public List<IBinder> getTopVisibleActivities() {
20972            synchronized (ActivityManagerService.this) {
20973                return mStackSupervisor.getTopVisibleActivities();
20974            }
20975        }
20976    }
20977
20978    private final class SleepTokenImpl extends SleepToken {
20979        private final String mTag;
20980        private final long mAcquireTime;
20981
20982        public SleepTokenImpl(String tag) {
20983            mTag = tag;
20984            mAcquireTime = SystemClock.uptimeMillis();
20985        }
20986
20987        @Override
20988        public void release() {
20989            synchronized (ActivityManagerService.this) {
20990                if (mSleepTokens.remove(this)) {
20991                    updateSleepIfNeededLocked();
20992                }
20993            }
20994        }
20995
20996        @Override
20997        public String toString() {
20998            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20999        }
21000    }
21001
21002    /**
21003     * An implementation of IAppTask, that allows an app to manage its own tasks via
21004     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21005     * only the process that calls getAppTasks() can call the AppTask methods.
21006     */
21007    class AppTaskImpl extends IAppTask.Stub {
21008        private int mTaskId;
21009        private int mCallingUid;
21010
21011        public AppTaskImpl(int taskId, int callingUid) {
21012            mTaskId = taskId;
21013            mCallingUid = callingUid;
21014        }
21015
21016        private void checkCaller() {
21017            if (mCallingUid != Binder.getCallingUid()) {
21018                throw new SecurityException("Caller " + mCallingUid
21019                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21020            }
21021        }
21022
21023        @Override
21024        public void finishAndRemoveTask() {
21025            checkCaller();
21026
21027            synchronized (ActivityManagerService.this) {
21028                long origId = Binder.clearCallingIdentity();
21029                try {
21030                    // We remove the task from recents to preserve backwards
21031                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21032                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21033                    }
21034                } finally {
21035                    Binder.restoreCallingIdentity(origId);
21036                }
21037            }
21038        }
21039
21040        @Override
21041        public ActivityManager.RecentTaskInfo getTaskInfo() {
21042            checkCaller();
21043
21044            synchronized (ActivityManagerService.this) {
21045                long origId = Binder.clearCallingIdentity();
21046                try {
21047                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21048                    if (tr == null) {
21049                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21050                    }
21051                    return createRecentTaskInfoFromTaskRecord(tr);
21052                } finally {
21053                    Binder.restoreCallingIdentity(origId);
21054                }
21055            }
21056        }
21057
21058        @Override
21059        public void moveToFront() {
21060            checkCaller();
21061            // Will bring task to front if it already has a root activity.
21062            final long origId = Binder.clearCallingIdentity();
21063            try {
21064                synchronized (this) {
21065                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21066                }
21067            } finally {
21068                Binder.restoreCallingIdentity(origId);
21069            }
21070        }
21071
21072        @Override
21073        public int startActivity(IBinder whoThread, String callingPackage,
21074                Intent intent, String resolvedType, Bundle bOptions) {
21075            checkCaller();
21076
21077            int callingUser = UserHandle.getCallingUserId();
21078            TaskRecord tr;
21079            IApplicationThread appThread;
21080            synchronized (ActivityManagerService.this) {
21081                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21082                if (tr == null) {
21083                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21084                }
21085                appThread = ApplicationThreadNative.asInterface(whoThread);
21086                if (appThread == null) {
21087                    throw new IllegalArgumentException("Bad app thread " + appThread);
21088                }
21089            }
21090            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21091                    resolvedType, null, null, null, null, 0, 0, null, null,
21092                    null, bOptions, false, callingUser, null, tr);
21093        }
21094
21095        @Override
21096        public void setExcludeFromRecents(boolean exclude) {
21097            checkCaller();
21098
21099            synchronized (ActivityManagerService.this) {
21100                long origId = Binder.clearCallingIdentity();
21101                try {
21102                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21103                    if (tr == null) {
21104                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21105                    }
21106                    Intent intent = tr.getBaseIntent();
21107                    if (exclude) {
21108                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21109                    } else {
21110                        intent.setFlags(intent.getFlags()
21111                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21112                    }
21113                } finally {
21114                    Binder.restoreCallingIdentity(origId);
21115                }
21116            }
21117        }
21118    }
21119
21120    /**
21121     * Kill processes for the user with id userId and that depend on the package named packageName
21122     */
21123    @Override
21124    public void killPackageDependents(String packageName, int userId) {
21125        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21126        if (packageName == null) {
21127            throw new NullPointerException(
21128                    "Cannot kill the dependents of a package without its name.");
21129        }
21130
21131        long callingId = Binder.clearCallingIdentity();
21132        IPackageManager pm = AppGlobals.getPackageManager();
21133        int pkgUid = -1;
21134        try {
21135            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21136        } catch (RemoteException e) {
21137        }
21138        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21139            throw new IllegalArgumentException(
21140                    "Cannot kill dependents of non-existing package " + packageName);
21141        }
21142        try {
21143            synchronized(this) {
21144                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21145                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21146                        "dep: " + packageName);
21147            }
21148        } finally {
21149            Binder.restoreCallingIdentity(callingId);
21150        }
21151    }
21152}
21153