ActivityManagerService.java revision 9323df6e469de5002cae168d24d776e79d7f6f4c
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.google.android.collect.Lists;
20import com.google.android.collect.Maps;
21import com.android.internal.R;
22import com.android.internal.annotations.GuardedBy;
23import com.android.internal.app.AssistUtils;
24import com.android.internal.app.DumpHeapActivity;
25import com.android.internal.app.IAppOpsCallback;
26import com.android.internal.app.IAppOpsService;
27import com.android.internal.app.IVoiceInteractor;
28import com.android.internal.app.ProcessMap;
29import com.android.internal.app.SystemUserHomeActivity;
30import com.android.internal.app.procstats.ProcessStats;
31import com.android.internal.os.BackgroundThread;
32import com.android.internal.os.BatteryStatsImpl;
33import com.android.internal.os.IResultReceiver;
34import com.android.internal.os.ProcessCpuTracker;
35import com.android.internal.os.TransferPipe;
36import com.android.internal.os.Zygote;
37import com.android.internal.os.InstallerConnection.InstallerException;
38import com.android.internal.util.ArrayUtils;
39import com.android.internal.util.FastPrintWriter;
40import com.android.internal.util.FastXmlSerializer;
41import com.android.internal.util.MemInfoReader;
42import com.android.internal.util.Preconditions;
43import com.android.internal.util.ProgressReporter;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.Notification;
101import android.app.NotificationManager;
102import android.app.PendingIntent;
103import android.app.ProfilerInfo;
104import android.app.admin.DevicePolicyManager;
105import android.app.admin.DevicePolicyManagerInternal;
106import android.app.assist.AssistContent;
107import android.app.assist.AssistStructure;
108import android.app.backup.IBackupManager;
109import android.app.usage.UsageEvents;
110import android.app.usage.UsageStatsManagerInternal;
111import android.appwidget.AppWidgetManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.PackageManager.NameNotFoundException;
136import android.content.pm.PackageManagerInternal;
137import android.content.pm.ParceledListSlice;
138import android.content.pm.PathPermission;
139import android.content.pm.PermissionInfo;
140import android.content.pm.ProviderInfo;
141import android.content.pm.ResolveInfo;
142import android.content.pm.ServiceInfo;
143import android.content.pm.UserInfo;
144import android.content.res.CompatibilityInfo;
145import android.content.res.Configuration;
146import android.content.res.Resources;
147import android.database.ContentObserver;
148import android.graphics.Bitmap;
149import android.graphics.Point;
150import android.graphics.Rect;
151import android.location.LocationManager;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.BatteryStats;
156import android.os.Binder;
157import android.os.Build;
158import android.os.Bundle;
159import android.os.Debug;
160import android.os.DropBoxManager;
161import android.os.Environment;
162import android.os.FactoryTest;
163import android.os.FileObserver;
164import android.os.FileUtils;
165import android.os.Handler;
166import android.os.IBinder;
167import android.os.IPermissionController;
168import android.os.IProcessInfoService;
169import android.os.IProgressListener;
170import android.os.Looper;
171import android.os.Message;
172import android.os.Parcel;
173import android.os.ParcelFileDescriptor;
174import android.os.PersistableBundle;
175import android.os.PowerManager;
176import android.os.PowerManagerInternal;
177import android.os.Process;
178import android.os.RemoteCallbackList;
179import android.os.RemoteException;
180import android.os.ResultReceiver;
181import android.os.ServiceManager;
182import android.os.StrictMode;
183import android.os.SystemClock;
184import android.os.SystemProperties;
185import android.os.Trace;
186import android.os.TransactionTooLargeException;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.os.WorkSource;
191import android.os.storage.IMountService;
192import android.os.storage.MountServiceInternal;
193import android.os.storage.StorageManager;
194import android.provider.Settings;
195import android.service.voice.IVoiceInteractionSession;
196import android.service.voice.VoiceInteractionManagerInternal;
197import android.service.voice.VoiceInteractionSession;
198import android.text.format.DateUtils;
199import android.text.format.Time;
200import android.util.ArrayMap;
201import android.util.ArraySet;
202import android.util.AtomicFile;
203import android.util.DebugUtils;
204import android.util.EventLog;
205import android.util.LocaleList;
206import android.util.Log;
207import android.util.Pair;
208import android.util.PrintWriterPrinter;
209import android.util.Slog;
210import android.util.SparseArray;
211import android.util.TimeUtils;
212import android.util.Xml;
213import android.view.Display;
214import android.view.Gravity;
215import android.view.LayoutInflater;
216import android.view.View;
217import android.view.WindowManager;
218
219import java.io.File;
220import java.io.FileDescriptor;
221import java.io.FileInputStream;
222import java.io.FileNotFoundException;
223import java.io.FileOutputStream;
224import java.io.IOException;
225import java.io.InputStreamReader;
226import java.io.PrintWriter;
227import java.io.StringWriter;
228import java.lang.ref.WeakReference;
229import java.nio.charset.StandardCharsets;
230import java.util.ArrayList;
231import java.util.Arrays;
232import java.util.Collections;
233import java.util.Comparator;
234import java.util.HashMap;
235import java.util.HashSet;
236import java.util.Iterator;
237import java.util.List;
238import java.util.Locale;
239import java.util.Map;
240import java.util.Set;
241import java.util.concurrent.atomic.AtomicBoolean;
242import java.util.concurrent.atomic.AtomicLong;
243
244import dalvik.system.VMRuntime;
245
246import libcore.io.IoUtils;
247import libcore.util.EmptyArray;
248
249import static android.Manifest.permission.INTERACT_ACROSS_USERS;
250import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
251import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
252import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
253import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
254import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
255import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
256import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
257import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
258import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
259import static android.app.ActivityManager.StackId.HOME_STACK_ID;
260import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
261import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
262import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
263import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
264import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
265import static android.content.pm.PackageManager.GET_PROVIDERS;
266import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
267import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
268import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
269import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
270import static android.content.pm.PackageManager.PERMISSION_GRANTED;
271import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
272import static android.provider.Settings.Global.DEBUG_APP;
273import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
274import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
275import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
276import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
277import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
278import static android.provider.Settings.System.FONT_SCALE;
279import static com.android.internal.util.XmlUtils.readBooleanAttribute;
280import static com.android.internal.util.XmlUtils.readIntAttribute;
281import static com.android.internal.util.XmlUtils.readLongAttribute;
282import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
283import static com.android.internal.util.XmlUtils.writeIntAttribute;
284import static com.android.internal.util.XmlUtils.writeLongAttribute;
285import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
317import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
341import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
342import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
343import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
344import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
345import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
346import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
347import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
348import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
349import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
350import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
351import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
352import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
353import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
354import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
355import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
356import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
357import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
358import static org.xmlpull.v1.XmlPullParser.START_TAG;
359
360public final class ActivityManagerService extends ActivityManagerNative
361        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
362
363    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
364    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
365    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
366    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
367    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
368    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
369    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
370    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
371    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
372    private static final String TAG_LRU = TAG + POSTFIX_LRU;
373    private static final String TAG_MU = TAG + POSTFIX_MU;
374    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
375    private static final String TAG_POWER = TAG + POSTFIX_POWER;
376    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
377    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
378    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
379    private static final String TAG_PSS = TAG + POSTFIX_PSS;
380    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
381    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
382    private static final String TAG_STACK = TAG + POSTFIX_STACK;
383    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
384    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
385    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
386    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
387    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
388
389    /** Control over CPU and battery monitoring */
390    // write battery stats every 30 minutes.
391    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
392    static final boolean MONITOR_CPU_USAGE = true;
393    // don't sample cpu less than every 5 seconds.
394    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
395    // wait possibly forever for next cpu sample.
396    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
397    static final boolean MONITOR_THREAD_CPU_USAGE = false;
398
399    // The flags that are set for all calls we make to the package manager.
400    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
401
402    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
403
404    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
405
406    // Amount of time after a call to stopAppSwitches() during which we will
407    // prevent further untrusted switches from happening.
408    static final long APP_SWITCH_DELAY_TIME = 5*1000;
409
410    // How long we wait for a launched process to attach to the activity manager
411    // before we decide it's never going to come up for real.
412    static final int PROC_START_TIMEOUT = 10*1000;
413    // How long we wait for an attached process to publish its content providers
414    // before we decide it must be hung.
415    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
416
417    // How long we will retain processes hosting content providers in the "last activity"
418    // state before allowing them to drop down to the regular cached LRU list.  This is
419    // to avoid thrashing of provider processes under low memory situations.
420    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
421
422    // How long we wait for a launched process to attach to the activity manager
423    // before we decide it's never going to come up for real, when the process was
424    // started with a wrapper for instrumentation (such as Valgrind) because it
425    // could take much longer than usual.
426    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
427
428    // How long to wait after going idle before forcing apps to GC.
429    static final int GC_TIMEOUT = 5*1000;
430
431    // The minimum amount of time between successive GC requests for a process.
432    static final int GC_MIN_INTERVAL = 60*1000;
433
434    // The minimum amount of time between successive PSS requests for a process.
435    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
436
437    // The minimum amount of time between successive PSS requests for a process
438    // when the request is due to the memory state being lowered.
439    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
440
441    // The rate at which we check for apps using excessive power -- 15 mins.
442    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
443
444    // The minimum sample duration we will allow before deciding we have
445    // enough data on wake locks to start killing things.
446    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
447
448    // The minimum sample duration we will allow before deciding we have
449    // enough data on CPU usage to start killing things.
450    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
451
452    // How long we allow a receiver to run before giving up on it.
453    static final int BROADCAST_FG_TIMEOUT = 10*1000;
454    static final int BROADCAST_BG_TIMEOUT = 60*1000;
455
456    // How long we wait until we timeout on key dispatching.
457    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
458
459    // How long we wait until we timeout on key dispatching during instrumentation.
460    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
461
462    // This is the amount of time an app needs to be running a foreground service before
463    // we will consider it to be doing interaction for usage stats.
464    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
465
466    // Maximum amount of time we will allow to elapse before re-reporting usage stats
467    // interaction with foreground processes.
468    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
469
470    // This is the amount of time we allow an app to settle after it goes into the background,
471    // before we start restricting what it can do.
472    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
473
474    // How long to wait in getAssistContextExtras for the activity and foreground services
475    // to respond with the result.
476    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
477
478    // How long top wait when going through the modern assist (which doesn't need to block
479    // on getting this result before starting to launch its UI).
480    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
481
482    // Maximum number of persisted Uri grants a package is allowed
483    static final int MAX_PERSISTED_URI_GRANTS = 128;
484
485    static final int MY_PID = Process.myPid();
486
487    static final String[] EMPTY_STRING_ARRAY = new String[0];
488
489    // How many bytes to write into the dropbox log before truncating
490    static final int DROPBOX_MAX_SIZE = 256 * 1024;
491
492    // Access modes for handleIncomingUser.
493    static final int ALLOW_NON_FULL = 0;
494    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
495    static final int ALLOW_FULL_ONLY = 2;
496
497    // Delay in notifying task stack change listeners (in millis)
498    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
499
500    // Necessary ApplicationInfo flags to mark an app as persistent
501    private static final int PERSISTENT_MASK =
502            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
503
504    // Intent sent when remote bugreport collection has been completed
505    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
506            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
507
508    // Delay to disable app launch boost
509    static final int APP_BOOST_MESSAGE_DELAY = 3000;
510    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
511    static final int APP_BOOST_TIMEOUT = 2500;
512
513    // Used to indicate that a task is removed it should also be removed from recents.
514    private static final boolean REMOVE_FROM_RECENTS = true;
515    // Used to indicate that an app transition should be animated.
516    static final boolean ANIMATE = true;
517
518    // Determines whether to take full screen screenshots
519    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
520    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
521
522    private static native int nativeMigrateToBoost();
523    private static native int nativeMigrateFromBoost();
524    private boolean mIsBoosted = false;
525    private long mBoostStartTime = 0;
526
527    /** All system services */
528    SystemServiceManager mSystemServiceManager;
529
530    private Installer mInstaller;
531
532    /** Run all ActivityStacks through this */
533    final ActivityStackSupervisor mStackSupervisor;
534
535    final ActivityStarter mActivityStarter;
536
537    /** Task stack change listeners. */
538    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
539            new RemoteCallbackList<ITaskStackListener>();
540
541    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
542
543    public IntentFirewall mIntentFirewall;
544
545    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
546    // default actuion automatically.  Important for devices without direct input
547    // devices.
548    private boolean mShowDialogs = true;
549    private boolean mInVrMode = false;
550
551    BroadcastQueue mFgBroadcastQueue;
552    BroadcastQueue mBgBroadcastQueue;
553    // Convenient for easy iteration over the queues. Foreground is first
554    // so that dispatch of foreground broadcasts gets precedence.
555    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
556
557    BroadcastQueue broadcastQueueForIntent(Intent intent) {
558        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
559        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
560                "Broadcast intent " + intent + " on "
561                + (isFg ? "foreground" : "background") + " queue");
562        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
563    }
564
565    /**
566     * Activity we have told the window manager to have key focus.
567     */
568    ActivityRecord mFocusedActivity = null;
569
570    /**
571     * User id of the last activity mFocusedActivity was set to.
572     */
573    private int mLastFocusedUserId;
574
575    /**
576     * If non-null, we are tracking the time the user spends in the currently focused app.
577     */
578    private AppTimeTracker mCurAppTimeTracker;
579
580    /**
581     * List of intents that were used to start the most recent tasks.
582     */
583    final RecentTasks mRecentTasks;
584
585    /**
586     * For addAppTask: cached of the last activity component that was added.
587     */
588    ComponentName mLastAddedTaskComponent;
589
590    /**
591     * For addAppTask: cached of the last activity uid that was added.
592     */
593    int mLastAddedTaskUid;
594
595    /**
596     * For addAppTask: cached of the last ActivityInfo that was added.
597     */
598    ActivityInfo mLastAddedTaskActivity;
599
600    /**
601     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
602     */
603    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
604
605    /**
606     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
607     */
608    String mDeviceOwnerName;
609
610    final UserController mUserController;
611
612    final AppErrors mAppErrors;
613
614    boolean mDoingSetFocusedActivity;
615
616    public boolean canShowErrorDialogs() {
617        return mShowDialogs && !mSleeping && !mShuttingDown;
618    }
619
620    public class PendingAssistExtras extends Binder implements Runnable {
621        public final ActivityRecord activity;
622        public final Bundle extras;
623        public final Intent intent;
624        public final String hint;
625        public final IResultReceiver receiver;
626        public final int userHandle;
627        public boolean haveResult = false;
628        public Bundle result = null;
629        public AssistStructure structure = null;
630        public AssistContent content = null;
631        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
632                String _hint, IResultReceiver _receiver, int _userHandle) {
633            activity = _activity;
634            extras = _extras;
635            intent = _intent;
636            hint = _hint;
637            receiver = _receiver;
638            userHandle = _userHandle;
639        }
640        @Override
641        public void run() {
642            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
643            synchronized (this) {
644                haveResult = true;
645                notifyAll();
646            }
647            pendingAssistExtrasTimedOut(this);
648        }
649    }
650
651    final ArrayList<PendingAssistExtras> mPendingAssistExtras
652            = new ArrayList<PendingAssistExtras>();
653
654    /**
655     * Process management.
656     */
657    final ProcessList mProcessList = new ProcessList();
658
659    /**
660     * All of the applications we currently have running organized by name.
661     * The keys are strings of the application package name (as
662     * returned by the package manager), and the keys are ApplicationRecord
663     * objects.
664     */
665    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
666
667    /**
668     * Tracking long-term execution of processes to look for abuse and other
669     * bad app behavior.
670     */
671    final ProcessStatsService mProcessStats;
672
673    /**
674     * The currently running isolated processes.
675     */
676    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
677
678    /**
679     * Counter for assigning isolated process uids, to avoid frequently reusing the
680     * same ones.
681     */
682    int mNextIsolatedProcessUid = 0;
683
684    /**
685     * The currently running heavy-weight process, if any.
686     */
687    ProcessRecord mHeavyWeightProcess = null;
688
689    /**
690     * All of the processes we currently have running organized by pid.
691     * The keys are the pid running the application.
692     *
693     * <p>NOTE: This object is protected by its own lock, NOT the global
694     * activity manager lock!
695     */
696    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
697
698    /**
699     * All of the processes that have been forced to be foreground.  The key
700     * is the pid of the caller who requested it (we hold a death
701     * link on it).
702     */
703    abstract class ForegroundToken implements IBinder.DeathRecipient {
704        int pid;
705        IBinder token;
706    }
707    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
708
709    /**
710     * List of records for processes that someone had tried to start before the
711     * system was ready.  We don't start them at that point, but ensure they
712     * are started by the time booting is complete.
713     */
714    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
715
716    /**
717     * List of persistent applications that are in the process
718     * of being started.
719     */
720    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
721
722    /**
723     * Processes that are being forcibly torn down.
724     */
725    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
726
727    /**
728     * List of running applications, sorted by recent usage.
729     * The first entry in the list is the least recently used.
730     */
731    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
732
733    /**
734     * Where in mLruProcesses that the processes hosting activities start.
735     */
736    int mLruProcessActivityStart = 0;
737
738    /**
739     * Where in mLruProcesses that the processes hosting services start.
740     * This is after (lower index) than mLruProcessesActivityStart.
741     */
742    int mLruProcessServiceStart = 0;
743
744    /**
745     * List of processes that should gc as soon as things are idle.
746     */
747    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
748
749    /**
750     * Processes we want to collect PSS data from.
751     */
752    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
753
754    private boolean mBinderTransactionTrackingEnabled = false;
755
756    /**
757     * Last time we requested PSS data of all processes.
758     */
759    long mLastFullPssTime = SystemClock.uptimeMillis();
760
761    /**
762     * If set, the next time we collect PSS data we should do a full collection
763     * with data from native processes and the kernel.
764     */
765    boolean mFullPssPending = false;
766
767    /**
768     * This is the process holding what we currently consider to be
769     * the "home" activity.
770     */
771    ProcessRecord mHomeProcess;
772
773    /**
774     * This is the process holding the activity the user last visited that
775     * is in a different process from the one they are currently in.
776     */
777    ProcessRecord mPreviousProcess;
778
779    /**
780     * The time at which the previous process was last visible.
781     */
782    long mPreviousProcessVisibleTime;
783
784    /**
785     * Track all uids that have actively running processes.
786     */
787    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
788
789    /**
790     * This is for verifying the UID report flow.
791     */
792    static final boolean VALIDATE_UID_STATES = true;
793    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
794
795    /**
796     * Packages that the user has asked to have run in screen size
797     * compatibility mode instead of filling the screen.
798     */
799    final CompatModePackages mCompatModePackages;
800
801    /**
802     * Set of IntentSenderRecord objects that are currently active.
803     */
804    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
805            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
806
807    /**
808     * Fingerprints (hashCode()) of stack traces that we've
809     * already logged DropBox entries for.  Guarded by itself.  If
810     * something (rogue user app) forces this over
811     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
812     */
813    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
814    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
815
816    /**
817     * Strict Mode background batched logging state.
818     *
819     * The string buffer is guarded by itself, and its lock is also
820     * used to determine if another batched write is already
821     * in-flight.
822     */
823    private final StringBuilder mStrictModeBuffer = new StringBuilder();
824
825    /**
826     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
827     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
828     */
829    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
830
831    /**
832     * Resolver for broadcast intents to registered receivers.
833     * Holds BroadcastFilter (subclass of IntentFilter).
834     */
835    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
836            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
837        @Override
838        protected boolean allowFilterResult(
839                BroadcastFilter filter, List<BroadcastFilter> dest) {
840            IBinder target = filter.receiverList.receiver.asBinder();
841            for (int i = dest.size() - 1; i >= 0; i--) {
842                if (dest.get(i).receiverList.receiver.asBinder() == target) {
843                    return false;
844                }
845            }
846            return true;
847        }
848
849        @Override
850        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
851            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
852                    || userId == filter.owningUserId) {
853                return super.newResult(filter, match, userId);
854            }
855            return null;
856        }
857
858        @Override
859        protected BroadcastFilter[] newArray(int size) {
860            return new BroadcastFilter[size];
861        }
862
863        @Override
864        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
865            return packageName.equals(filter.packageName);
866        }
867    };
868
869    /**
870     * State of all active sticky broadcasts per user.  Keys are the action of the
871     * sticky Intent, values are an ArrayList of all broadcasted intents with
872     * that action (which should usually be one).  The SparseArray is keyed
873     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
874     * for stickies that are sent to all users.
875     */
876    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
877            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
878
879    final ActiveServices mServices;
880
881    final static class Association {
882        final int mSourceUid;
883        final String mSourceProcess;
884        final int mTargetUid;
885        final ComponentName mTargetComponent;
886        final String mTargetProcess;
887
888        int mCount;
889        long mTime;
890
891        int mNesting;
892        long mStartTime;
893
894        // states of the source process when the bind occurred.
895        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
896        long mLastStateUptime;
897        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
898                - ActivityManager.MIN_PROCESS_STATE+1];
899
900        Association(int sourceUid, String sourceProcess, int targetUid,
901                ComponentName targetComponent, String targetProcess) {
902            mSourceUid = sourceUid;
903            mSourceProcess = sourceProcess;
904            mTargetUid = targetUid;
905            mTargetComponent = targetComponent;
906            mTargetProcess = targetProcess;
907        }
908    }
909
910    /**
911     * When service association tracking is enabled, this is all of the associations we
912     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
913     * -> association data.
914     */
915    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
916            mAssociations = new SparseArray<>();
917    boolean mTrackingAssociations;
918
919    /**
920     * Backup/restore process management
921     */
922    String mBackupAppName = null;
923    BackupRecord mBackupTarget = null;
924
925    final ProviderMap mProviderMap;
926
927    /**
928     * List of content providers who have clients waiting for them.  The
929     * application is currently being launched and the provider will be
930     * removed from this list once it is published.
931     */
932    final ArrayList<ContentProviderRecord> mLaunchingProviders
933            = new ArrayList<ContentProviderRecord>();
934
935    /**
936     * File storing persisted {@link #mGrantedUriPermissions}.
937     */
938    private final AtomicFile mGrantFile;
939
940    /** XML constants used in {@link #mGrantFile} */
941    private static final String TAG_URI_GRANTS = "uri-grants";
942    private static final String TAG_URI_GRANT = "uri-grant";
943    private static final String ATTR_USER_HANDLE = "userHandle";
944    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
945    private static final String ATTR_TARGET_USER_ID = "targetUserId";
946    private static final String ATTR_SOURCE_PKG = "sourcePkg";
947    private static final String ATTR_TARGET_PKG = "targetPkg";
948    private static final String ATTR_URI = "uri";
949    private static final String ATTR_MODE_FLAGS = "modeFlags";
950    private static final String ATTR_CREATED_TIME = "createdTime";
951    private static final String ATTR_PREFIX = "prefix";
952
953    /**
954     * Global set of specific {@link Uri} permissions that have been granted.
955     * This optimized lookup structure maps from {@link UriPermission#targetUid}
956     * to {@link UriPermission#uri} to {@link UriPermission}.
957     */
958    @GuardedBy("this")
959    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
960            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
961
962    public static class GrantUri {
963        public final int sourceUserId;
964        public final Uri uri;
965        public boolean prefix;
966
967        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
968            this.sourceUserId = sourceUserId;
969            this.uri = uri;
970            this.prefix = prefix;
971        }
972
973        @Override
974        public int hashCode() {
975            int hashCode = 1;
976            hashCode = 31 * hashCode + sourceUserId;
977            hashCode = 31 * hashCode + uri.hashCode();
978            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
979            return hashCode;
980        }
981
982        @Override
983        public boolean equals(Object o) {
984            if (o instanceof GrantUri) {
985                GrantUri other = (GrantUri) o;
986                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
987                        && prefix == other.prefix;
988            }
989            return false;
990        }
991
992        @Override
993        public String toString() {
994            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
995            if (prefix) result += " [prefix]";
996            return result;
997        }
998
999        public String toSafeString() {
1000            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1001            if (prefix) result += " [prefix]";
1002            return result;
1003        }
1004
1005        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1006            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1007                    ContentProvider.getUriWithoutUserId(uri), false);
1008        }
1009    }
1010
1011    CoreSettingsObserver mCoreSettingsObserver;
1012
1013    FontScaleSettingObserver mFontScaleSettingObserver;
1014
1015    private final class FontScaleSettingObserver extends ContentObserver {
1016        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1017
1018        public FontScaleSettingObserver() {
1019            super(mHandler);
1020            ContentResolver resolver = mContext.getContentResolver();
1021            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1022        }
1023
1024        @Override
1025        public void onChange(boolean selfChange, Uri uri) {
1026            if (mFontScaleUri.equals(uri)) {
1027                updateFontScaleIfNeeded();
1028            }
1029        }
1030    }
1031
1032    /**
1033     * Thread-local storage used to carry caller permissions over through
1034     * indirect content-provider access.
1035     */
1036    private class Identity {
1037        public final IBinder token;
1038        public final int pid;
1039        public final int uid;
1040
1041        Identity(IBinder _token, int _pid, int _uid) {
1042            token = _token;
1043            pid = _pid;
1044            uid = _uid;
1045        }
1046    }
1047
1048    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1049
1050    /**
1051     * All information we have collected about the runtime performance of
1052     * any user id that can impact battery performance.
1053     */
1054    final BatteryStatsService mBatteryStatsService;
1055
1056    /**
1057     * Information about component usage
1058     */
1059    UsageStatsManagerInternal mUsageStatsService;
1060
1061    /**
1062     * Access to DeviceIdleController service.
1063     */
1064    DeviceIdleController.LocalService mLocalDeviceIdleController;
1065
1066    /**
1067     * Information about and control over application operations
1068     */
1069    final AppOpsService mAppOpsService;
1070
1071    /**
1072     * Current configuration information.  HistoryRecord objects are given
1073     * a reference to this object to indicate which configuration they are
1074     * currently running in, so this object must be kept immutable.
1075     */
1076    Configuration mConfiguration = new Configuration();
1077
1078    /**
1079     * Current sequencing integer of the configuration, for skipping old
1080     * configurations.
1081     */
1082    int mConfigurationSeq = 0;
1083
1084    boolean mSuppressResizeConfigChanges = false;
1085
1086    /**
1087     * Hardware-reported OpenGLES version.
1088     */
1089    final int GL_ES_VERSION;
1090
1091    /**
1092     * List of initialization arguments to pass to all processes when binding applications to them.
1093     * For example, references to the commonly used services.
1094     */
1095    HashMap<String, IBinder> mAppBindArgs;
1096
1097    /**
1098     * Temporary to avoid allocations.  Protected by main lock.
1099     */
1100    final StringBuilder mStringBuilder = new StringBuilder(256);
1101
1102    /**
1103     * Used to control how we initialize the service.
1104     */
1105    ComponentName mTopComponent;
1106    String mTopAction = Intent.ACTION_MAIN;
1107    String mTopData;
1108
1109    volatile boolean mProcessesReady = false;
1110    volatile boolean mSystemReady = false;
1111    volatile boolean mOnBattery = false;
1112    volatile int mFactoryTest;
1113
1114    @GuardedBy("this") boolean mBooting = false;
1115    @GuardedBy("this") boolean mCallFinishBooting = false;
1116    @GuardedBy("this") boolean mBootAnimationComplete = false;
1117    @GuardedBy("this") boolean mLaunchWarningShown = false;
1118    @GuardedBy("this") boolean mCheckedForSetup = false;
1119
1120    Context mContext;
1121
1122    /**
1123     * The time at which we will allow normal application switches again,
1124     * after a call to {@link #stopAppSwitches()}.
1125     */
1126    long mAppSwitchesAllowedTime;
1127
1128    /**
1129     * This is set to true after the first switch after mAppSwitchesAllowedTime
1130     * is set; any switches after that will clear the time.
1131     */
1132    boolean mDidAppSwitch;
1133
1134    /**
1135     * Last time (in realtime) at which we checked for power usage.
1136     */
1137    long mLastPowerCheckRealtime;
1138
1139    /**
1140     * Last time (in uptime) at which we checked for power usage.
1141     */
1142    long mLastPowerCheckUptime;
1143
1144    /**
1145     * Set while we are wanting to sleep, to prevent any
1146     * activities from being started/resumed.
1147     */
1148    private boolean mSleeping = false;
1149
1150    /**
1151     * The process state used for processes that are running the top activities.
1152     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1153     */
1154    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1155
1156    /**
1157     * Set while we are running a voice interaction.  This overrides
1158     * sleeping while it is active.
1159     */
1160    private IVoiceInteractionSession mRunningVoice;
1161
1162    /**
1163     * For some direct access we need to power manager.
1164     */
1165    PowerManagerInternal mLocalPowerManager;
1166
1167    /**
1168     * We want to hold a wake lock while running a voice interaction session, since
1169     * this may happen with the screen off and we need to keep the CPU running to
1170     * be able to continue to interact with the user.
1171     */
1172    PowerManager.WakeLock mVoiceWakeLock;
1173
1174    /**
1175     * State of external calls telling us if the device is awake or asleep.
1176     */
1177    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1178
1179    /**
1180     * A list of tokens that cause the top activity to be put to sleep.
1181     * They are used by components that may hide and block interaction with underlying
1182     * activities.
1183     */
1184    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1185
1186    static final int LOCK_SCREEN_HIDDEN = 0;
1187    static final int LOCK_SCREEN_LEAVING = 1;
1188    static final int LOCK_SCREEN_SHOWN = 2;
1189    /**
1190     * State of external call telling us if the lock screen is shown.
1191     */
1192    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1193
1194    /**
1195     * Set if we are shutting down the system, similar to sleeping.
1196     */
1197    boolean mShuttingDown = false;
1198
1199    /**
1200     * Current sequence id for oom_adj computation traversal.
1201     */
1202    int mAdjSeq = 0;
1203
1204    /**
1205     * Current sequence id for process LRU updating.
1206     */
1207    int mLruSeq = 0;
1208
1209    /**
1210     * Keep track of the non-cached/empty process we last found, to help
1211     * determine how to distribute cached/empty processes next time.
1212     */
1213    int mNumNonCachedProcs = 0;
1214
1215    /**
1216     * Keep track of the number of cached hidden procs, to balance oom adj
1217     * distribution between those and empty procs.
1218     */
1219    int mNumCachedHiddenProcs = 0;
1220
1221    /**
1222     * Keep track of the number of service processes we last found, to
1223     * determine on the next iteration which should be B services.
1224     */
1225    int mNumServiceProcs = 0;
1226    int mNewNumAServiceProcs = 0;
1227    int mNewNumServiceProcs = 0;
1228
1229    /**
1230     * Allow the current computed overall memory level of the system to go down?
1231     * This is set to false when we are killing processes for reasons other than
1232     * memory management, so that the now smaller process list will not be taken as
1233     * an indication that memory is tighter.
1234     */
1235    boolean mAllowLowerMemLevel = false;
1236
1237    /**
1238     * The last computed memory level, for holding when we are in a state that
1239     * processes are going away for other reasons.
1240     */
1241    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1242
1243    /**
1244     * The last total number of process we have, to determine if changes actually look
1245     * like a shrinking number of process due to lower RAM.
1246     */
1247    int mLastNumProcesses;
1248
1249    /**
1250     * The uptime of the last time we performed idle maintenance.
1251     */
1252    long mLastIdleTime = SystemClock.uptimeMillis();
1253
1254    /**
1255     * Total time spent with RAM that has been added in the past since the last idle time.
1256     */
1257    long mLowRamTimeSinceLastIdle = 0;
1258
1259    /**
1260     * If RAM is currently low, when that horrible situation started.
1261     */
1262    long mLowRamStartTime = 0;
1263
1264    /**
1265     * For reporting to battery stats the current top application.
1266     */
1267    private String mCurResumedPackage = null;
1268    private int mCurResumedUid = -1;
1269
1270    /**
1271     * For reporting to battery stats the apps currently running foreground
1272     * service.  The ProcessMap is package/uid tuples; each of these contain
1273     * an array of the currently foreground processes.
1274     */
1275    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1276            = new ProcessMap<ArrayList<ProcessRecord>>();
1277
1278    /**
1279     * This is set if we had to do a delayed dexopt of an app before launching
1280     * it, to increase the ANR timeouts in that case.
1281     */
1282    boolean mDidDexOpt;
1283
1284    /**
1285     * Set if the systemServer made a call to enterSafeMode.
1286     */
1287    boolean mSafeMode;
1288
1289    /**
1290     * If true, we are running under a test environment so will sample PSS from processes
1291     * much more rapidly to try to collect better data when the tests are rapidly
1292     * running through apps.
1293     */
1294    boolean mTestPssMode = false;
1295
1296    String mDebugApp = null;
1297    boolean mWaitForDebugger = false;
1298    boolean mDebugTransient = false;
1299    String mOrigDebugApp = null;
1300    boolean mOrigWaitForDebugger = false;
1301    boolean mAlwaysFinishActivities = false;
1302    boolean mLenientBackgroundCheck = false;
1303    boolean mForceResizableActivities;
1304    boolean mSupportsMultiWindow;
1305    boolean mSupportsFreeformWindowManagement;
1306    boolean mSupportsPictureInPicture;
1307    Rect mDefaultPinnedStackBounds;
1308    IActivityController mController = null;
1309    boolean mControllerIsAMonkey = false;
1310    String mProfileApp = null;
1311    ProcessRecord mProfileProc = null;
1312    String mProfileFile;
1313    ParcelFileDescriptor mProfileFd;
1314    int mSamplingInterval = 0;
1315    boolean mAutoStopProfiler = false;
1316    int mProfileType = 0;
1317    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1318    String mMemWatchDumpProcName;
1319    String mMemWatchDumpFile;
1320    int mMemWatchDumpPid;
1321    int mMemWatchDumpUid;
1322    String mTrackAllocationApp = null;
1323    String mNativeDebuggingApp = null;
1324
1325    final long[] mTmpLong = new long[2];
1326
1327    static final class ProcessChangeItem {
1328        static final int CHANGE_ACTIVITIES = 1<<0;
1329        static final int CHANGE_PROCESS_STATE = 1<<1;
1330        int changes;
1331        int uid;
1332        int pid;
1333        int processState;
1334        boolean foregroundActivities;
1335    }
1336
1337    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1338    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1339
1340    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1341    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1342
1343    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1344    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1345
1346    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1347    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1348
1349    /**
1350     * Runtime CPU use collection thread.  This object's lock is used to
1351     * perform synchronization with the thread (notifying it to run).
1352     */
1353    final Thread mProcessCpuThread;
1354
1355    /**
1356     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1357     * Must acquire this object's lock when accessing it.
1358     * NOTE: this lock will be held while doing long operations (trawling
1359     * through all processes in /proc), so it should never be acquired by
1360     * any critical paths such as when holding the main activity manager lock.
1361     */
1362    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1363            MONITOR_THREAD_CPU_USAGE);
1364    final AtomicLong mLastCpuTime = new AtomicLong(0);
1365    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1366
1367    long mLastWriteTime = 0;
1368
1369    /**
1370     * Used to retain an update lock when the foreground activity is in
1371     * immersive mode.
1372     */
1373    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1374
1375    /**
1376     * Set to true after the system has finished booting.
1377     */
1378    boolean mBooted = false;
1379
1380    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1381    int mProcessLimitOverride = -1;
1382
1383    WindowManagerService mWindowManager;
1384    final ActivityThread mSystemThread;
1385
1386    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1387        final ProcessRecord mApp;
1388        final int mPid;
1389        final IApplicationThread mAppThread;
1390
1391        AppDeathRecipient(ProcessRecord app, int pid,
1392                IApplicationThread thread) {
1393            if (DEBUG_ALL) Slog.v(
1394                TAG, "New death recipient " + this
1395                + " for thread " + thread.asBinder());
1396            mApp = app;
1397            mPid = pid;
1398            mAppThread = thread;
1399        }
1400
1401        @Override
1402        public void binderDied() {
1403            if (DEBUG_ALL) Slog.v(
1404                TAG, "Death received in " + this
1405                + " for thread " + mAppThread.asBinder());
1406            synchronized(ActivityManagerService.this) {
1407                appDiedLocked(mApp, mPid, mAppThread, true);
1408            }
1409        }
1410    }
1411
1412    static final int SHOW_ERROR_UI_MSG = 1;
1413    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1414    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1415    static final int UPDATE_CONFIGURATION_MSG = 4;
1416    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1417    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1418    static final int SERVICE_TIMEOUT_MSG = 12;
1419    static final int UPDATE_TIME_ZONE = 13;
1420    static final int SHOW_UID_ERROR_UI_MSG = 14;
1421    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1422    static final int PROC_START_TIMEOUT_MSG = 20;
1423    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1424    static final int KILL_APPLICATION_MSG = 22;
1425    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1426    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1427    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1428    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1429    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1430    static final int CLEAR_DNS_CACHE_MSG = 28;
1431    static final int UPDATE_HTTP_PROXY_MSG = 29;
1432    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1433    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1434    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1435    static final int REPORT_MEM_USAGE_MSG = 33;
1436    static final int REPORT_USER_SWITCH_MSG = 34;
1437    static final int CONTINUE_USER_SWITCH_MSG = 35;
1438    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1439    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1440    static final int PERSIST_URI_GRANTS_MSG = 38;
1441    static final int REQUEST_ALL_PSS_MSG = 39;
1442    static final int START_PROFILES_MSG = 40;
1443    static final int UPDATE_TIME = 41;
1444    static final int SYSTEM_USER_START_MSG = 42;
1445    static final int SYSTEM_USER_CURRENT_MSG = 43;
1446    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1447    static final int FINISH_BOOTING_MSG = 45;
1448    static final int START_USER_SWITCH_UI_MSG = 46;
1449    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1450    static final int DISMISS_DIALOG_UI_MSG = 48;
1451    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1452    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1453    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1454    static final int DELETE_DUMPHEAP_MSG = 52;
1455    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1456    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1457    static final int REPORT_TIME_TRACKER_MSG = 55;
1458    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1459    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1460    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1461    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1462    static final int IDLE_UIDS_MSG = 60;
1463    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1464    static final int LOG_STACK_STATE = 62;
1465    static final int VR_MODE_CHANGE_MSG = 63;
1466    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1467    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1468    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1469    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1470    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1471
1472    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1473    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1474    static final int FIRST_COMPAT_MODE_MSG = 300;
1475    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1476
1477    static ServiceThread sKillThread = null;
1478    static KillHandler sKillHandler = null;
1479
1480    CompatModeDialog mCompatModeDialog;
1481    long mLastMemUsageReportTime = 0;
1482
1483    /**
1484     * Flag whether the current user is a "monkey", i.e. whether
1485     * the UI is driven by a UI automation tool.
1486     */
1487    private boolean mUserIsMonkey;
1488
1489    /** Flag whether the device has a Recents UI */
1490    boolean mHasRecents;
1491
1492    /** The dimensions of the thumbnails in the Recents UI. */
1493    int mThumbnailWidth;
1494    int mThumbnailHeight;
1495    float mFullscreenThumbnailScale;
1496
1497    final ServiceThread mHandlerThread;
1498    final MainHandler mHandler;
1499    final UiHandler mUiHandler;
1500
1501    PackageManagerInternal mPackageManagerInt;
1502
1503    final class KillHandler extends Handler {
1504        static final int KILL_PROCESS_GROUP_MSG = 4000;
1505
1506        public KillHandler(Looper looper) {
1507            super(looper, null, true);
1508        }
1509
1510        @Override
1511        public void handleMessage(Message msg) {
1512            switch (msg.what) {
1513                case KILL_PROCESS_GROUP_MSG:
1514                {
1515                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1516                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1517                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1518                }
1519                break;
1520
1521                default:
1522                    super.handleMessage(msg);
1523            }
1524        }
1525    }
1526
1527    final class UiHandler extends Handler {
1528        public UiHandler() {
1529            super(com.android.server.UiThread.get().getLooper(), null, true);
1530        }
1531
1532        @Override
1533        public void handleMessage(Message msg) {
1534            switch (msg.what) {
1535            case SHOW_ERROR_UI_MSG: {
1536                mAppErrors.handleShowAppErrorUi(msg);
1537                ensureBootCompleted();
1538            } break;
1539            case SHOW_NOT_RESPONDING_UI_MSG: {
1540                mAppErrors.handleShowAnrUi(msg);
1541                ensureBootCompleted();
1542            } break;
1543            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1544                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1545                synchronized (ActivityManagerService.this) {
1546                    ProcessRecord proc = (ProcessRecord) data.get("app");
1547                    if (proc == null) {
1548                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1549                        break;
1550                    }
1551                    if (proc.crashDialog != null) {
1552                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1553                        return;
1554                    }
1555                    AppErrorResult res = (AppErrorResult) data.get("result");
1556                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1557                        Dialog d = new StrictModeViolationDialog(mContext,
1558                                ActivityManagerService.this, res, proc);
1559                        d.show();
1560                        proc.crashDialog = d;
1561                    } else {
1562                        // The device is asleep, so just pretend that the user
1563                        // saw a crash dialog and hit "force quit".
1564                        res.set(0);
1565                    }
1566                }
1567                ensureBootCompleted();
1568            } break;
1569            case SHOW_FACTORY_ERROR_UI_MSG: {
1570                Dialog d = new FactoryErrorDialog(
1571                    mContext, msg.getData().getCharSequence("msg"));
1572                d.show();
1573                ensureBootCompleted();
1574            } break;
1575            case WAIT_FOR_DEBUGGER_UI_MSG: {
1576                synchronized (ActivityManagerService.this) {
1577                    ProcessRecord app = (ProcessRecord)msg.obj;
1578                    if (msg.arg1 != 0) {
1579                        if (!app.waitedForDebugger) {
1580                            Dialog d = new AppWaitingForDebuggerDialog(
1581                                    ActivityManagerService.this,
1582                                    mContext, app);
1583                            app.waitDialog = d;
1584                            app.waitedForDebugger = true;
1585                            d.show();
1586                        }
1587                    } else {
1588                        if (app.waitDialog != null) {
1589                            app.waitDialog.dismiss();
1590                            app.waitDialog = null;
1591                        }
1592                    }
1593                }
1594            } break;
1595            case SHOW_UID_ERROR_UI_MSG: {
1596                if (mShowDialogs) {
1597                    AlertDialog d = new BaseErrorDialog(mContext);
1598                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1599                    d.setCancelable(false);
1600                    d.setTitle(mContext.getText(R.string.android_system_label));
1601                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1602                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1603                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1604                    d.show();
1605                }
1606            } break;
1607            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1608                if (mShowDialogs) {
1609                    AlertDialog d = new BaseErrorDialog(mContext);
1610                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1611                    d.setCancelable(false);
1612                    d.setTitle(mContext.getText(R.string.android_system_label));
1613                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1614                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1615                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1616                    d.show();
1617                }
1618            } break;
1619            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1620                synchronized (ActivityManagerService.this) {
1621                    ActivityRecord ar = (ActivityRecord) msg.obj;
1622                    if (mCompatModeDialog != null) {
1623                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1624                                ar.info.applicationInfo.packageName)) {
1625                            return;
1626                        }
1627                        mCompatModeDialog.dismiss();
1628                        mCompatModeDialog = null;
1629                    }
1630                    if (ar != null && false) {
1631                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1632                                ar.packageName)) {
1633                            int mode = mCompatModePackages.computeCompatModeLocked(
1634                                    ar.info.applicationInfo);
1635                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1636                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1637                                mCompatModeDialog = new CompatModeDialog(
1638                                        ActivityManagerService.this, mContext,
1639                                        ar.info.applicationInfo);
1640                                mCompatModeDialog.show();
1641                            }
1642                        }
1643                    }
1644                }
1645                break;
1646            }
1647            case START_USER_SWITCH_UI_MSG: {
1648                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1649                break;
1650            }
1651            case DISMISS_DIALOG_UI_MSG: {
1652                final Dialog d = (Dialog) msg.obj;
1653                d.dismiss();
1654                break;
1655            }
1656            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1657                dispatchProcessesChanged();
1658                break;
1659            }
1660            case DISPATCH_PROCESS_DIED_UI_MSG: {
1661                final int pid = msg.arg1;
1662                final int uid = msg.arg2;
1663                dispatchProcessDied(pid, uid);
1664                break;
1665            }
1666            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1667                dispatchUidsChanged();
1668            } break;
1669            }
1670        }
1671    }
1672
1673    final class MainHandler extends Handler {
1674        public MainHandler(Looper looper) {
1675            super(looper, null, true);
1676        }
1677
1678        @Override
1679        public void handleMessage(Message msg) {
1680            switch (msg.what) {
1681            case UPDATE_CONFIGURATION_MSG: {
1682                final ContentResolver resolver = mContext.getContentResolver();
1683                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1684                        msg.arg1);
1685            } break;
1686            case GC_BACKGROUND_PROCESSES_MSG: {
1687                synchronized (ActivityManagerService.this) {
1688                    performAppGcsIfAppropriateLocked();
1689                }
1690            } break;
1691            case SERVICE_TIMEOUT_MSG: {
1692                if (mDidDexOpt) {
1693                    mDidDexOpt = false;
1694                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1695                    nmsg.obj = msg.obj;
1696                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1697                    return;
1698                }
1699                mServices.serviceTimeout((ProcessRecord)msg.obj);
1700            } break;
1701            case UPDATE_TIME_ZONE: {
1702                synchronized (ActivityManagerService.this) {
1703                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1704                        ProcessRecord r = mLruProcesses.get(i);
1705                        if (r.thread != null) {
1706                            try {
1707                                r.thread.updateTimeZone();
1708                            } catch (RemoteException ex) {
1709                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1710                            }
1711                        }
1712                    }
1713                }
1714            } break;
1715            case CLEAR_DNS_CACHE_MSG: {
1716                synchronized (ActivityManagerService.this) {
1717                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1718                        ProcessRecord r = mLruProcesses.get(i);
1719                        if (r.thread != null) {
1720                            try {
1721                                r.thread.clearDnsCache();
1722                            } catch (RemoteException ex) {
1723                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1724                            }
1725                        }
1726                    }
1727                }
1728            } break;
1729            case UPDATE_HTTP_PROXY_MSG: {
1730                ProxyInfo proxy = (ProxyInfo)msg.obj;
1731                String host = "";
1732                String port = "";
1733                String exclList = "";
1734                Uri pacFileUrl = Uri.EMPTY;
1735                if (proxy != null) {
1736                    host = proxy.getHost();
1737                    port = Integer.toString(proxy.getPort());
1738                    exclList = proxy.getExclusionListAsString();
1739                    pacFileUrl = proxy.getPacFileUrl();
1740                }
1741                synchronized (ActivityManagerService.this) {
1742                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1743                        ProcessRecord r = mLruProcesses.get(i);
1744                        if (r.thread != null) {
1745                            try {
1746                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1747                            } catch (RemoteException ex) {
1748                                Slog.w(TAG, "Failed to update http proxy for: " +
1749                                        r.info.processName);
1750                            }
1751                        }
1752                    }
1753                }
1754            } break;
1755            case PROC_START_TIMEOUT_MSG: {
1756                if (mDidDexOpt) {
1757                    mDidDexOpt = false;
1758                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1759                    nmsg.obj = msg.obj;
1760                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1761                    return;
1762                }
1763                ProcessRecord app = (ProcessRecord)msg.obj;
1764                synchronized (ActivityManagerService.this) {
1765                    processStartTimedOutLocked(app);
1766                }
1767            } break;
1768            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1769                ProcessRecord app = (ProcessRecord)msg.obj;
1770                synchronized (ActivityManagerService.this) {
1771                    processContentProviderPublishTimedOutLocked(app);
1772                }
1773            } break;
1774            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1775                synchronized (ActivityManagerService.this) {
1776                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1777                }
1778            } break;
1779            case KILL_APPLICATION_MSG: {
1780                synchronized (ActivityManagerService.this) {
1781                    int appid = msg.arg1;
1782                    boolean restart = (msg.arg2 == 1);
1783                    Bundle bundle = (Bundle)msg.obj;
1784                    String pkg = bundle.getString("pkg");
1785                    String reason = bundle.getString("reason");
1786                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1787                            false, UserHandle.USER_ALL, reason);
1788                }
1789            } break;
1790            case FINALIZE_PENDING_INTENT_MSG: {
1791                ((PendingIntentRecord)msg.obj).completeFinalize();
1792            } break;
1793            case POST_HEAVY_NOTIFICATION_MSG: {
1794                INotificationManager inm = NotificationManager.getService();
1795                if (inm == null) {
1796                    return;
1797                }
1798
1799                ActivityRecord root = (ActivityRecord)msg.obj;
1800                ProcessRecord process = root.app;
1801                if (process == null) {
1802                    return;
1803                }
1804
1805                try {
1806                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1807                    String text = mContext.getString(R.string.heavy_weight_notification,
1808                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1809                    Notification notification = new Notification.Builder(context)
1810                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1811                            .setWhen(0)
1812                            .setOngoing(true)
1813                            .setTicker(text)
1814                            .setColor(mContext.getColor(
1815                                    com.android.internal.R.color.system_notification_accent_color))
1816                            .setContentTitle(text)
1817                            .setContentText(
1818                                    mContext.getText(R.string.heavy_weight_notification_detail))
1819                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1820                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1821                                    new UserHandle(root.userId)))
1822                            .build();
1823                    try {
1824                        int[] outId = new int[1];
1825                        inm.enqueueNotificationWithTag("android", "android", null,
1826                                R.string.heavy_weight_notification,
1827                                notification, outId, root.userId);
1828                    } catch (RuntimeException e) {
1829                        Slog.w(ActivityManagerService.TAG,
1830                                "Error showing notification for heavy-weight app", e);
1831                    } catch (RemoteException e) {
1832                    }
1833                } catch (NameNotFoundException e) {
1834                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1835                }
1836            } break;
1837            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1838                INotificationManager inm = NotificationManager.getService();
1839                if (inm == null) {
1840                    return;
1841                }
1842                try {
1843                    inm.cancelNotificationWithTag("android", null,
1844                            R.string.heavy_weight_notification,  msg.arg1);
1845                } catch (RuntimeException e) {
1846                    Slog.w(ActivityManagerService.TAG,
1847                            "Error canceling notification for service", e);
1848                } catch (RemoteException e) {
1849                }
1850            } break;
1851            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1852                synchronized (ActivityManagerService.this) {
1853                    checkExcessivePowerUsageLocked(true);
1854                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1855                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1856                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1857                }
1858            } break;
1859            case REPORT_MEM_USAGE_MSG: {
1860                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1861                Thread thread = new Thread() {
1862                    @Override public void run() {
1863                        reportMemUsage(memInfos);
1864                    }
1865                };
1866                thread.start();
1867                break;
1868            }
1869            case REPORT_USER_SWITCH_MSG: {
1870                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1871                break;
1872            }
1873            case CONTINUE_USER_SWITCH_MSG: {
1874                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1875                break;
1876            }
1877            case USER_SWITCH_TIMEOUT_MSG: {
1878                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1879                break;
1880            }
1881            case IMMERSIVE_MODE_LOCK_MSG: {
1882                final boolean nextState = (msg.arg1 != 0);
1883                if (mUpdateLock.isHeld() != nextState) {
1884                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1885                            "Applying new update lock state '" + nextState
1886                            + "' for " + (ActivityRecord)msg.obj);
1887                    if (nextState) {
1888                        mUpdateLock.acquire();
1889                    } else {
1890                        mUpdateLock.release();
1891                    }
1892                }
1893                break;
1894            }
1895            case PERSIST_URI_GRANTS_MSG: {
1896                writeGrantedUriPermissions();
1897                break;
1898            }
1899            case REQUEST_ALL_PSS_MSG: {
1900                synchronized (ActivityManagerService.this) {
1901                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1902                }
1903                break;
1904            }
1905            case START_PROFILES_MSG: {
1906                synchronized (ActivityManagerService.this) {
1907                    mUserController.startProfilesLocked();
1908                }
1909                break;
1910            }
1911            case UPDATE_TIME: {
1912                synchronized (ActivityManagerService.this) {
1913                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1914                        ProcessRecord r = mLruProcesses.get(i);
1915                        if (r.thread != null) {
1916                            try {
1917                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1918                            } catch (RemoteException ex) {
1919                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1920                            }
1921                        }
1922                    }
1923                }
1924                break;
1925            }
1926            case SYSTEM_USER_START_MSG: {
1927                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1928                        Integer.toString(msg.arg1), msg.arg1);
1929                mSystemServiceManager.startUser(msg.arg1);
1930                break;
1931            }
1932            case SYSTEM_USER_UNLOCK_MSG: {
1933                final int userId = msg.arg1;
1934                mSystemServiceManager.unlockUser(userId);
1935                synchronized (ActivityManagerService.this) {
1936                    mRecentTasks.loadUserRecentsLocked(userId);
1937                }
1938                if (userId == UserHandle.USER_SYSTEM) {
1939                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1940                }
1941                installEncryptionUnawareProviders(userId);
1942                break;
1943            }
1944            case SYSTEM_USER_CURRENT_MSG: {
1945                mBatteryStatsService.noteEvent(
1946                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1947                        Integer.toString(msg.arg2), msg.arg2);
1948                mBatteryStatsService.noteEvent(
1949                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1950                        Integer.toString(msg.arg1), msg.arg1);
1951                mSystemServiceManager.switchUser(msg.arg1);
1952                break;
1953            }
1954            case ENTER_ANIMATION_COMPLETE_MSG: {
1955                synchronized (ActivityManagerService.this) {
1956                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1957                    if (r != null && r.app != null && r.app.thread != null) {
1958                        try {
1959                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1960                        } catch (RemoteException e) {
1961                        }
1962                    }
1963                }
1964                break;
1965            }
1966            case FINISH_BOOTING_MSG: {
1967                if (msg.arg1 != 0) {
1968                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1969                    finishBooting();
1970                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1971                }
1972                if (msg.arg2 != 0) {
1973                    enableScreenAfterBoot();
1974                }
1975                break;
1976            }
1977            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1978                try {
1979                    Locale l = (Locale) msg.obj;
1980                    IBinder service = ServiceManager.getService("mount");
1981                    IMountService mountService = IMountService.Stub.asInterface(service);
1982                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1983                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1984                } catch (RemoteException e) {
1985                    Log.e(TAG, "Error storing locale for decryption UI", e);
1986                }
1987                break;
1988            }
1989            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1990                synchronized (ActivityManagerService.this) {
1991                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1992                        try {
1993                            // Make a one-way callback to the listener
1994                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1995                        } catch (RemoteException e){
1996                            // Handled by the RemoteCallbackList
1997                        }
1998                    }
1999                    mTaskStackListeners.finishBroadcast();
2000                }
2001                break;
2002            }
2003            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2004                synchronized (ActivityManagerService.this) {
2005                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2006                        try {
2007                            // Make a one-way callback to the listener
2008                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2009                        } catch (RemoteException e){
2010                            // Handled by the RemoteCallbackList
2011                        }
2012                    }
2013                    mTaskStackListeners.finishBroadcast();
2014                }
2015                break;
2016            }
2017            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2018                synchronized (ActivityManagerService.this) {
2019                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2020                        try {
2021                            // Make a one-way callback to the listener
2022                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2023                        } catch (RemoteException e){
2024                            // Handled by the RemoteCallbackList
2025                        }
2026                    }
2027                    mTaskStackListeners.finishBroadcast();
2028                }
2029                break;
2030            }
2031            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2032                synchronized (ActivityManagerService.this) {
2033                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2034                        try {
2035                            // Make a one-way callback to the listener
2036                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2037                        } catch (RemoteException e){
2038                            // Handled by the RemoteCallbackList
2039                        }
2040                    }
2041                    mTaskStackListeners.finishBroadcast();
2042                }
2043                break;
2044            }
2045            case NOTIFY_FORCED_RESIZABLE_MSG: {
2046                synchronized (ActivityManagerService.this) {
2047                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2048                        try {
2049                            // Make a one-way callback to the listener
2050                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2051                                    (String) msg.obj, msg.arg1);
2052                        } catch (RemoteException e){
2053                            // Handled by the RemoteCallbackList
2054                        }
2055                    }
2056                    mTaskStackListeners.finishBroadcast();
2057                }
2058                break;
2059            }
2060                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2061                    synchronized (ActivityManagerService.this) {
2062                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2063                            try {
2064                                // Make a one-way callback to the listener
2065                                mTaskStackListeners.getBroadcastItem(i)
2066                                        .onActivityDismissingDockedStack();
2067                            } catch (RemoteException e){
2068                                // Handled by the RemoteCallbackList
2069                            }
2070                        }
2071                        mTaskStackListeners.finishBroadcast();
2072                    }
2073                    break;
2074                }
2075            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2076                final int uid = msg.arg1;
2077                final byte[] firstPacket = (byte[]) msg.obj;
2078
2079                synchronized (mPidsSelfLocked) {
2080                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2081                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2082                        if (p.uid == uid) {
2083                            try {
2084                                p.thread.notifyCleartextNetwork(firstPacket);
2085                            } catch (RemoteException ignored) {
2086                            }
2087                        }
2088                    }
2089                }
2090                break;
2091            }
2092            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2093                final String procName;
2094                final int uid;
2095                final long memLimit;
2096                final String reportPackage;
2097                synchronized (ActivityManagerService.this) {
2098                    procName = mMemWatchDumpProcName;
2099                    uid = mMemWatchDumpUid;
2100                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2101                    if (val == null) {
2102                        val = mMemWatchProcesses.get(procName, 0);
2103                    }
2104                    if (val != null) {
2105                        memLimit = val.first;
2106                        reportPackage = val.second;
2107                    } else {
2108                        memLimit = 0;
2109                        reportPackage = null;
2110                    }
2111                }
2112                if (procName == null) {
2113                    return;
2114                }
2115
2116                if (DEBUG_PSS) Slog.d(TAG_PSS,
2117                        "Showing dump heap notification from " + procName + "/" + uid);
2118
2119                INotificationManager inm = NotificationManager.getService();
2120                if (inm == null) {
2121                    return;
2122                }
2123
2124                String text = mContext.getString(R.string.dump_heap_notification, procName);
2125
2126
2127                Intent deleteIntent = new Intent();
2128                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2129                Intent intent = new Intent();
2130                intent.setClassName("android", DumpHeapActivity.class.getName());
2131                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2132                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2133                if (reportPackage != null) {
2134                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2135                }
2136                int userId = UserHandle.getUserId(uid);
2137                Notification notification = new Notification.Builder(mContext)
2138                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2139                        .setWhen(0)
2140                        .setOngoing(true)
2141                        .setAutoCancel(true)
2142                        .setTicker(text)
2143                        .setColor(mContext.getColor(
2144                                com.android.internal.R.color.system_notification_accent_color))
2145                        .setContentTitle(text)
2146                        .setContentText(
2147                                mContext.getText(R.string.dump_heap_notification_detail))
2148                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2149                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2150                                new UserHandle(userId)))
2151                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2152                                deleteIntent, 0, UserHandle.SYSTEM))
2153                        .build();
2154
2155                try {
2156                    int[] outId = new int[1];
2157                    inm.enqueueNotificationWithTag("android", "android", null,
2158                            R.string.dump_heap_notification,
2159                            notification, outId, userId);
2160                } catch (RuntimeException e) {
2161                    Slog.w(ActivityManagerService.TAG,
2162                            "Error showing notification for dump heap", e);
2163                } catch (RemoteException e) {
2164                }
2165            } break;
2166            case DELETE_DUMPHEAP_MSG: {
2167                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2168                        DumpHeapActivity.JAVA_URI,
2169                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2170                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2171                        UserHandle.myUserId());
2172                synchronized (ActivityManagerService.this) {
2173                    mMemWatchDumpFile = null;
2174                    mMemWatchDumpProcName = null;
2175                    mMemWatchDumpPid = -1;
2176                    mMemWatchDumpUid = -1;
2177                }
2178            } break;
2179            case FOREGROUND_PROFILE_CHANGED_MSG: {
2180                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2181            } break;
2182            case REPORT_TIME_TRACKER_MSG: {
2183                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2184                tracker.deliverResult(mContext);
2185            } break;
2186            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2187                mUserController.dispatchUserSwitchComplete(msg.arg1);
2188            } break;
2189            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2190                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2191                try {
2192                    connection.shutdown();
2193                } catch (RemoteException e) {
2194                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2195                }
2196                // Only a UiAutomation can set this flag and now that
2197                // it is finished we make sure it is reset to its default.
2198                mUserIsMonkey = false;
2199            } break;
2200            case APP_BOOST_DEACTIVATE_MSG: {
2201                synchronized(ActivityManagerService.this) {
2202                    if (mIsBoosted) {
2203                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2204                            nativeMigrateFromBoost();
2205                            mIsBoosted = false;
2206                            mBoostStartTime = 0;
2207                        } else {
2208                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2209                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2210                        }
2211                    }
2212                }
2213            } break;
2214            case IDLE_UIDS_MSG: {
2215                idleUids();
2216            } break;
2217            case LOG_STACK_STATE: {
2218                synchronized (ActivityManagerService.this) {
2219                    mStackSupervisor.logStackState();
2220                }
2221            } break;
2222            case VR_MODE_CHANGE_MSG: {
2223                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2224                final ActivityRecord r = (ActivityRecord) msg.obj;
2225                boolean vrMode;
2226                ComponentName requestedPackage;
2227                ComponentName callingPackage;
2228                int userId;
2229                synchronized (ActivityManagerService.this) {
2230                    vrMode = r.requestedVrComponent != null;
2231                    requestedPackage = r.requestedVrComponent;
2232                    userId = r.userId;
2233                    callingPackage = r.info.getComponentName();
2234                    if (mInVrMode != vrMode) {
2235                        mInVrMode = vrMode;
2236                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2237                    }
2238                }
2239                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2240            } break;
2241            }
2242        }
2243    };
2244
2245    static final int COLLECT_PSS_BG_MSG = 1;
2246
2247    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2248        @Override
2249        public void handleMessage(Message msg) {
2250            switch (msg.what) {
2251            case COLLECT_PSS_BG_MSG: {
2252                long start = SystemClock.uptimeMillis();
2253                MemInfoReader memInfo = null;
2254                synchronized (ActivityManagerService.this) {
2255                    if (mFullPssPending) {
2256                        mFullPssPending = false;
2257                        memInfo = new MemInfoReader();
2258                    }
2259                }
2260                if (memInfo != null) {
2261                    updateCpuStatsNow();
2262                    long nativeTotalPss = 0;
2263                    synchronized (mProcessCpuTracker) {
2264                        final int N = mProcessCpuTracker.countStats();
2265                        for (int j=0; j<N; j++) {
2266                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2267                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2268                                // This is definitely an application process; skip it.
2269                                continue;
2270                            }
2271                            synchronized (mPidsSelfLocked) {
2272                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2273                                    // This is one of our own processes; skip it.
2274                                    continue;
2275                                }
2276                            }
2277                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2278                        }
2279                    }
2280                    memInfo.readMemInfo();
2281                    synchronized (ActivityManagerService.this) {
2282                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2283                                + (SystemClock.uptimeMillis()-start) + "ms");
2284                        final long cachedKb = memInfo.getCachedSizeKb();
2285                        final long freeKb = memInfo.getFreeSizeKb();
2286                        final long zramKb = memInfo.getZramTotalSizeKb();
2287                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2288                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2289                                kernelKb*1024, nativeTotalPss*1024);
2290                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2291                                nativeTotalPss);
2292                    }
2293                }
2294
2295                int num = 0;
2296                long[] tmp = new long[2];
2297                do {
2298                    ProcessRecord proc;
2299                    int procState;
2300                    int pid;
2301                    long lastPssTime;
2302                    synchronized (ActivityManagerService.this) {
2303                        if (mPendingPssProcesses.size() <= 0) {
2304                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2305                                    "Collected PSS of " + num + " processes in "
2306                                    + (SystemClock.uptimeMillis() - start) + "ms");
2307                            mPendingPssProcesses.clear();
2308                            return;
2309                        }
2310                        proc = mPendingPssProcesses.remove(0);
2311                        procState = proc.pssProcState;
2312                        lastPssTime = proc.lastPssTime;
2313                        if (proc.thread != null && procState == proc.setProcState
2314                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2315                                        < SystemClock.uptimeMillis()) {
2316                            pid = proc.pid;
2317                        } else {
2318                            proc = null;
2319                            pid = 0;
2320                        }
2321                    }
2322                    if (proc != null) {
2323                        long pss = Debug.getPss(pid, tmp, null);
2324                        synchronized (ActivityManagerService.this) {
2325                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2326                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2327                                num++;
2328                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2329                                        SystemClock.uptimeMillis());
2330                            }
2331                        }
2332                    }
2333                } while (true);
2334            }
2335            }
2336        }
2337    };
2338
2339    public void setSystemProcess() {
2340        try {
2341            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2342            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2343            ServiceManager.addService("meminfo", new MemBinder(this));
2344            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2345            ServiceManager.addService("dbinfo", new DbBinder(this));
2346            if (MONITOR_CPU_USAGE) {
2347                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2348            }
2349            ServiceManager.addService("permission", new PermissionController(this));
2350            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2351
2352            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2353                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2354            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2355
2356            synchronized (this) {
2357                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2358                app.persistent = true;
2359                app.pid = MY_PID;
2360                app.maxAdj = ProcessList.SYSTEM_ADJ;
2361                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2362                synchronized (mPidsSelfLocked) {
2363                    mPidsSelfLocked.put(app.pid, app);
2364                }
2365                updateLruProcessLocked(app, false, null);
2366                updateOomAdjLocked();
2367            }
2368        } catch (PackageManager.NameNotFoundException e) {
2369            throw new RuntimeException(
2370                    "Unable to find android system package", e);
2371        }
2372    }
2373
2374    public void setWindowManager(WindowManagerService wm) {
2375        mWindowManager = wm;
2376        mStackSupervisor.setWindowManager(wm);
2377        mActivityStarter.setWindowManager(wm);
2378    }
2379
2380    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2381        mUsageStatsService = usageStatsManager;
2382    }
2383
2384    public void startObservingNativeCrashes() {
2385        final NativeCrashListener ncl = new NativeCrashListener(this);
2386        ncl.start();
2387    }
2388
2389    public IAppOpsService getAppOpsService() {
2390        return mAppOpsService;
2391    }
2392
2393    static class MemBinder extends Binder {
2394        ActivityManagerService mActivityManagerService;
2395        MemBinder(ActivityManagerService activityManagerService) {
2396            mActivityManagerService = activityManagerService;
2397        }
2398
2399        @Override
2400        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2401            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2402                    != PackageManager.PERMISSION_GRANTED) {
2403                pw.println("Permission Denial: can't dump meminfo from from pid="
2404                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2405                        + " without permission " + android.Manifest.permission.DUMP);
2406                return;
2407            }
2408
2409            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2410        }
2411    }
2412
2413    static class GraphicsBinder extends Binder {
2414        ActivityManagerService mActivityManagerService;
2415        GraphicsBinder(ActivityManagerService activityManagerService) {
2416            mActivityManagerService = activityManagerService;
2417        }
2418
2419        @Override
2420        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2421            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2422                    != PackageManager.PERMISSION_GRANTED) {
2423                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2424                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2425                        + " without permission " + android.Manifest.permission.DUMP);
2426                return;
2427            }
2428
2429            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2430        }
2431    }
2432
2433    static class DbBinder extends Binder {
2434        ActivityManagerService mActivityManagerService;
2435        DbBinder(ActivityManagerService activityManagerService) {
2436            mActivityManagerService = activityManagerService;
2437        }
2438
2439        @Override
2440        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2441            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2442                    != PackageManager.PERMISSION_GRANTED) {
2443                pw.println("Permission Denial: can't dump dbinfo from from pid="
2444                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2445                        + " without permission " + android.Manifest.permission.DUMP);
2446                return;
2447            }
2448
2449            mActivityManagerService.dumpDbInfo(fd, pw, args);
2450        }
2451    }
2452
2453    static class CpuBinder extends Binder {
2454        ActivityManagerService mActivityManagerService;
2455        CpuBinder(ActivityManagerService activityManagerService) {
2456            mActivityManagerService = activityManagerService;
2457        }
2458
2459        @Override
2460        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2461            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2462                    != PackageManager.PERMISSION_GRANTED) {
2463                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2464                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2465                        + " without permission " + android.Manifest.permission.DUMP);
2466                return;
2467            }
2468
2469            synchronized (mActivityManagerService.mProcessCpuTracker) {
2470                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2471                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2472                        SystemClock.uptimeMillis()));
2473            }
2474        }
2475    }
2476
2477    public static final class Lifecycle extends SystemService {
2478        private final ActivityManagerService mService;
2479
2480        public Lifecycle(Context context) {
2481            super(context);
2482            mService = new ActivityManagerService(context);
2483        }
2484
2485        @Override
2486        public void onStart() {
2487            mService.start();
2488        }
2489
2490        public ActivityManagerService getService() {
2491            return mService;
2492        }
2493    }
2494
2495    // Note: This method is invoked on the main thread but may need to attach various
2496    // handlers to other threads.  So take care to be explicit about the looper.
2497    public ActivityManagerService(Context systemContext) {
2498        mContext = systemContext;
2499        mFactoryTest = FactoryTest.getMode();
2500        mSystemThread = ActivityThread.currentActivityThread();
2501
2502        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2503
2504        mHandlerThread = new ServiceThread(TAG,
2505                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2506        mHandlerThread.start();
2507        mHandler = new MainHandler(mHandlerThread.getLooper());
2508        mUiHandler = new UiHandler();
2509
2510        /* static; one-time init here */
2511        if (sKillHandler == null) {
2512            sKillThread = new ServiceThread(TAG + ":kill",
2513                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2514            sKillThread.start();
2515            sKillHandler = new KillHandler(sKillThread.getLooper());
2516        }
2517
2518        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2519                "foreground", BROADCAST_FG_TIMEOUT, false);
2520        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2521                "background", BROADCAST_BG_TIMEOUT, true);
2522        mBroadcastQueues[0] = mFgBroadcastQueue;
2523        mBroadcastQueues[1] = mBgBroadcastQueue;
2524
2525        mServices = new ActiveServices(this);
2526        mProviderMap = new ProviderMap(this);
2527        mAppErrors = new AppErrors(mContext, this);
2528
2529        // TODO: Move creation of battery stats service outside of activity manager service.
2530        File dataDir = Environment.getDataDirectory();
2531        File systemDir = new File(dataDir, "system");
2532        systemDir.mkdirs();
2533        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2534        mBatteryStatsService.getActiveStatistics().readLocked();
2535        mBatteryStatsService.scheduleWriteToDisk();
2536        mOnBattery = DEBUG_POWER ? true
2537                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2538        mBatteryStatsService.getActiveStatistics().setCallback(this);
2539
2540        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2541
2542        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2543        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2544                new IAppOpsCallback.Stub() {
2545                    @Override public void opChanged(int op, int uid, String packageName) {
2546                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2547                            if (mAppOpsService.checkOperation(op, uid, packageName)
2548                                    != AppOpsManager.MODE_ALLOWED) {
2549                                runInBackgroundDisabled(uid);
2550                            }
2551                        }
2552                    }
2553                });
2554
2555        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2556
2557        mUserController = new UserController(this);
2558
2559        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2560            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2561
2562        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2563
2564        mConfiguration.setToDefaults();
2565        mConfiguration.setLocales(LocaleList.getDefault());
2566
2567        mConfigurationSeq = mConfiguration.seq = 1;
2568        mProcessCpuTracker.init();
2569
2570        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2571        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2572        mStackSupervisor = new ActivityStackSupervisor(this);
2573        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2574        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2575
2576        mProcessCpuThread = new Thread("CpuTracker") {
2577            @Override
2578            public void run() {
2579                while (true) {
2580                    try {
2581                        try {
2582                            synchronized(this) {
2583                                final long now = SystemClock.uptimeMillis();
2584                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2585                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2586                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2587                                //        + ", write delay=" + nextWriteDelay);
2588                                if (nextWriteDelay < nextCpuDelay) {
2589                                    nextCpuDelay = nextWriteDelay;
2590                                }
2591                                if (nextCpuDelay > 0) {
2592                                    mProcessCpuMutexFree.set(true);
2593                                    this.wait(nextCpuDelay);
2594                                }
2595                            }
2596                        } catch (InterruptedException e) {
2597                        }
2598                        updateCpuStatsNow();
2599                    } catch (Exception e) {
2600                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2601                    }
2602                }
2603            }
2604        };
2605
2606        Watchdog.getInstance().addMonitor(this);
2607        Watchdog.getInstance().addThread(mHandler);
2608    }
2609
2610    public void setSystemServiceManager(SystemServiceManager mgr) {
2611        mSystemServiceManager = mgr;
2612    }
2613
2614    public void setInstaller(Installer installer) {
2615        mInstaller = installer;
2616    }
2617
2618    private void start() {
2619        Process.removeAllProcessGroups();
2620        mProcessCpuThread.start();
2621
2622        mBatteryStatsService.publish(mContext);
2623        mAppOpsService.publish(mContext);
2624        Slog.d("AppOps", "AppOpsService published");
2625        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2626    }
2627
2628    void onUserStoppedLocked(int userId) {
2629        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2630    }
2631
2632    public void initPowerManagement() {
2633        mStackSupervisor.initPowerManagement();
2634        mBatteryStatsService.initPowerManagement();
2635        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2636        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2637        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2638        mVoiceWakeLock.setReferenceCounted(false);
2639    }
2640
2641    @Override
2642    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2643            throws RemoteException {
2644        if (code == SYSPROPS_TRANSACTION) {
2645            // We need to tell all apps about the system property change.
2646            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2647            synchronized(this) {
2648                final int NP = mProcessNames.getMap().size();
2649                for (int ip=0; ip<NP; ip++) {
2650                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2651                    final int NA = apps.size();
2652                    for (int ia=0; ia<NA; ia++) {
2653                        ProcessRecord app = apps.valueAt(ia);
2654                        if (app.thread != null) {
2655                            procs.add(app.thread.asBinder());
2656                        }
2657                    }
2658                }
2659            }
2660
2661            int N = procs.size();
2662            for (int i=0; i<N; i++) {
2663                Parcel data2 = Parcel.obtain();
2664                try {
2665                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2666                } catch (RemoteException e) {
2667                }
2668                data2.recycle();
2669            }
2670        }
2671        try {
2672            return super.onTransact(code, data, reply, flags);
2673        } catch (RuntimeException e) {
2674            // The activity manager only throws security exceptions, so let's
2675            // log all others.
2676            if (!(e instanceof SecurityException)) {
2677                Slog.wtf(TAG, "Activity Manager Crash", e);
2678            }
2679            throw e;
2680        }
2681    }
2682
2683    void updateCpuStats() {
2684        final long now = SystemClock.uptimeMillis();
2685        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2686            return;
2687        }
2688        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2689            synchronized (mProcessCpuThread) {
2690                mProcessCpuThread.notify();
2691            }
2692        }
2693    }
2694
2695    void updateCpuStatsNow() {
2696        synchronized (mProcessCpuTracker) {
2697            mProcessCpuMutexFree.set(false);
2698            final long now = SystemClock.uptimeMillis();
2699            boolean haveNewCpuStats = false;
2700
2701            if (MONITOR_CPU_USAGE &&
2702                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2703                mLastCpuTime.set(now);
2704                mProcessCpuTracker.update();
2705                if (mProcessCpuTracker.hasGoodLastStats()) {
2706                    haveNewCpuStats = true;
2707                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2708                    //Slog.i(TAG, "Total CPU usage: "
2709                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2710
2711                    // Slog the cpu usage if the property is set.
2712                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2713                        int user = mProcessCpuTracker.getLastUserTime();
2714                        int system = mProcessCpuTracker.getLastSystemTime();
2715                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2716                        int irq = mProcessCpuTracker.getLastIrqTime();
2717                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2718                        int idle = mProcessCpuTracker.getLastIdleTime();
2719
2720                        int total = user + system + iowait + irq + softIrq + idle;
2721                        if (total == 0) total = 1;
2722
2723                        EventLog.writeEvent(EventLogTags.CPU,
2724                                ((user+system+iowait+irq+softIrq) * 100) / total,
2725                                (user * 100) / total,
2726                                (system * 100) / total,
2727                                (iowait * 100) / total,
2728                                (irq * 100) / total,
2729                                (softIrq * 100) / total);
2730                    }
2731                }
2732            }
2733
2734            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2735            synchronized(bstats) {
2736                synchronized(mPidsSelfLocked) {
2737                    if (haveNewCpuStats) {
2738                        if (bstats.startAddingCpuLocked()) {
2739                            int totalUTime = 0;
2740                            int totalSTime = 0;
2741                            final int N = mProcessCpuTracker.countStats();
2742                            for (int i=0; i<N; i++) {
2743                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2744                                if (!st.working) {
2745                                    continue;
2746                                }
2747                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2748                                totalUTime += st.rel_utime;
2749                                totalSTime += st.rel_stime;
2750                                if (pr != null) {
2751                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2752                                    if (ps == null || !ps.isActive()) {
2753                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2754                                                pr.info.uid, pr.processName);
2755                                    }
2756                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2757                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2758                                } else {
2759                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2760                                    if (ps == null || !ps.isActive()) {
2761                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2762                                                bstats.mapUid(st.uid), st.name);
2763                                    }
2764                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2765                                }
2766                            }
2767                            final int userTime = mProcessCpuTracker.getLastUserTime();
2768                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2769                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2770                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2771                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2772                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2773                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2774                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2775                        }
2776                    }
2777                }
2778
2779                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2780                    mLastWriteTime = now;
2781                    mBatteryStatsService.scheduleWriteToDisk();
2782                }
2783            }
2784        }
2785    }
2786
2787    @Override
2788    public void batteryNeedsCpuUpdate() {
2789        updateCpuStatsNow();
2790    }
2791
2792    @Override
2793    public void batteryPowerChanged(boolean onBattery) {
2794        // When plugging in, update the CPU stats first before changing
2795        // the plug state.
2796        updateCpuStatsNow();
2797        synchronized (this) {
2798            synchronized(mPidsSelfLocked) {
2799                mOnBattery = DEBUG_POWER ? true : onBattery;
2800            }
2801        }
2802    }
2803
2804    @Override
2805    public void batterySendBroadcast(Intent intent) {
2806        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2807                AppOpsManager.OP_NONE, null, false, false,
2808                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2809    }
2810
2811    /**
2812     * Initialize the application bind args. These are passed to each
2813     * process when the bindApplication() IPC is sent to the process. They're
2814     * lazily setup to make sure the services are running when they're asked for.
2815     */
2816    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2817        if (mAppBindArgs == null) {
2818            mAppBindArgs = new HashMap<>();
2819
2820            // Isolated processes won't get this optimization, so that we don't
2821            // violate the rules about which services they have access to.
2822            if (!isolated) {
2823                // Setup the application init args
2824                mAppBindArgs.put("package", ServiceManager.getService("package"));
2825                mAppBindArgs.put("window", ServiceManager.getService("window"));
2826                mAppBindArgs.put(Context.ALARM_SERVICE,
2827                        ServiceManager.getService(Context.ALARM_SERVICE));
2828            }
2829        }
2830        return mAppBindArgs;
2831    }
2832
2833    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2834        if (r == null || mFocusedActivity == r) {
2835            return false;
2836        }
2837
2838        if (!r.isFocusable()) {
2839            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2840            return false;
2841        }
2842
2843        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2844
2845        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2846        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2847                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2848        mDoingSetFocusedActivity = true;
2849
2850        final ActivityRecord last = mFocusedActivity;
2851        mFocusedActivity = r;
2852        if (r.task.isApplicationTask()) {
2853            if (mCurAppTimeTracker != r.appTimeTracker) {
2854                // We are switching app tracking.  Complete the current one.
2855                if (mCurAppTimeTracker != null) {
2856                    mCurAppTimeTracker.stop();
2857                    mHandler.obtainMessage(
2858                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2859                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2860                    mCurAppTimeTracker = null;
2861                }
2862                if (r.appTimeTracker != null) {
2863                    mCurAppTimeTracker = r.appTimeTracker;
2864                    startTimeTrackingFocusedActivityLocked();
2865                }
2866            } else {
2867                startTimeTrackingFocusedActivityLocked();
2868            }
2869        } else {
2870            r.appTimeTracker = null;
2871        }
2872        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2873        // TODO: Probably not, because we don't want to resume voice on switching
2874        // back to this activity
2875        if (r.task.voiceInteractor != null) {
2876            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2877        } else {
2878            finishRunningVoiceLocked();
2879            IVoiceInteractionSession session;
2880            if (last != null && ((session = last.task.voiceSession) != null
2881                    || (session = last.voiceSession) != null)) {
2882                // We had been in a voice interaction session, but now focused has
2883                // move to something different.  Just finish the session, we can't
2884                // return to it and retain the proper state and synchronization with
2885                // the voice interaction service.
2886                finishVoiceTask(session);
2887            }
2888        }
2889        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2890            mWindowManager.setFocusedApp(r.appToken, true);
2891        }
2892        applyUpdateLockStateLocked(r);
2893        applyUpdateVrModeLocked(r);
2894        if (mFocusedActivity.userId != mLastFocusedUserId) {
2895            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2896            mHandler.obtainMessage(
2897                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2898            mLastFocusedUserId = mFocusedActivity.userId;
2899        }
2900
2901        // Log a warning if the focused app is changed during the process. This could
2902        // indicate a problem of the focus setting logic!
2903        if (mFocusedActivity != r) Slog.w(TAG,
2904                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2905        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2906
2907        EventLogTags.writeAmFocusedActivity(
2908                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2909                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2910                reason);
2911        return true;
2912    }
2913
2914    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2915        if (mFocusedActivity != goingAway) {
2916            return;
2917        }
2918
2919        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2920        if (focusedStack != null) {
2921            final ActivityRecord top = focusedStack.topActivity();
2922            if (top != null && top.userId != mLastFocusedUserId) {
2923                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2924                mHandler.sendMessage(
2925                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2926                mLastFocusedUserId = top.userId;
2927            }
2928        }
2929
2930        // Try to move focus to another activity if possible.
2931        if (setFocusedActivityLocked(
2932                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2933            return;
2934        }
2935
2936        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2937                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2938        mFocusedActivity = null;
2939        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2940    }
2941
2942    @Override
2943    public void setFocusedStack(int stackId) {
2944        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2945        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2946        final long callingId = Binder.clearCallingIdentity();
2947        try {
2948            synchronized (this) {
2949                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2950                if (stack == null) {
2951                    return;
2952                }
2953                final ActivityRecord r = stack.topRunningActivityLocked();
2954                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2955                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2956                }
2957            }
2958        } finally {
2959            Binder.restoreCallingIdentity(callingId);
2960        }
2961    }
2962
2963    @Override
2964    public void setFocusedTask(int taskId) {
2965        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2966        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2967        final long callingId = Binder.clearCallingIdentity();
2968        try {
2969            synchronized (this) {
2970                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2971                if (task == null) {
2972                    return;
2973                }
2974                final ActivityRecord r = task.topRunningActivityLocked();
2975                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2976                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2977                }
2978            }
2979        } finally {
2980            Binder.restoreCallingIdentity(callingId);
2981        }
2982    }
2983
2984    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2985    @Override
2986    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2987        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2988        synchronized (this) {
2989            if (listener != null) {
2990                mTaskStackListeners.register(listener);
2991            }
2992        }
2993    }
2994
2995    @Override
2996    public void notifyActivityDrawn(IBinder token) {
2997        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2998        synchronized (this) {
2999            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3000            if (r != null) {
3001                r.task.stack.notifyActivityDrawnLocked(r);
3002            }
3003        }
3004    }
3005
3006    final void applyUpdateLockStateLocked(ActivityRecord r) {
3007        // Modifications to the UpdateLock state are done on our handler, outside
3008        // the activity manager's locks.  The new state is determined based on the
3009        // state *now* of the relevant activity record.  The object is passed to
3010        // the handler solely for logging detail, not to be consulted/modified.
3011        final boolean nextState = r != null && r.immersive;
3012        mHandler.sendMessage(
3013                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3014    }
3015
3016    final void applyUpdateVrModeLocked(ActivityRecord r) {
3017        mHandler.sendMessage(
3018                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3019    }
3020
3021    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3022        Message msg = Message.obtain();
3023        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3024        msg.obj = r.task.askedCompatMode ? null : r;
3025        mUiHandler.sendMessage(msg);
3026    }
3027
3028    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3029            String what, Object obj, ProcessRecord srcApp) {
3030        app.lastActivityTime = now;
3031
3032        if (app.activities.size() > 0) {
3033            // Don't want to touch dependent processes that are hosting activities.
3034            return index;
3035        }
3036
3037        int lrui = mLruProcesses.lastIndexOf(app);
3038        if (lrui < 0) {
3039            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3040                    + what + " " + obj + " from " + srcApp);
3041            return index;
3042        }
3043
3044        if (lrui >= index) {
3045            // Don't want to cause this to move dependent processes *back* in the
3046            // list as if they were less frequently used.
3047            return index;
3048        }
3049
3050        if (lrui >= mLruProcessActivityStart) {
3051            // Don't want to touch dependent processes that are hosting activities.
3052            return index;
3053        }
3054
3055        mLruProcesses.remove(lrui);
3056        if (index > 0) {
3057            index--;
3058        }
3059        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3060                + " in LRU list: " + app);
3061        mLruProcesses.add(index, app);
3062        return index;
3063    }
3064
3065    static void killProcessGroup(int uid, int pid) {
3066        if (sKillHandler != null) {
3067            sKillHandler.sendMessage(
3068                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3069        } else {
3070            Slog.w(TAG, "Asked to kill process group before system bringup!");
3071            Process.killProcessGroup(uid, pid);
3072        }
3073    }
3074
3075    final void removeLruProcessLocked(ProcessRecord app) {
3076        int lrui = mLruProcesses.lastIndexOf(app);
3077        if (lrui >= 0) {
3078            if (!app.killed) {
3079                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3080                Process.killProcessQuiet(app.pid);
3081                killProcessGroup(app.uid, app.pid);
3082            }
3083            if (lrui <= mLruProcessActivityStart) {
3084                mLruProcessActivityStart--;
3085            }
3086            if (lrui <= mLruProcessServiceStart) {
3087                mLruProcessServiceStart--;
3088            }
3089            mLruProcesses.remove(lrui);
3090        }
3091    }
3092
3093    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3094            ProcessRecord client) {
3095        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3096                || app.treatLikeActivity;
3097        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3098        if (!activityChange && hasActivity) {
3099            // The process has activities, so we are only allowing activity-based adjustments
3100            // to move it.  It should be kept in the front of the list with other
3101            // processes that have activities, and we don't want those to change their
3102            // order except due to activity operations.
3103            return;
3104        }
3105
3106        mLruSeq++;
3107        final long now = SystemClock.uptimeMillis();
3108        app.lastActivityTime = now;
3109
3110        // First a quick reject: if the app is already at the position we will
3111        // put it, then there is nothing to do.
3112        if (hasActivity) {
3113            final int N = mLruProcesses.size();
3114            if (N > 0 && mLruProcesses.get(N-1) == app) {
3115                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3116                return;
3117            }
3118        } else {
3119            if (mLruProcessServiceStart > 0
3120                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3121                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3122                return;
3123            }
3124        }
3125
3126        int lrui = mLruProcesses.lastIndexOf(app);
3127
3128        if (app.persistent && lrui >= 0) {
3129            // We don't care about the position of persistent processes, as long as
3130            // they are in the list.
3131            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3132            return;
3133        }
3134
3135        /* In progress: compute new position first, so we can avoid doing work
3136           if the process is not actually going to move.  Not yet working.
3137        int addIndex;
3138        int nextIndex;
3139        boolean inActivity = false, inService = false;
3140        if (hasActivity) {
3141            // Process has activities, put it at the very tipsy-top.
3142            addIndex = mLruProcesses.size();
3143            nextIndex = mLruProcessServiceStart;
3144            inActivity = true;
3145        } else if (hasService) {
3146            // Process has services, put it at the top of the service list.
3147            addIndex = mLruProcessActivityStart;
3148            nextIndex = mLruProcessServiceStart;
3149            inActivity = true;
3150            inService = true;
3151        } else  {
3152            // Process not otherwise of interest, it goes to the top of the non-service area.
3153            addIndex = mLruProcessServiceStart;
3154            if (client != null) {
3155                int clientIndex = mLruProcesses.lastIndexOf(client);
3156                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3157                        + app);
3158                if (clientIndex >= 0 && addIndex > clientIndex) {
3159                    addIndex = clientIndex;
3160                }
3161            }
3162            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3163        }
3164
3165        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3166                + mLruProcessActivityStart + "): " + app);
3167        */
3168
3169        if (lrui >= 0) {
3170            if (lrui < mLruProcessActivityStart) {
3171                mLruProcessActivityStart--;
3172            }
3173            if (lrui < mLruProcessServiceStart) {
3174                mLruProcessServiceStart--;
3175            }
3176            /*
3177            if (addIndex > lrui) {
3178                addIndex--;
3179            }
3180            if (nextIndex > lrui) {
3181                nextIndex--;
3182            }
3183            */
3184            mLruProcesses.remove(lrui);
3185        }
3186
3187        /*
3188        mLruProcesses.add(addIndex, app);
3189        if (inActivity) {
3190            mLruProcessActivityStart++;
3191        }
3192        if (inService) {
3193            mLruProcessActivityStart++;
3194        }
3195        */
3196
3197        int nextIndex;
3198        if (hasActivity) {
3199            final int N = mLruProcesses.size();
3200            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3201                // Process doesn't have activities, but has clients with
3202                // activities...  move it up, but one below the top (the top
3203                // should always have a real activity).
3204                if (DEBUG_LRU) Slog.d(TAG_LRU,
3205                        "Adding to second-top of LRU activity list: " + app);
3206                mLruProcesses.add(N - 1, app);
3207                // To keep it from spamming the LRU list (by making a bunch of clients),
3208                // we will push down any other entries owned by the app.
3209                final int uid = app.info.uid;
3210                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3211                    ProcessRecord subProc = mLruProcesses.get(i);
3212                    if (subProc.info.uid == uid) {
3213                        // We want to push this one down the list.  If the process after
3214                        // it is for the same uid, however, don't do so, because we don't
3215                        // want them internally to be re-ordered.
3216                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3217                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3218                                    "Pushing uid " + uid + " swapping at " + i + ": "
3219                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3220                            ProcessRecord tmp = mLruProcesses.get(i);
3221                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3222                            mLruProcesses.set(i - 1, tmp);
3223                            i--;
3224                        }
3225                    } else {
3226                        // A gap, we can stop here.
3227                        break;
3228                    }
3229                }
3230            } else {
3231                // Process has activities, put it at the very tipsy-top.
3232                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3233                mLruProcesses.add(app);
3234            }
3235            nextIndex = mLruProcessServiceStart;
3236        } else if (hasService) {
3237            // Process has services, put it at the top of the service list.
3238            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3239            mLruProcesses.add(mLruProcessActivityStart, app);
3240            nextIndex = mLruProcessServiceStart;
3241            mLruProcessActivityStart++;
3242        } else  {
3243            // Process not otherwise of interest, it goes to the top of the non-service area.
3244            int index = mLruProcessServiceStart;
3245            if (client != null) {
3246                // If there is a client, don't allow the process to be moved up higher
3247                // in the list than that client.
3248                int clientIndex = mLruProcesses.lastIndexOf(client);
3249                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3250                        + " when updating " + app);
3251                if (clientIndex <= lrui) {
3252                    // Don't allow the client index restriction to push it down farther in the
3253                    // list than it already is.
3254                    clientIndex = lrui;
3255                }
3256                if (clientIndex >= 0 && index > clientIndex) {
3257                    index = clientIndex;
3258                }
3259            }
3260            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3261            mLruProcesses.add(index, app);
3262            nextIndex = index-1;
3263            mLruProcessActivityStart++;
3264            mLruProcessServiceStart++;
3265        }
3266
3267        // If the app is currently using a content provider or service,
3268        // bump those processes as well.
3269        for (int j=app.connections.size()-1; j>=0; j--) {
3270            ConnectionRecord cr = app.connections.valueAt(j);
3271            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3272                    && cr.binding.service.app != null
3273                    && cr.binding.service.app.lruSeq != mLruSeq
3274                    && !cr.binding.service.app.persistent) {
3275                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3276                        "service connection", cr, app);
3277            }
3278        }
3279        for (int j=app.conProviders.size()-1; j>=0; j--) {
3280            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3281            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3282                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3283                        "provider reference", cpr, app);
3284            }
3285        }
3286    }
3287
3288    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3289        if (uid == Process.SYSTEM_UID) {
3290            // The system gets to run in any process.  If there are multiple
3291            // processes with the same uid, just pick the first (this
3292            // should never happen).
3293            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3294            if (procs == null) return null;
3295            final int procCount = procs.size();
3296            for (int i = 0; i < procCount; i++) {
3297                final int procUid = procs.keyAt(i);
3298                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3299                    // Don't use an app process or different user process for system component.
3300                    continue;
3301                }
3302                return procs.valueAt(i);
3303            }
3304        }
3305        ProcessRecord proc = mProcessNames.get(processName, uid);
3306        if (false && proc != null && !keepIfLarge
3307                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3308                && proc.lastCachedPss >= 4000) {
3309            // Turn this condition on to cause killing to happen regularly, for testing.
3310            if (proc.baseProcessTracker != null) {
3311                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3312            }
3313            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3314        } else if (proc != null && !keepIfLarge
3315                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3316                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3317            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3318            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3319                if (proc.baseProcessTracker != null) {
3320                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3321                }
3322                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3323            }
3324        }
3325        return proc;
3326    }
3327
3328    void notifyPackageUse(String packageName) {
3329        IPackageManager pm = AppGlobals.getPackageManager();
3330        try {
3331            pm.notifyPackageUse(packageName);
3332        } catch (RemoteException e) {
3333        }
3334    }
3335
3336    boolean isNextTransitionForward() {
3337        int transit = mWindowManager.getPendingAppTransition();
3338        return transit == TRANSIT_ACTIVITY_OPEN
3339                || transit == TRANSIT_TASK_OPEN
3340                || transit == TRANSIT_TASK_TO_FRONT;
3341    }
3342
3343    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3344            String processName, String abiOverride, int uid, Runnable crashHandler) {
3345        synchronized(this) {
3346            ApplicationInfo info = new ApplicationInfo();
3347            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3348            // For isolated processes, the former contains the parent's uid and the latter the
3349            // actual uid of the isolated process.
3350            // In the special case introduced by this method (which is, starting an isolated
3351            // process directly from the SystemServer without an actual parent app process) the
3352            // closest thing to a parent's uid is SYSTEM_UID.
3353            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3354            // the |isolated| logic in the ProcessRecord constructor.
3355            info.uid = Process.SYSTEM_UID;
3356            info.processName = processName;
3357            info.className = entryPoint;
3358            info.packageName = "android";
3359            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3360                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3361                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3362                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3363                    crashHandler);
3364            return proc != null ? proc.pid : 0;
3365        }
3366    }
3367
3368    final ProcessRecord startProcessLocked(String processName,
3369            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3370            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3371            boolean isolated, boolean keepIfLarge) {
3372        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3373                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3374                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3375                null /* crashHandler */);
3376    }
3377
3378    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3379            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3380            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3381            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3382        long startTime = SystemClock.elapsedRealtime();
3383        ProcessRecord app;
3384        if (!isolated) {
3385            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3386            checkTime(startTime, "startProcess: after getProcessRecord");
3387
3388            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3389                // If we are in the background, then check to see if this process
3390                // is bad.  If so, we will just silently fail.
3391                if (mAppErrors.isBadProcessLocked(info)) {
3392                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3393                            + "/" + info.processName);
3394                    return null;
3395                }
3396            } else {
3397                // When the user is explicitly starting a process, then clear its
3398                // crash count so that we won't make it bad until they see at
3399                // least one crash dialog again, and make the process good again
3400                // if it had been bad.
3401                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3402                        + "/" + info.processName);
3403                mAppErrors.resetProcessCrashTimeLocked(info);
3404                if (mAppErrors.isBadProcessLocked(info)) {
3405                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3406                            UserHandle.getUserId(info.uid), info.uid,
3407                            info.processName);
3408                    mAppErrors.clearBadProcessLocked(info);
3409                    if (app != null) {
3410                        app.bad = false;
3411                    }
3412                }
3413            }
3414        } else {
3415            // If this is an isolated process, it can't re-use an existing process.
3416            app = null;
3417        }
3418
3419        // app launch boost for big.little configurations
3420        // use cpusets to migrate freshly launched tasks to big cores
3421        synchronized(ActivityManagerService.this) {
3422            nativeMigrateToBoost();
3423            mIsBoosted = true;
3424            mBoostStartTime = SystemClock.uptimeMillis();
3425            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3426            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3427        }
3428
3429        // We don't have to do anything more if:
3430        // (1) There is an existing application record; and
3431        // (2) The caller doesn't think it is dead, OR there is no thread
3432        //     object attached to it so we know it couldn't have crashed; and
3433        // (3) There is a pid assigned to it, so it is either starting or
3434        //     already running.
3435        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3436                + " app=" + app + " knownToBeDead=" + knownToBeDead
3437                + " thread=" + (app != null ? app.thread : null)
3438                + " pid=" + (app != null ? app.pid : -1));
3439        if (app != null && app.pid > 0) {
3440            if (!knownToBeDead || app.thread == null) {
3441                // We already have the app running, or are waiting for it to
3442                // come up (we have a pid but not yet its thread), so keep it.
3443                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3444                // If this is a new package in the process, add the package to the list
3445                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3446                checkTime(startTime, "startProcess: done, added package to proc");
3447                return app;
3448            }
3449
3450            // An application record is attached to a previous process,
3451            // clean it up now.
3452            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3453            checkTime(startTime, "startProcess: bad proc running, killing");
3454            killProcessGroup(app.uid, app.pid);
3455            handleAppDiedLocked(app, true, true);
3456            checkTime(startTime, "startProcess: done killing old proc");
3457        }
3458
3459        String hostingNameStr = hostingName != null
3460                ? hostingName.flattenToShortString() : null;
3461
3462        if (app == null) {
3463            checkTime(startTime, "startProcess: creating new process record");
3464            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3465            if (app == null) {
3466                Slog.w(TAG, "Failed making new process record for "
3467                        + processName + "/" + info.uid + " isolated=" + isolated);
3468                return null;
3469            }
3470            app.crashHandler = crashHandler;
3471            checkTime(startTime, "startProcess: done creating new process record");
3472        } else {
3473            // If this is a new package in the process, add the package to the list
3474            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3475            checkTime(startTime, "startProcess: added package to existing proc");
3476        }
3477
3478        // If the system is not ready yet, then hold off on starting this
3479        // process until it is.
3480        if (!mProcessesReady
3481                && !isAllowedWhileBooting(info)
3482                && !allowWhileBooting) {
3483            if (!mProcessesOnHold.contains(app)) {
3484                mProcessesOnHold.add(app);
3485            }
3486            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3487                    "System not ready, putting on hold: " + app);
3488            checkTime(startTime, "startProcess: returning with proc on hold");
3489            return app;
3490        }
3491
3492        checkTime(startTime, "startProcess: stepping in to startProcess");
3493        startProcessLocked(
3494                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3495        checkTime(startTime, "startProcess: done starting proc!");
3496        return (app.pid != 0) ? app : null;
3497    }
3498
3499    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3500        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3501    }
3502
3503    private final void startProcessLocked(ProcessRecord app,
3504            String hostingType, String hostingNameStr) {
3505        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3506                null /* entryPoint */, null /* entryPointArgs */);
3507    }
3508
3509    private final void startProcessLocked(ProcessRecord app, String hostingType,
3510            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3511        long startTime = SystemClock.elapsedRealtime();
3512        if (app.pid > 0 && app.pid != MY_PID) {
3513            checkTime(startTime, "startProcess: removing from pids map");
3514            synchronized (mPidsSelfLocked) {
3515                mPidsSelfLocked.remove(app.pid);
3516                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3517            }
3518            checkTime(startTime, "startProcess: done removing from pids map");
3519            app.setPid(0);
3520        }
3521
3522        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3523                "startProcessLocked removing on hold: " + app);
3524        mProcessesOnHold.remove(app);
3525
3526        checkTime(startTime, "startProcess: starting to update cpu stats");
3527        updateCpuStats();
3528        checkTime(startTime, "startProcess: done updating cpu stats");
3529
3530        try {
3531            try {
3532                final int userId = UserHandle.getUserId(app.uid);
3533                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3534            } catch (RemoteException e) {
3535                throw e.rethrowAsRuntimeException();
3536            }
3537
3538            int uid = app.uid;
3539            int[] gids = null;
3540            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3541            if (!app.isolated) {
3542                int[] permGids = null;
3543                try {
3544                    checkTime(startTime, "startProcess: getting gids from package manager");
3545                    final IPackageManager pm = AppGlobals.getPackageManager();
3546                    permGids = pm.getPackageGids(app.info.packageName,
3547                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3548                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3549                            MountServiceInternal.class);
3550                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3551                            app.info.packageName);
3552                } catch (RemoteException e) {
3553                    throw e.rethrowAsRuntimeException();
3554                }
3555
3556                /*
3557                 * Add shared application and profile GIDs so applications can share some
3558                 * resources like shared libraries and access user-wide resources
3559                 */
3560                if (ArrayUtils.isEmpty(permGids)) {
3561                    gids = new int[2];
3562                } else {
3563                    gids = new int[permGids.length + 2];
3564                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3565                }
3566                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3567                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3568            }
3569            checkTime(startTime, "startProcess: building args");
3570            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3571                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3572                        && mTopComponent != null
3573                        && app.processName.equals(mTopComponent.getPackageName())) {
3574                    uid = 0;
3575                }
3576                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3577                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3578                    uid = 0;
3579                }
3580            }
3581            int debugFlags = 0;
3582            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3583                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3584                // Also turn on CheckJNI for debuggable apps. It's quite
3585                // awkward to turn on otherwise.
3586                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3587            }
3588            // Run the app in safe mode if its manifest requests so or the
3589            // system is booted in safe mode.
3590            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3591                mSafeMode == true) {
3592                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3593            }
3594            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3595                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3596            }
3597            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3598            if ("true".equals(genDebugInfoProperty)) {
3599                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3600            }
3601            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3602                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3603            }
3604            if ("1".equals(SystemProperties.get("debug.assert"))) {
3605                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3606            }
3607            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3608                // Enable all debug flags required by the native debugger.
3609                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3610                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3611                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3612                mNativeDebuggingApp = null;
3613            }
3614
3615            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3616            if (requiredAbi == null) {
3617                requiredAbi = Build.SUPPORTED_ABIS[0];
3618            }
3619
3620            String instructionSet = null;
3621            if (app.info.primaryCpuAbi != null) {
3622                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3623            }
3624
3625            app.gids = gids;
3626            app.requiredAbi = requiredAbi;
3627            app.instructionSet = instructionSet;
3628
3629            // Start the process.  It will either succeed and return a result containing
3630            // the PID of the new process, or else throw a RuntimeException.
3631            boolean isActivityProcess = (entryPoint == null);
3632            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3633            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3634                    app.processName);
3635            checkTime(startTime, "startProcess: asking zygote to start proc");
3636            Process.ProcessStartResult startResult = Process.start(entryPoint,
3637                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3638                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3639                    app.info.dataDir, entryPointArgs);
3640            checkTime(startTime, "startProcess: returned from zygote!");
3641            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3642
3643            if (app.isolated) {
3644                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3645            }
3646            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3647            checkTime(startTime, "startProcess: done updating battery stats");
3648
3649            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3650                    UserHandle.getUserId(uid), startResult.pid, uid,
3651                    app.processName, hostingType,
3652                    hostingNameStr != null ? hostingNameStr : "");
3653
3654            try {
3655                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3656                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3657            } catch (RemoteException ex) {
3658                // Ignore
3659            }
3660
3661            if (app.persistent) {
3662                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3663            }
3664
3665            if (DEBUG_PROCESSES) {
3666                checkTime(startTime, "startProcess: building log message");
3667                StringBuilder buf = mStringBuilder;
3668                buf.setLength(0);
3669                buf.append("Start proc ");
3670                buf.append(startResult.pid);
3671                buf.append(':');
3672                buf.append(app.processName);
3673                buf.append('/');
3674                UserHandle.formatUid(buf, uid);
3675                if (!isActivityProcess) {
3676                    buf.append(" [");
3677                    buf.append(entryPoint);
3678                    buf.append("]");
3679                }
3680                buf.append(" for ");
3681                buf.append(hostingType);
3682                if (hostingNameStr != null) {
3683                    buf.append(" ");
3684                    buf.append(hostingNameStr);
3685                }
3686                Slog.i(TAG, buf.toString());
3687            }
3688            app.setPid(startResult.pid);
3689            app.usingWrapper = startResult.usingWrapper;
3690            app.removed = false;
3691            app.killed = false;
3692            app.killedByAm = false;
3693            checkTime(startTime, "startProcess: starting to update pids map");
3694            synchronized (mPidsSelfLocked) {
3695                this.mPidsSelfLocked.put(startResult.pid, app);
3696                if (isActivityProcess) {
3697                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3698                    msg.obj = app;
3699                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3700                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3701                }
3702            }
3703            checkTime(startTime, "startProcess: done updating pids map");
3704        } catch (RuntimeException e) {
3705            // XXX do better error recovery.
3706            app.setPid(0);
3707            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3708            if (app.isolated) {
3709                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3710            }
3711            Slog.e(TAG, "Failure starting process " + app.processName, e);
3712        }
3713    }
3714
3715    void updateUsageStats(ActivityRecord component, boolean resumed) {
3716        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3717                "updateUsageStats: comp=" + component + "res=" + resumed);
3718        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3719        if (resumed) {
3720            if (mUsageStatsService != null) {
3721                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3722                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3723            }
3724            synchronized (stats) {
3725                stats.noteActivityResumedLocked(component.app.uid);
3726            }
3727        } else {
3728            if (mUsageStatsService != null) {
3729                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3730                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3731            }
3732            synchronized (stats) {
3733                stats.noteActivityPausedLocked(component.app.uid);
3734            }
3735        }
3736    }
3737
3738    Intent getHomeIntent() {
3739        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3740        intent.setComponent(mTopComponent);
3741        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3742        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3743            intent.addCategory(Intent.CATEGORY_HOME);
3744        }
3745        return intent;
3746    }
3747
3748    boolean startHomeActivityLocked(int userId, String reason) {
3749        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3750                && mTopAction == null) {
3751            // We are running in factory test mode, but unable to find
3752            // the factory test app, so just sit around displaying the
3753            // error message and don't try to start anything.
3754            return false;
3755        }
3756        Intent intent = getHomeIntent();
3757        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3758        if (aInfo != null) {
3759            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3760            // Don't do this if the home app is currently being
3761            // instrumented.
3762            aInfo = new ActivityInfo(aInfo);
3763            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3764            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3765                    aInfo.applicationInfo.uid, true);
3766            if (app == null || app.instrumentationClass == null) {
3767                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3768                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3769            }
3770        }
3771
3772        return true;
3773    }
3774
3775    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3776        ActivityInfo ai = null;
3777        ComponentName comp = intent.getComponent();
3778        try {
3779            if (comp != null) {
3780                // Factory test.
3781                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3782            } else {
3783                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3784                        intent,
3785                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3786                        flags, userId);
3787
3788                if (info != null) {
3789                    ai = info.activityInfo;
3790                }
3791            }
3792        } catch (RemoteException e) {
3793            // ignore
3794        }
3795
3796        return ai;
3797    }
3798
3799    /**
3800     * Starts the "new version setup screen" if appropriate.
3801     */
3802    void startSetupActivityLocked() {
3803        // Only do this once per boot.
3804        if (mCheckedForSetup) {
3805            return;
3806        }
3807
3808        // We will show this screen if the current one is a different
3809        // version than the last one shown, and we are not running in
3810        // low-level factory test mode.
3811        final ContentResolver resolver = mContext.getContentResolver();
3812        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3813                Settings.Global.getInt(resolver,
3814                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3815            mCheckedForSetup = true;
3816
3817            // See if we should be showing the platform update setup UI.
3818            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3819            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3820                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3821            if (!ris.isEmpty()) {
3822                final ResolveInfo ri = ris.get(0);
3823                String vers = ri.activityInfo.metaData != null
3824                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3825                        : null;
3826                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3827                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3828                            Intent.METADATA_SETUP_VERSION);
3829                }
3830                String lastVers = Settings.Secure.getString(
3831                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3832                if (vers != null && !vers.equals(lastVers)) {
3833                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3834                    intent.setComponent(new ComponentName(
3835                            ri.activityInfo.packageName, ri.activityInfo.name));
3836                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3837                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3838                            null, 0, 0, 0, null, false, false, null, null, null);
3839                }
3840            }
3841        }
3842    }
3843
3844    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3845        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3846    }
3847
3848    void enforceNotIsolatedCaller(String caller) {
3849        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3850            throw new SecurityException("Isolated process not allowed to call " + caller);
3851        }
3852    }
3853
3854    void enforceShellRestriction(String restriction, int userHandle) {
3855        if (Binder.getCallingUid() == Process.SHELL_UID) {
3856            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3857                throw new SecurityException("Shell does not have permission to access user "
3858                        + userHandle);
3859            }
3860        }
3861    }
3862
3863    @Override
3864    public int getFrontActivityScreenCompatMode() {
3865        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3866        synchronized (this) {
3867            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3868        }
3869    }
3870
3871    @Override
3872    public void setFrontActivityScreenCompatMode(int mode) {
3873        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3874                "setFrontActivityScreenCompatMode");
3875        synchronized (this) {
3876            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3877        }
3878    }
3879
3880    @Override
3881    public int getPackageScreenCompatMode(String packageName) {
3882        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3883        synchronized (this) {
3884            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3885        }
3886    }
3887
3888    @Override
3889    public void setPackageScreenCompatMode(String packageName, int mode) {
3890        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3891                "setPackageScreenCompatMode");
3892        synchronized (this) {
3893            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3894        }
3895    }
3896
3897    @Override
3898    public boolean getPackageAskScreenCompat(String packageName) {
3899        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3900        synchronized (this) {
3901            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3902        }
3903    }
3904
3905    @Override
3906    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3907        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3908                "setPackageAskScreenCompat");
3909        synchronized (this) {
3910            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3911        }
3912    }
3913
3914    private boolean hasUsageStatsPermission(String callingPackage) {
3915        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3916                Binder.getCallingUid(), callingPackage);
3917        if (mode == AppOpsManager.MODE_DEFAULT) {
3918            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3919                    == PackageManager.PERMISSION_GRANTED;
3920        }
3921        return mode == AppOpsManager.MODE_ALLOWED;
3922    }
3923
3924    @Override
3925    public int getPackageProcessState(String packageName, String callingPackage) {
3926        if (!hasUsageStatsPermission(callingPackage)) {
3927            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3928                    "getPackageProcessState");
3929        }
3930
3931        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3932        synchronized (this) {
3933            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3934                final ProcessRecord proc = mLruProcesses.get(i);
3935                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3936                        || procState > proc.setProcState) {
3937                    boolean found = false;
3938                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3939                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3940                            procState = proc.setProcState;
3941                            found = true;
3942                        }
3943                    }
3944                    if (proc.pkgDeps != null && !found) {
3945                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3946                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3947                                procState = proc.setProcState;
3948                                break;
3949                            }
3950                        }
3951                    }
3952                }
3953            }
3954        }
3955        return procState;
3956    }
3957
3958    @Override
3959    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3960        synchronized (this) {
3961            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3962            if (app == null) {
3963                return false;
3964            }
3965            if (app.trimMemoryLevel < level && app.thread != null &&
3966                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3967                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3968                try {
3969                    app.thread.scheduleTrimMemory(level);
3970                    app.trimMemoryLevel = level;
3971                    return true;
3972                } catch (RemoteException e) {
3973                    // Fallthrough to failure case.
3974                }
3975            }
3976        }
3977        return false;
3978    }
3979
3980    private void dispatchProcessesChanged() {
3981        int N;
3982        synchronized (this) {
3983            N = mPendingProcessChanges.size();
3984            if (mActiveProcessChanges.length < N) {
3985                mActiveProcessChanges = new ProcessChangeItem[N];
3986            }
3987            mPendingProcessChanges.toArray(mActiveProcessChanges);
3988            mPendingProcessChanges.clear();
3989            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3990                    "*** Delivering " + N + " process changes");
3991        }
3992
3993        int i = mProcessObservers.beginBroadcast();
3994        while (i > 0) {
3995            i--;
3996            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3997            if (observer != null) {
3998                try {
3999                    for (int j=0; j<N; j++) {
4000                        ProcessChangeItem item = mActiveProcessChanges[j];
4001                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4002                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4003                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4004                                    + item.uid + ": " + item.foregroundActivities);
4005                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4006                                    item.foregroundActivities);
4007                        }
4008                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4009                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4010                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4011                                    + ": " + item.processState);
4012                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4013                        }
4014                    }
4015                } catch (RemoteException e) {
4016                }
4017            }
4018        }
4019        mProcessObservers.finishBroadcast();
4020
4021        synchronized (this) {
4022            for (int j=0; j<N; j++) {
4023                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4024            }
4025        }
4026    }
4027
4028    private void dispatchProcessDied(int pid, int uid) {
4029        int i = mProcessObservers.beginBroadcast();
4030        while (i > 0) {
4031            i--;
4032            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4033            if (observer != null) {
4034                try {
4035                    observer.onProcessDied(pid, uid);
4036                } catch (RemoteException e) {
4037                }
4038            }
4039        }
4040        mProcessObservers.finishBroadcast();
4041    }
4042
4043    private void dispatchUidsChanged() {
4044        int N;
4045        synchronized (this) {
4046            N = mPendingUidChanges.size();
4047            if (mActiveUidChanges.length < N) {
4048                mActiveUidChanges = new UidRecord.ChangeItem[N];
4049            }
4050            for (int i=0; i<N; i++) {
4051                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4052                mActiveUidChanges[i] = change;
4053                if (change.uidRecord != null) {
4054                    change.uidRecord.pendingChange = null;
4055                    change.uidRecord = null;
4056                }
4057            }
4058            mPendingUidChanges.clear();
4059            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4060                    "*** Delivering " + N + " uid changes");
4061        }
4062
4063        if (mLocalPowerManager != null) {
4064            for (int j=0; j<N; j++) {
4065                UidRecord.ChangeItem item = mActiveUidChanges[j];
4066                if (item.change == UidRecord.CHANGE_GONE
4067                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4068                    mLocalPowerManager.uidGone(item.uid);
4069                } else {
4070                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4071                }
4072            }
4073        }
4074
4075        int i = mUidObservers.beginBroadcast();
4076        while (i > 0) {
4077            i--;
4078            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4079            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4080            if (observer != null) {
4081                try {
4082                    for (int j=0; j<N; j++) {
4083                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4084                        final int change = item.change;
4085                        UidRecord validateUid = null;
4086                        if (VALIDATE_UID_STATES && i == 0) {
4087                            validateUid = mValidateUids.get(item.uid);
4088                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4089                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4090                                validateUid = new UidRecord(item.uid);
4091                                mValidateUids.put(item.uid, validateUid);
4092                            }
4093                        }
4094                        if (change == UidRecord.CHANGE_IDLE
4095                                || change == UidRecord.CHANGE_GONE_IDLE) {
4096                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4097                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4098                                        "UID idle uid=" + item.uid);
4099                                observer.onUidIdle(item.uid);
4100                            }
4101                            if (VALIDATE_UID_STATES && i == 0) {
4102                                if (validateUid != null) {
4103                                    validateUid.idle = true;
4104                                }
4105                            }
4106                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4107                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4108                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4109                                        "UID active uid=" + item.uid);
4110                                observer.onUidActive(item.uid);
4111                            }
4112                            if (VALIDATE_UID_STATES && i == 0) {
4113                                validateUid.idle = false;
4114                            }
4115                        }
4116                        if (change == UidRecord.CHANGE_GONE
4117                                || change == UidRecord.CHANGE_GONE_IDLE) {
4118                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4119                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4120                                        "UID gone uid=" + item.uid);
4121                                observer.onUidGone(item.uid);
4122                            }
4123                            if (VALIDATE_UID_STATES && i == 0) {
4124                                if (validateUid != null) {
4125                                    mValidateUids.remove(item.uid);
4126                                }
4127                            }
4128                        } else {
4129                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4130                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4131                                        "UID CHANGED uid=" + item.uid
4132                                                + ": " + item.processState);
4133                                observer.onUidStateChanged(item.uid, item.processState);
4134                            }
4135                            if (VALIDATE_UID_STATES && i == 0) {
4136                                validateUid.curProcState = validateUid.setProcState
4137                                        = item.processState;
4138                            }
4139                        }
4140                    }
4141                } catch (RemoteException e) {
4142                }
4143            }
4144        }
4145        mUidObservers.finishBroadcast();
4146
4147        synchronized (this) {
4148            for (int j=0; j<N; j++) {
4149                mAvailUidChanges.add(mActiveUidChanges[j]);
4150            }
4151        }
4152    }
4153
4154    @Override
4155    public final int startActivity(IApplicationThread caller, String callingPackage,
4156            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4157            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4158        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4159                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4160                UserHandle.getCallingUserId());
4161    }
4162
4163    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4164        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4165        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4166                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4167                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4168
4169        // TODO: Switch to user app stacks here.
4170        String mimeType = intent.getType();
4171        final Uri data = intent.getData();
4172        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4173            mimeType = getProviderMimeType(data, userId);
4174        }
4175        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4176
4177        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4178        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4179                null, 0, 0, null, null, null, null, false, userId, container, null);
4180    }
4181
4182    @Override
4183    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4184            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4185            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4186        enforceNotIsolatedCaller("startActivity");
4187        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4188                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4189        // TODO: Switch to user app stacks here.
4190        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4191                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4192                profilerInfo, null, null, bOptions, false, userId, null, null);
4193    }
4194
4195    @Override
4196    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4197            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4198            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4199            int userId) {
4200
4201        // This is very dangerous -- it allows you to perform a start activity (including
4202        // permission grants) as any app that may launch one of your own activities.  So
4203        // we will only allow this to be done from activities that are part of the core framework,
4204        // and then only when they are running as the system.
4205        final ActivityRecord sourceRecord;
4206        final int targetUid;
4207        final String targetPackage;
4208        synchronized (this) {
4209            if (resultTo == null) {
4210                throw new SecurityException("Must be called from an activity");
4211            }
4212            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4213            if (sourceRecord == null) {
4214                throw new SecurityException("Called with bad activity token: " + resultTo);
4215            }
4216            if (!sourceRecord.info.packageName.equals("android")) {
4217                throw new SecurityException(
4218                        "Must be called from an activity that is declared in the android package");
4219            }
4220            if (sourceRecord.app == null) {
4221                throw new SecurityException("Called without a process attached to activity");
4222            }
4223            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4224                // This is still okay, as long as this activity is running under the
4225                // uid of the original calling activity.
4226                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4227                    throw new SecurityException(
4228                            "Calling activity in uid " + sourceRecord.app.uid
4229                                    + " must be system uid or original calling uid "
4230                                    + sourceRecord.launchedFromUid);
4231                }
4232            }
4233            if (ignoreTargetSecurity) {
4234                if (intent.getComponent() == null) {
4235                    throw new SecurityException(
4236                            "Component must be specified with ignoreTargetSecurity");
4237                }
4238                if (intent.getSelector() != null) {
4239                    throw new SecurityException(
4240                            "Selector not allowed with ignoreTargetSecurity");
4241                }
4242            }
4243            targetUid = sourceRecord.launchedFromUid;
4244            targetPackage = sourceRecord.launchedFromPackage;
4245        }
4246
4247        if (userId == UserHandle.USER_NULL) {
4248            userId = UserHandle.getUserId(sourceRecord.app.uid);
4249        }
4250
4251        // TODO: Switch to user app stacks here.
4252        try {
4253            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4254                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4255                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4256            return ret;
4257        } catch (SecurityException e) {
4258            // XXX need to figure out how to propagate to original app.
4259            // A SecurityException here is generally actually a fault of the original
4260            // calling activity (such as a fairly granting permissions), so propagate it
4261            // back to them.
4262            /*
4263            StringBuilder msg = new StringBuilder();
4264            msg.append("While launching");
4265            msg.append(intent.toString());
4266            msg.append(": ");
4267            msg.append(e.getMessage());
4268            */
4269            throw e;
4270        }
4271    }
4272
4273    @Override
4274    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4275            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4276            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4277        enforceNotIsolatedCaller("startActivityAndWait");
4278        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4279                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4280        WaitResult res = new WaitResult();
4281        // TODO: Switch to user app stacks here.
4282        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4283                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4284                bOptions, false, userId, null, null);
4285        return res;
4286    }
4287
4288    @Override
4289    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4290            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4291            int startFlags, Configuration config, Bundle bOptions, int userId) {
4292        enforceNotIsolatedCaller("startActivityWithConfig");
4293        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4294                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4295        // TODO: Switch to user app stacks here.
4296        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4297                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4298                null, null, config, bOptions, false, userId, null, null);
4299        return ret;
4300    }
4301
4302    @Override
4303    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4304            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4305            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4306            throws TransactionTooLargeException {
4307        enforceNotIsolatedCaller("startActivityIntentSender");
4308        // Refuse possible leaked file descriptors
4309        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4310            throw new IllegalArgumentException("File descriptors passed in Intent");
4311        }
4312
4313        IIntentSender sender = intent.getTarget();
4314        if (!(sender instanceof PendingIntentRecord)) {
4315            throw new IllegalArgumentException("Bad PendingIntent object");
4316        }
4317
4318        PendingIntentRecord pir = (PendingIntentRecord)sender;
4319
4320        synchronized (this) {
4321            // If this is coming from the currently resumed activity, it is
4322            // effectively saying that app switches are allowed at this point.
4323            final ActivityStack stack = getFocusedStack();
4324            if (stack.mResumedActivity != null &&
4325                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4326                mAppSwitchesAllowedTime = 0;
4327            }
4328        }
4329        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4330                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4331        return ret;
4332    }
4333
4334    @Override
4335    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4336            Intent intent, String resolvedType, IVoiceInteractionSession session,
4337            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4338            Bundle bOptions, int userId) {
4339        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4340                != PackageManager.PERMISSION_GRANTED) {
4341            String msg = "Permission Denial: startVoiceActivity() from pid="
4342                    + Binder.getCallingPid()
4343                    + ", uid=" + Binder.getCallingUid()
4344                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4345            Slog.w(TAG, msg);
4346            throw new SecurityException(msg);
4347        }
4348        if (session == null || interactor == null) {
4349            throw new NullPointerException("null session or interactor");
4350        }
4351        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4352                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4353        // TODO: Switch to user app stacks here.
4354        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4355                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4356                null, bOptions, false, userId, null, null);
4357    }
4358
4359    @Override
4360    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4361            throws RemoteException {
4362        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4363        synchronized (this) {
4364            ActivityRecord activity = getFocusedStack().topActivity();
4365            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4366                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4367            }
4368            if (mRunningVoice != null || activity.task.voiceSession != null
4369                    || activity.voiceSession != null) {
4370                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4371                return;
4372            }
4373            if (activity.pendingVoiceInteractionStart) {
4374                Slog.w(TAG, "Pending start of voice interaction already.");
4375                return;
4376            }
4377            activity.pendingVoiceInteractionStart = true;
4378        }
4379        LocalServices.getService(VoiceInteractionManagerInternal.class)
4380                .startLocalVoiceInteraction(callingActivity, options);
4381    }
4382
4383    @Override
4384    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4385        LocalServices.getService(VoiceInteractionManagerInternal.class)
4386                .stopLocalVoiceInteraction(callingActivity);
4387    }
4388
4389    @Override
4390    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4391        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4392                .supportsLocalVoiceInteraction();
4393    }
4394
4395    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4396            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4397        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4398        if (activityToCallback == null) return;
4399        activityToCallback.setVoiceSessionLocked(voiceSession);
4400
4401        // Inform the activity
4402        try {
4403            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4404                    voiceInteractor);
4405            long token = Binder.clearCallingIdentity();
4406            try {
4407                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4408            } finally {
4409                Binder.restoreCallingIdentity(token);
4410            }
4411            // TODO: VI Should we cache the activity so that it's easier to find later
4412            // rather than scan through all the stacks and activities?
4413        } catch (RemoteException re) {
4414            activityToCallback.clearVoiceSessionLocked();
4415            // TODO: VI Should this terminate the voice session?
4416        }
4417    }
4418
4419    @Override
4420    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4421        synchronized (this) {
4422            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4423                if (keepAwake) {
4424                    mVoiceWakeLock.acquire();
4425                } else {
4426                    mVoiceWakeLock.release();
4427                }
4428            }
4429        }
4430    }
4431
4432    @Override
4433    public boolean startNextMatchingActivity(IBinder callingActivity,
4434            Intent intent, Bundle bOptions) {
4435        // Refuse possible leaked file descriptors
4436        if (intent != null && intent.hasFileDescriptors() == true) {
4437            throw new IllegalArgumentException("File descriptors passed in Intent");
4438        }
4439        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4440
4441        synchronized (this) {
4442            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4443            if (r == null) {
4444                ActivityOptions.abort(options);
4445                return false;
4446            }
4447            if (r.app == null || r.app.thread == null) {
4448                // The caller is not running...  d'oh!
4449                ActivityOptions.abort(options);
4450                return false;
4451            }
4452            intent = new Intent(intent);
4453            // The caller is not allowed to change the data.
4454            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4455            // And we are resetting to find the next component...
4456            intent.setComponent(null);
4457
4458            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4459
4460            ActivityInfo aInfo = null;
4461            try {
4462                List<ResolveInfo> resolves =
4463                    AppGlobals.getPackageManager().queryIntentActivities(
4464                            intent, r.resolvedType,
4465                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4466                            UserHandle.getCallingUserId()).getList();
4467
4468                // Look for the original activity in the list...
4469                final int N = resolves != null ? resolves.size() : 0;
4470                for (int i=0; i<N; i++) {
4471                    ResolveInfo rInfo = resolves.get(i);
4472                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4473                            && rInfo.activityInfo.name.equals(r.info.name)) {
4474                        // We found the current one...  the next matching is
4475                        // after it.
4476                        i++;
4477                        if (i<N) {
4478                            aInfo = resolves.get(i).activityInfo;
4479                        }
4480                        if (debug) {
4481                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4482                                    + "/" + r.info.name);
4483                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4484                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4485                        }
4486                        break;
4487                    }
4488                }
4489            } catch (RemoteException e) {
4490            }
4491
4492            if (aInfo == null) {
4493                // Nobody who is next!
4494                ActivityOptions.abort(options);
4495                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4496                return false;
4497            }
4498
4499            intent.setComponent(new ComponentName(
4500                    aInfo.applicationInfo.packageName, aInfo.name));
4501            intent.setFlags(intent.getFlags()&~(
4502                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4503                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4504                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4505                    Intent.FLAG_ACTIVITY_NEW_TASK));
4506
4507            // Okay now we need to start the new activity, replacing the
4508            // currently running activity.  This is a little tricky because
4509            // we want to start the new one as if the current one is finished,
4510            // but not finish the current one first so that there is no flicker.
4511            // And thus...
4512            final boolean wasFinishing = r.finishing;
4513            r.finishing = true;
4514
4515            // Propagate reply information over to the new activity.
4516            final ActivityRecord resultTo = r.resultTo;
4517            final String resultWho = r.resultWho;
4518            final int requestCode = r.requestCode;
4519            r.resultTo = null;
4520            if (resultTo != null) {
4521                resultTo.removeResultsLocked(r, resultWho, requestCode);
4522            }
4523
4524            final long origId = Binder.clearCallingIdentity();
4525            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4526                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4527                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4528                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4529                    false, false, null, null, null);
4530            Binder.restoreCallingIdentity(origId);
4531
4532            r.finishing = wasFinishing;
4533            if (res != ActivityManager.START_SUCCESS) {
4534                return false;
4535            }
4536            return true;
4537        }
4538    }
4539
4540    @Override
4541    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4542        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4543            String msg = "Permission Denial: startActivityFromRecents called without " +
4544                    START_TASKS_FROM_RECENTS;
4545            Slog.w(TAG, msg);
4546            throw new SecurityException(msg);
4547        }
4548        final long origId = Binder.clearCallingIdentity();
4549        try {
4550            synchronized (this) {
4551                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4552            }
4553        } finally {
4554            Binder.restoreCallingIdentity(origId);
4555        }
4556    }
4557
4558    final int startActivityInPackage(int uid, String callingPackage,
4559            Intent intent, String resolvedType, IBinder resultTo,
4560            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4561            IActivityContainer container, TaskRecord inTask) {
4562
4563        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4564                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4565
4566        // TODO: Switch to user app stacks here.
4567        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4568                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4569                null, null, null, bOptions, false, userId, container, inTask);
4570        return ret;
4571    }
4572
4573    @Override
4574    public final int startActivities(IApplicationThread caller, String callingPackage,
4575            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4576            int userId) {
4577        enforceNotIsolatedCaller("startActivities");
4578        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4579                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4580        // TODO: Switch to user app stacks here.
4581        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4582                resolvedTypes, resultTo, bOptions, userId);
4583        return ret;
4584    }
4585
4586    final int startActivitiesInPackage(int uid, String callingPackage,
4587            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4588            Bundle bOptions, int userId) {
4589
4590        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4591                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4592        // TODO: Switch to user app stacks here.
4593        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4594                resultTo, bOptions, userId);
4595        return ret;
4596    }
4597
4598    @Override
4599    public void reportActivityFullyDrawn(IBinder token) {
4600        synchronized (this) {
4601            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4602            if (r == null) {
4603                return;
4604            }
4605            r.reportFullyDrawnLocked();
4606        }
4607    }
4608
4609    @Override
4610    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4611        synchronized (this) {
4612            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4613            if (r == null) {
4614                return;
4615            }
4616            TaskRecord task = r.task;
4617            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4618                // Fixed screen orientation isn't supported when activities aren't in full screen
4619                // mode.
4620                return;
4621            }
4622            final long origId = Binder.clearCallingIdentity();
4623            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4624            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4625                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4626            if (config != null) {
4627                r.frozenBeforeDestroy = true;
4628                if (!updateConfigurationLocked(config, r, false)) {
4629                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4630                }
4631            }
4632            Binder.restoreCallingIdentity(origId);
4633        }
4634    }
4635
4636    @Override
4637    public int getRequestedOrientation(IBinder token) {
4638        synchronized (this) {
4639            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4640            if (r == null) {
4641                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4642            }
4643            return mWindowManager.getAppOrientation(r.appToken);
4644        }
4645    }
4646
4647    /**
4648     * This is the internal entry point for handling Activity.finish().
4649     *
4650     * @param token The Binder token referencing the Activity we want to finish.
4651     * @param resultCode Result code, if any, from this Activity.
4652     * @param resultData Result data (Intent), if any, from this Activity.
4653     * @param finishTask Whether to finish the task associated with this Activity.
4654     *
4655     * @return Returns true if the activity successfully finished, or false if it is still running.
4656     */
4657    @Override
4658    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4659            int finishTask) {
4660        // Refuse possible leaked file descriptors
4661        if (resultData != null && resultData.hasFileDescriptors() == true) {
4662            throw new IllegalArgumentException("File descriptors passed in Intent");
4663        }
4664
4665        synchronized(this) {
4666            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4667            if (r == null) {
4668                return true;
4669            }
4670            // Keep track of the root activity of the task before we finish it
4671            TaskRecord tr = r.task;
4672            ActivityRecord rootR = tr.getRootActivity();
4673            if (rootR == null) {
4674                Slog.w(TAG, "Finishing task with all activities already finished");
4675            }
4676            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4677            // finish.
4678            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4679                    mStackSupervisor.isLastLockedTask(tr)) {
4680                Slog.i(TAG, "Not finishing task in lock task mode");
4681                mStackSupervisor.showLockTaskToast();
4682                return false;
4683            }
4684            if (mController != null) {
4685                // Find the first activity that is not finishing.
4686                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4687                if (next != null) {
4688                    // ask watcher if this is allowed
4689                    boolean resumeOK = true;
4690                    try {
4691                        resumeOK = mController.activityResuming(next.packageName);
4692                    } catch (RemoteException e) {
4693                        mController = null;
4694                        Watchdog.getInstance().setActivityController(null);
4695                    }
4696
4697                    if (!resumeOK) {
4698                        Slog.i(TAG, "Not finishing activity because controller resumed");
4699                        return false;
4700                    }
4701                }
4702            }
4703            final long origId = Binder.clearCallingIdentity();
4704            try {
4705                boolean res;
4706                final boolean finishWithRootActivity =
4707                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4708                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4709                        || (finishWithRootActivity && r == rootR)) {
4710                    // If requested, remove the task that is associated to this activity only if it
4711                    // was the root activity in the task. The result code and data is ignored
4712                    // because we don't support returning them across task boundaries. Also, to
4713                    // keep backwards compatibility we remove the task from recents when finishing
4714                    // task with root activity.
4715                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4716                    if (!res) {
4717                        Slog.i(TAG, "Removing task failed to finish activity");
4718                    }
4719                } else {
4720                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4721                            resultData, "app-request", true);
4722                    if (!res) {
4723                        Slog.i(TAG, "Failed to finish by app-request");
4724                    }
4725                }
4726                return res;
4727            } finally {
4728                Binder.restoreCallingIdentity(origId);
4729            }
4730        }
4731    }
4732
4733    @Override
4734    public final void finishHeavyWeightApp() {
4735        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4736                != PackageManager.PERMISSION_GRANTED) {
4737            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4738                    + Binder.getCallingPid()
4739                    + ", uid=" + Binder.getCallingUid()
4740                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4741            Slog.w(TAG, msg);
4742            throw new SecurityException(msg);
4743        }
4744
4745        synchronized(this) {
4746            if (mHeavyWeightProcess == null) {
4747                return;
4748            }
4749
4750            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4751            for (int i = 0; i < activities.size(); i++) {
4752                ActivityRecord r = activities.get(i);
4753                if (!r.finishing && r.isInStackLocked()) {
4754                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4755                            null, "finish-heavy", true);
4756                }
4757            }
4758
4759            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4760                    mHeavyWeightProcess.userId, 0));
4761            mHeavyWeightProcess = null;
4762        }
4763    }
4764
4765    @Override
4766    public void crashApplication(int uid, int initialPid, String packageName,
4767            String message) {
4768        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4769                != PackageManager.PERMISSION_GRANTED) {
4770            String msg = "Permission Denial: crashApplication() from pid="
4771                    + Binder.getCallingPid()
4772                    + ", uid=" + Binder.getCallingUid()
4773                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4774            Slog.w(TAG, msg);
4775            throw new SecurityException(msg);
4776        }
4777
4778        synchronized(this) {
4779            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4780        }
4781    }
4782
4783    @Override
4784    public final void finishSubActivity(IBinder token, String resultWho,
4785            int requestCode) {
4786        synchronized(this) {
4787            final long origId = Binder.clearCallingIdentity();
4788            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4789            if (r != null) {
4790                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4791            }
4792            Binder.restoreCallingIdentity(origId);
4793        }
4794    }
4795
4796    @Override
4797    public boolean finishActivityAffinity(IBinder token) {
4798        synchronized(this) {
4799            final long origId = Binder.clearCallingIdentity();
4800            try {
4801                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4802                if (r == null) {
4803                    return false;
4804                }
4805
4806                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4807                // can finish.
4808                final TaskRecord task = r.task;
4809                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4810                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4811                    mStackSupervisor.showLockTaskToast();
4812                    return false;
4813                }
4814                return task.stack.finishActivityAffinityLocked(r);
4815            } finally {
4816                Binder.restoreCallingIdentity(origId);
4817            }
4818        }
4819    }
4820
4821    @Override
4822    public void finishVoiceTask(IVoiceInteractionSession session) {
4823        synchronized (this) {
4824            final long origId = Binder.clearCallingIdentity();
4825            try {
4826                // TODO: VI Consider treating local voice interactions and voice tasks
4827                // differently here
4828                mStackSupervisor.finishVoiceTask(session);
4829            } finally {
4830                Binder.restoreCallingIdentity(origId);
4831            }
4832        }
4833
4834    }
4835
4836    @Override
4837    public boolean releaseActivityInstance(IBinder token) {
4838        synchronized(this) {
4839            final long origId = Binder.clearCallingIdentity();
4840            try {
4841                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4842                if (r == null) {
4843                    return false;
4844                }
4845                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4846            } finally {
4847                Binder.restoreCallingIdentity(origId);
4848            }
4849        }
4850    }
4851
4852    @Override
4853    public void releaseSomeActivities(IApplicationThread appInt) {
4854        synchronized(this) {
4855            final long origId = Binder.clearCallingIdentity();
4856            try {
4857                ProcessRecord app = getRecordForAppLocked(appInt);
4858                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4859            } finally {
4860                Binder.restoreCallingIdentity(origId);
4861            }
4862        }
4863    }
4864
4865    @Override
4866    public boolean willActivityBeVisible(IBinder token) {
4867        synchronized(this) {
4868            ActivityStack stack = ActivityRecord.getStackLocked(token);
4869            if (stack != null) {
4870                return stack.willActivityBeVisibleLocked(token);
4871            }
4872            return false;
4873        }
4874    }
4875
4876    @Override
4877    public void overridePendingTransition(IBinder token, String packageName,
4878            int enterAnim, int exitAnim) {
4879        synchronized(this) {
4880            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4881            if (self == null) {
4882                return;
4883            }
4884
4885            final long origId = Binder.clearCallingIdentity();
4886
4887            if (self.state == ActivityState.RESUMED
4888                    || self.state == ActivityState.PAUSING) {
4889                mWindowManager.overridePendingAppTransition(packageName,
4890                        enterAnim, exitAnim, null);
4891            }
4892
4893            Binder.restoreCallingIdentity(origId);
4894        }
4895    }
4896
4897    /**
4898     * Main function for removing an existing process from the activity manager
4899     * as a result of that process going away.  Clears out all connections
4900     * to the process.
4901     */
4902    private final void handleAppDiedLocked(ProcessRecord app,
4903            boolean restarting, boolean allowRestart) {
4904        int pid = app.pid;
4905        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4906        if (!kept && !restarting) {
4907            removeLruProcessLocked(app);
4908            if (pid > 0) {
4909                ProcessList.remove(pid);
4910            }
4911        }
4912
4913        if (mProfileProc == app) {
4914            clearProfilerLocked();
4915        }
4916
4917        // Remove this application's activities from active lists.
4918        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4919
4920        app.activities.clear();
4921
4922        if (app.instrumentationClass != null) {
4923            Slog.w(TAG, "Crash of app " + app.processName
4924                  + " running instrumentation " + app.instrumentationClass);
4925            Bundle info = new Bundle();
4926            info.putString("shortMsg", "Process crashed.");
4927            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4928        }
4929
4930        if (!restarting && hasVisibleActivities
4931                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4932            // If there was nothing to resume, and we are not already restarting this process, but
4933            // there is a visible activity that is hosted by the process...  then make sure all
4934            // visible activities are running, taking care of restarting this process.
4935            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4936        }
4937    }
4938
4939    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4940        IBinder threadBinder = thread.asBinder();
4941        // Find the application record.
4942        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4943            ProcessRecord rec = mLruProcesses.get(i);
4944            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4945                return i;
4946            }
4947        }
4948        return -1;
4949    }
4950
4951    final ProcessRecord getRecordForAppLocked(
4952            IApplicationThread thread) {
4953        if (thread == null) {
4954            return null;
4955        }
4956
4957        int appIndex = getLRURecordIndexForAppLocked(thread);
4958        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4959    }
4960
4961    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4962        // If there are no longer any background processes running,
4963        // and the app that died was not running instrumentation,
4964        // then tell everyone we are now low on memory.
4965        boolean haveBg = false;
4966        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4967            ProcessRecord rec = mLruProcesses.get(i);
4968            if (rec.thread != null
4969                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4970                haveBg = true;
4971                break;
4972            }
4973        }
4974
4975        if (!haveBg) {
4976            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4977            if (doReport) {
4978                long now = SystemClock.uptimeMillis();
4979                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4980                    doReport = false;
4981                } else {
4982                    mLastMemUsageReportTime = now;
4983                }
4984            }
4985            final ArrayList<ProcessMemInfo> memInfos
4986                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4987            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4988            long now = SystemClock.uptimeMillis();
4989            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4990                ProcessRecord rec = mLruProcesses.get(i);
4991                if (rec == dyingProc || rec.thread == null) {
4992                    continue;
4993                }
4994                if (doReport) {
4995                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4996                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4997                }
4998                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4999                    // The low memory report is overriding any current
5000                    // state for a GC request.  Make sure to do
5001                    // heavy/important/visible/foreground processes first.
5002                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5003                        rec.lastRequestedGc = 0;
5004                    } else {
5005                        rec.lastRequestedGc = rec.lastLowMemory;
5006                    }
5007                    rec.reportLowMemory = true;
5008                    rec.lastLowMemory = now;
5009                    mProcessesToGc.remove(rec);
5010                    addProcessToGcListLocked(rec);
5011                }
5012            }
5013            if (doReport) {
5014                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5015                mHandler.sendMessage(msg);
5016            }
5017            scheduleAppGcsLocked();
5018        }
5019    }
5020
5021    final void appDiedLocked(ProcessRecord app) {
5022       appDiedLocked(app, app.pid, app.thread, false);
5023    }
5024
5025    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5026            boolean fromBinderDied) {
5027        // First check if this ProcessRecord is actually active for the pid.
5028        synchronized (mPidsSelfLocked) {
5029            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5030            if (curProc != app) {
5031                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5032                return;
5033            }
5034        }
5035
5036        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5037        synchronized (stats) {
5038            stats.noteProcessDiedLocked(app.info.uid, pid);
5039        }
5040
5041        if (!app.killed) {
5042            if (!fromBinderDied) {
5043                Process.killProcessQuiet(pid);
5044            }
5045            killProcessGroup(app.uid, pid);
5046            app.killed = true;
5047        }
5048
5049        // Clean up already done if the process has been re-started.
5050        if (app.pid == pid && app.thread != null &&
5051                app.thread.asBinder() == thread.asBinder()) {
5052            boolean doLowMem = app.instrumentationClass == null;
5053            boolean doOomAdj = doLowMem;
5054            if (!app.killedByAm) {
5055                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5056                        + ") has died");
5057                mAllowLowerMemLevel = true;
5058            } else {
5059                // Note that we always want to do oom adj to update our state with the
5060                // new number of procs.
5061                mAllowLowerMemLevel = false;
5062                doLowMem = false;
5063            }
5064            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5065            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5066                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5067            handleAppDiedLocked(app, false, true);
5068
5069            if (doOomAdj) {
5070                updateOomAdjLocked();
5071            }
5072            if (doLowMem) {
5073                doLowMemReportIfNeededLocked(app);
5074            }
5075        } else if (app.pid != pid) {
5076            // A new process has already been started.
5077            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5078                    + ") has died and restarted (pid " + app.pid + ").");
5079            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5080        } else if (DEBUG_PROCESSES) {
5081            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5082                    + thread.asBinder());
5083        }
5084    }
5085
5086    /**
5087     * If a stack trace dump file is configured, dump process stack traces.
5088     * @param clearTraces causes the dump file to be erased prior to the new
5089     *    traces being written, if true; when false, the new traces will be
5090     *    appended to any existing file content.
5091     * @param firstPids of dalvik VM processes to dump stack traces for first
5092     * @param lastPids of dalvik VM processes to dump stack traces for last
5093     * @param nativeProcs optional list of native process names to dump stack crawls
5094     * @return file containing stack traces, or null if no dump file is configured
5095     */
5096    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5097            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5098        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5099        if (tracesPath == null || tracesPath.length() == 0) {
5100            return null;
5101        }
5102
5103        File tracesFile = new File(tracesPath);
5104        try {
5105            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5106            tracesFile.createNewFile();
5107            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5108        } catch (IOException e) {
5109            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5110            return null;
5111        }
5112
5113        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5114        return tracesFile;
5115    }
5116
5117    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5118            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5119        // Use a FileObserver to detect when traces finish writing.
5120        // The order of traces is considered important to maintain for legibility.
5121        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5122            @Override
5123            public synchronized void onEvent(int event, String path) { notify(); }
5124        };
5125
5126        try {
5127            observer.startWatching();
5128
5129            // First collect all of the stacks of the most important pids.
5130            if (firstPids != null) {
5131                try {
5132                    int num = firstPids.size();
5133                    for (int i = 0; i < num; i++) {
5134                        synchronized (observer) {
5135                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5136                                    + firstPids.get(i));
5137                            final long sime = SystemClock.elapsedRealtime();
5138                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5139                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5140                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5141                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5142                        }
5143                    }
5144                } catch (InterruptedException e) {
5145                    Slog.wtf(TAG, e);
5146                }
5147            }
5148
5149            // Next collect the stacks of the native pids
5150            if (nativeProcs != null) {
5151                int[] pids = Process.getPidsForCommands(nativeProcs);
5152                if (pids != null) {
5153                    for (int pid : pids) {
5154                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5155                        final long sime = SystemClock.elapsedRealtime();
5156                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5157                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5158                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5159                    }
5160                }
5161            }
5162
5163            // Lastly, measure CPU usage.
5164            if (processCpuTracker != null) {
5165                processCpuTracker.init();
5166                System.gc();
5167                processCpuTracker.update();
5168                try {
5169                    synchronized (processCpuTracker) {
5170                        processCpuTracker.wait(500); // measure over 1/2 second.
5171                    }
5172                } catch (InterruptedException e) {
5173                }
5174                processCpuTracker.update();
5175
5176                // We'll take the stack crawls of just the top apps using CPU.
5177                final int N = processCpuTracker.countWorkingStats();
5178                int numProcs = 0;
5179                for (int i=0; i<N && numProcs<5; i++) {
5180                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5181                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5182                        numProcs++;
5183                        try {
5184                            synchronized (observer) {
5185                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5186                                        + stats.pid);
5187                                final long stime = SystemClock.elapsedRealtime();
5188                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5189                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5190                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5191                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5192                            }
5193                        } catch (InterruptedException e) {
5194                            Slog.wtf(TAG, e);
5195                        }
5196                    } else if (DEBUG_ANR) {
5197                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5198                                + stats.pid);
5199                    }
5200                }
5201            }
5202        } finally {
5203            observer.stopWatching();
5204        }
5205    }
5206
5207    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5208        if (true || IS_USER_BUILD) {
5209            return;
5210        }
5211        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5212        if (tracesPath == null || tracesPath.length() == 0) {
5213            return;
5214        }
5215
5216        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5217        StrictMode.allowThreadDiskWrites();
5218        try {
5219            final File tracesFile = new File(tracesPath);
5220            final File tracesDir = tracesFile.getParentFile();
5221            final File tracesTmp = new File(tracesDir, "__tmp__");
5222            try {
5223                if (tracesFile.exists()) {
5224                    tracesTmp.delete();
5225                    tracesFile.renameTo(tracesTmp);
5226                }
5227                StringBuilder sb = new StringBuilder();
5228                Time tobj = new Time();
5229                tobj.set(System.currentTimeMillis());
5230                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5231                sb.append(": ");
5232                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5233                sb.append(" since ");
5234                sb.append(msg);
5235                FileOutputStream fos = new FileOutputStream(tracesFile);
5236                fos.write(sb.toString().getBytes());
5237                if (app == null) {
5238                    fos.write("\n*** No application process!".getBytes());
5239                }
5240                fos.close();
5241                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5242            } catch (IOException e) {
5243                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5244                return;
5245            }
5246
5247            if (app != null) {
5248                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5249                firstPids.add(app.pid);
5250                dumpStackTraces(tracesPath, firstPids, null, null, null);
5251            }
5252
5253            File lastTracesFile = null;
5254            File curTracesFile = null;
5255            for (int i=9; i>=0; i--) {
5256                String name = String.format(Locale.US, "slow%02d.txt", i);
5257                curTracesFile = new File(tracesDir, name);
5258                if (curTracesFile.exists()) {
5259                    if (lastTracesFile != null) {
5260                        curTracesFile.renameTo(lastTracesFile);
5261                    } else {
5262                        curTracesFile.delete();
5263                    }
5264                }
5265                lastTracesFile = curTracesFile;
5266            }
5267            tracesFile.renameTo(curTracesFile);
5268            if (tracesTmp.exists()) {
5269                tracesTmp.renameTo(tracesFile);
5270            }
5271        } finally {
5272            StrictMode.setThreadPolicy(oldPolicy);
5273        }
5274    }
5275
5276    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5277        if (!mLaunchWarningShown) {
5278            mLaunchWarningShown = true;
5279            mUiHandler.post(new Runnable() {
5280                @Override
5281                public void run() {
5282                    synchronized (ActivityManagerService.this) {
5283                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5284                        d.show();
5285                        mUiHandler.postDelayed(new Runnable() {
5286                            @Override
5287                            public void run() {
5288                                synchronized (ActivityManagerService.this) {
5289                                    d.dismiss();
5290                                    mLaunchWarningShown = false;
5291                                }
5292                            }
5293                        }, 4000);
5294                    }
5295                }
5296            });
5297        }
5298    }
5299
5300    @Override
5301    public boolean clearApplicationUserData(final String packageName,
5302            final IPackageDataObserver observer, int userId) {
5303        enforceNotIsolatedCaller("clearApplicationUserData");
5304        int uid = Binder.getCallingUid();
5305        int pid = Binder.getCallingPid();
5306        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5307                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5308
5309        final DevicePolicyManagerInternal dpmi = LocalServices
5310                .getService(DevicePolicyManagerInternal.class);
5311        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5312            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5313        }
5314
5315        long callingId = Binder.clearCallingIdentity();
5316        try {
5317            IPackageManager pm = AppGlobals.getPackageManager();
5318            int pkgUid = -1;
5319            synchronized(this) {
5320                try {
5321                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5322                } catch (RemoteException e) {
5323                }
5324                if (pkgUid == -1) {
5325                    Slog.w(TAG, "Invalid packageName: " + packageName);
5326                    if (observer != null) {
5327                        try {
5328                            observer.onRemoveCompleted(packageName, false);
5329                        } catch (RemoteException e) {
5330                            Slog.i(TAG, "Observer no longer exists.");
5331                        }
5332                    }
5333                    return false;
5334                }
5335                if (uid == pkgUid || checkComponentPermission(
5336                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5337                        pid, uid, -1, true)
5338                        == PackageManager.PERMISSION_GRANTED) {
5339                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5340                } else {
5341                    throw new SecurityException("PID " + pid + " does not have permission "
5342                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5343                                    + " of package " + packageName);
5344                }
5345
5346                // Remove all tasks match the cleared application package and user
5347                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5348                    final TaskRecord tr = mRecentTasks.get(i);
5349                    final String taskPackageName =
5350                            tr.getBaseIntent().getComponent().getPackageName();
5351                    if (tr.userId != userId) continue;
5352                    if (!taskPackageName.equals(packageName)) continue;
5353                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5354                }
5355            }
5356
5357            try {
5358                // Clear application user data
5359                pm.clearApplicationUserData(packageName, observer, userId);
5360
5361                synchronized(this) {
5362                    // Remove all permissions granted from/to this package
5363                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5364                }
5365
5366                // Remove all zen rules created by this package; revoke it's zen access.
5367                INotificationManager inm = NotificationManager.getService();
5368                inm.removeAutomaticZenRules(packageName);
5369                inm.setNotificationPolicyAccessGranted(packageName, false);
5370
5371                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5372                        Uri.fromParts("package", packageName, null));
5373                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5374                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5375                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5376                        null, null, 0, null, null, null, null, false, false, userId);
5377            } catch (RemoteException e) {
5378            }
5379        } finally {
5380            Binder.restoreCallingIdentity(callingId);
5381        }
5382        return true;
5383    }
5384
5385    @Override
5386    public void killBackgroundProcesses(final String packageName, int userId) {
5387        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5388                != PackageManager.PERMISSION_GRANTED &&
5389                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5390                        != PackageManager.PERMISSION_GRANTED) {
5391            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5392                    + Binder.getCallingPid()
5393                    + ", uid=" + Binder.getCallingUid()
5394                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5395            Slog.w(TAG, msg);
5396            throw new SecurityException(msg);
5397        }
5398
5399        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5400                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5401        long callingId = Binder.clearCallingIdentity();
5402        try {
5403            IPackageManager pm = AppGlobals.getPackageManager();
5404            synchronized(this) {
5405                int appId = -1;
5406                try {
5407                    appId = UserHandle.getAppId(
5408                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5409                } catch (RemoteException e) {
5410                }
5411                if (appId == -1) {
5412                    Slog.w(TAG, "Invalid packageName: " + packageName);
5413                    return;
5414                }
5415                killPackageProcessesLocked(packageName, appId, userId,
5416                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5417            }
5418        } finally {
5419            Binder.restoreCallingIdentity(callingId);
5420        }
5421    }
5422
5423    @Override
5424    public void killAllBackgroundProcesses() {
5425        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5426                != PackageManager.PERMISSION_GRANTED) {
5427            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5428                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5429                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5430            Slog.w(TAG, msg);
5431            throw new SecurityException(msg);
5432        }
5433
5434        final long callingId = Binder.clearCallingIdentity();
5435        try {
5436            synchronized (this) {
5437                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5438                final int NP = mProcessNames.getMap().size();
5439                for (int ip = 0; ip < NP; ip++) {
5440                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5441                    final int NA = apps.size();
5442                    for (int ia = 0; ia < NA; ia++) {
5443                        final ProcessRecord app = apps.valueAt(ia);
5444                        if (app.persistent) {
5445                            // We don't kill persistent processes.
5446                            continue;
5447                        }
5448                        if (app.removed) {
5449                            procs.add(app);
5450                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5451                            app.removed = true;
5452                            procs.add(app);
5453                        }
5454                    }
5455                }
5456
5457                final int N = procs.size();
5458                for (int i = 0; i < N; i++) {
5459                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5460                }
5461
5462                mAllowLowerMemLevel = true;
5463
5464                updateOomAdjLocked();
5465                doLowMemReportIfNeededLocked(null);
5466            }
5467        } finally {
5468            Binder.restoreCallingIdentity(callingId);
5469        }
5470    }
5471
5472    /**
5473     * Kills all background processes, except those matching any of the
5474     * specified properties.
5475     *
5476     * @param minTargetSdk the target SDK version at or above which to preserve
5477     *                     processes, or {@code -1} to ignore the target SDK
5478     * @param maxProcState the process state at or below which to preserve
5479     *                     processes, or {@code -1} to ignore the process state
5480     */
5481    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5482        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5483                != PackageManager.PERMISSION_GRANTED) {
5484            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5485                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5486                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5487            Slog.w(TAG, msg);
5488            throw new SecurityException(msg);
5489        }
5490
5491        final long callingId = Binder.clearCallingIdentity();
5492        try {
5493            synchronized (this) {
5494                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5495                final int NP = mProcessNames.getMap().size();
5496                for (int ip = 0; ip < NP; ip++) {
5497                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5498                    final int NA = apps.size();
5499                    for (int ia = 0; ia < NA; ia++) {
5500                        final ProcessRecord app = apps.valueAt(ia);
5501                        if (app.removed) {
5502                            procs.add(app);
5503                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5504                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5505                            app.removed = true;
5506                            procs.add(app);
5507                        }
5508                    }
5509                }
5510
5511                final int N = procs.size();
5512                for (int i = 0; i < N; i++) {
5513                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5514                }
5515            }
5516        } finally {
5517            Binder.restoreCallingIdentity(callingId);
5518        }
5519    }
5520
5521    @Override
5522    public void forceStopPackage(final String packageName, int userId) {
5523        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5524                != PackageManager.PERMISSION_GRANTED) {
5525            String msg = "Permission Denial: forceStopPackage() from pid="
5526                    + Binder.getCallingPid()
5527                    + ", uid=" + Binder.getCallingUid()
5528                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5529            Slog.w(TAG, msg);
5530            throw new SecurityException(msg);
5531        }
5532        final int callingPid = Binder.getCallingPid();
5533        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5534                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5535        long callingId = Binder.clearCallingIdentity();
5536        try {
5537            IPackageManager pm = AppGlobals.getPackageManager();
5538            synchronized(this) {
5539                int[] users = userId == UserHandle.USER_ALL
5540                        ? mUserController.getUsers() : new int[] { userId };
5541                for (int user : users) {
5542                    int pkgUid = -1;
5543                    try {
5544                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5545                                user);
5546                    } catch (RemoteException e) {
5547                    }
5548                    if (pkgUid == -1) {
5549                        Slog.w(TAG, "Invalid packageName: " + packageName);
5550                        continue;
5551                    }
5552                    try {
5553                        pm.setPackageStoppedState(packageName, true, user);
5554                    } catch (RemoteException e) {
5555                    } catch (IllegalArgumentException e) {
5556                        Slog.w(TAG, "Failed trying to unstop package "
5557                                + packageName + ": " + e);
5558                    }
5559                    if (mUserController.isUserRunningLocked(user, 0)) {
5560                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5561                    }
5562                }
5563            }
5564        } finally {
5565            Binder.restoreCallingIdentity(callingId);
5566        }
5567    }
5568
5569    @Override
5570    public void addPackageDependency(String packageName) {
5571        synchronized (this) {
5572            int callingPid = Binder.getCallingPid();
5573            if (callingPid == Process.myPid()) {
5574                //  Yeah, um, no.
5575                return;
5576            }
5577            ProcessRecord proc;
5578            synchronized (mPidsSelfLocked) {
5579                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5580            }
5581            if (proc != null) {
5582                if (proc.pkgDeps == null) {
5583                    proc.pkgDeps = new ArraySet<String>(1);
5584                }
5585                proc.pkgDeps.add(packageName);
5586            }
5587        }
5588    }
5589
5590    /*
5591     * The pkg name and app id have to be specified.
5592     */
5593    @Override
5594    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5595        if (pkg == null) {
5596            return;
5597        }
5598        // Make sure the uid is valid.
5599        if (appid < 0) {
5600            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5601            return;
5602        }
5603        int callerUid = Binder.getCallingUid();
5604        // Only the system server can kill an application
5605        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5606            // Post an aysnc message to kill the application
5607            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5608            msg.arg1 = appid;
5609            msg.arg2 = 0;
5610            Bundle bundle = new Bundle();
5611            bundle.putString("pkg", pkg);
5612            bundle.putString("reason", reason);
5613            msg.obj = bundle;
5614            mHandler.sendMessage(msg);
5615        } else {
5616            throw new SecurityException(callerUid + " cannot kill pkg: " +
5617                    pkg);
5618        }
5619    }
5620
5621    @Override
5622    public void closeSystemDialogs(String reason) {
5623        enforceNotIsolatedCaller("closeSystemDialogs");
5624
5625        final int pid = Binder.getCallingPid();
5626        final int uid = Binder.getCallingUid();
5627        final long origId = Binder.clearCallingIdentity();
5628        try {
5629            synchronized (this) {
5630                // Only allow this from foreground processes, so that background
5631                // applications can't abuse it to prevent system UI from being shown.
5632                if (uid >= Process.FIRST_APPLICATION_UID) {
5633                    ProcessRecord proc;
5634                    synchronized (mPidsSelfLocked) {
5635                        proc = mPidsSelfLocked.get(pid);
5636                    }
5637                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5638                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5639                                + " from background process " + proc);
5640                        return;
5641                    }
5642                }
5643                closeSystemDialogsLocked(reason);
5644            }
5645        } finally {
5646            Binder.restoreCallingIdentity(origId);
5647        }
5648    }
5649
5650    void closeSystemDialogsLocked(String reason) {
5651        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5652        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5653                | Intent.FLAG_RECEIVER_FOREGROUND);
5654        if (reason != null) {
5655            intent.putExtra("reason", reason);
5656        }
5657        mWindowManager.closeSystemDialogs(reason);
5658
5659        mStackSupervisor.closeSystemDialogsLocked();
5660
5661        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5662                AppOpsManager.OP_NONE, null, false, false,
5663                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5664    }
5665
5666    @Override
5667    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5668        enforceNotIsolatedCaller("getProcessMemoryInfo");
5669        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5670        for (int i=pids.length-1; i>=0; i--) {
5671            ProcessRecord proc;
5672            int oomAdj;
5673            synchronized (this) {
5674                synchronized (mPidsSelfLocked) {
5675                    proc = mPidsSelfLocked.get(pids[i]);
5676                    oomAdj = proc != null ? proc.setAdj : 0;
5677                }
5678            }
5679            infos[i] = new Debug.MemoryInfo();
5680            Debug.getMemoryInfo(pids[i], infos[i]);
5681            if (proc != null) {
5682                synchronized (this) {
5683                    if (proc.thread != null && proc.setAdj == oomAdj) {
5684                        // Record this for posterity if the process has been stable.
5685                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5686                                infos[i].getTotalUss(), false, proc.pkgList);
5687                    }
5688                }
5689            }
5690        }
5691        return infos;
5692    }
5693
5694    @Override
5695    public long[] getProcessPss(int[] pids) {
5696        enforceNotIsolatedCaller("getProcessPss");
5697        long[] pss = new long[pids.length];
5698        for (int i=pids.length-1; i>=0; i--) {
5699            ProcessRecord proc;
5700            int oomAdj;
5701            synchronized (this) {
5702                synchronized (mPidsSelfLocked) {
5703                    proc = mPidsSelfLocked.get(pids[i]);
5704                    oomAdj = proc != null ? proc.setAdj : 0;
5705                }
5706            }
5707            long[] tmpUss = new long[1];
5708            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5709            if (proc != null) {
5710                synchronized (this) {
5711                    if (proc.thread != null && proc.setAdj == oomAdj) {
5712                        // Record this for posterity if the process has been stable.
5713                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5714                    }
5715                }
5716            }
5717        }
5718        return pss;
5719    }
5720
5721    @Override
5722    public void killApplicationProcess(String processName, int uid) {
5723        if (processName == null) {
5724            return;
5725        }
5726
5727        int callerUid = Binder.getCallingUid();
5728        // Only the system server can kill an application
5729        if (callerUid == Process.SYSTEM_UID) {
5730            synchronized (this) {
5731                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5732                if (app != null && app.thread != null) {
5733                    try {
5734                        app.thread.scheduleSuicide();
5735                    } catch (RemoteException e) {
5736                        // If the other end already died, then our work here is done.
5737                    }
5738                } else {
5739                    Slog.w(TAG, "Process/uid not found attempting kill of "
5740                            + processName + " / " + uid);
5741                }
5742            }
5743        } else {
5744            throw new SecurityException(callerUid + " cannot kill app process: " +
5745                    processName);
5746        }
5747    }
5748
5749    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5750        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5751                false, true, false, false, UserHandle.getUserId(uid), reason);
5752        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5753                Uri.fromParts("package", packageName, null));
5754        if (!mProcessesReady) {
5755            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5756                    | Intent.FLAG_RECEIVER_FOREGROUND);
5757        }
5758        intent.putExtra(Intent.EXTRA_UID, uid);
5759        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5760        broadcastIntentLocked(null, null, intent,
5761                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5762                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5763    }
5764
5765
5766    private final boolean killPackageProcessesLocked(String packageName, int appId,
5767            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5768            boolean doit, boolean evenPersistent, String reason) {
5769        ArrayList<ProcessRecord> procs = new ArrayList<>();
5770
5771        // Remove all processes this package may have touched: all with the
5772        // same UID (except for the system or root user), and all whose name
5773        // matches the package name.
5774        final int NP = mProcessNames.getMap().size();
5775        for (int ip=0; ip<NP; ip++) {
5776            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5777            final int NA = apps.size();
5778            for (int ia=0; ia<NA; ia++) {
5779                ProcessRecord app = apps.valueAt(ia);
5780                if (app.persistent && !evenPersistent) {
5781                    // we don't kill persistent processes
5782                    continue;
5783                }
5784                if (app.removed) {
5785                    if (doit) {
5786                        procs.add(app);
5787                    }
5788                    continue;
5789                }
5790
5791                // Skip process if it doesn't meet our oom adj requirement.
5792                if (app.setAdj < minOomAdj) {
5793                    continue;
5794                }
5795
5796                // If no package is specified, we call all processes under the
5797                // give user id.
5798                if (packageName == null) {
5799                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5800                        continue;
5801                    }
5802                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5803                        continue;
5804                    }
5805                // Package has been specified, we want to hit all processes
5806                // that match it.  We need to qualify this by the processes
5807                // that are running under the specified app and user ID.
5808                } else {
5809                    final boolean isDep = app.pkgDeps != null
5810                            && app.pkgDeps.contains(packageName);
5811                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5812                        continue;
5813                    }
5814                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5815                        continue;
5816                    }
5817                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5818                        continue;
5819                    }
5820                }
5821
5822                // Process has passed all conditions, kill it!
5823                if (!doit) {
5824                    return true;
5825                }
5826                app.removed = true;
5827                procs.add(app);
5828            }
5829        }
5830
5831        int N = procs.size();
5832        for (int i=0; i<N; i++) {
5833            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5834        }
5835        updateOomAdjLocked();
5836        return N > 0;
5837    }
5838
5839    private void cleanupDisabledPackageComponentsLocked(
5840            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5841
5842        Set<String> disabledClasses = null;
5843        boolean packageDisabled = false;
5844        IPackageManager pm = AppGlobals.getPackageManager();
5845
5846        if (changedClasses == null) {
5847            // Nothing changed...
5848            return;
5849        }
5850
5851        // Determine enable/disable state of the package and its components.
5852        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5853        for (int i = changedClasses.length - 1; i >= 0; i--) {
5854            final String changedClass = changedClasses[i];
5855
5856            if (changedClass.equals(packageName)) {
5857                try {
5858                    // Entire package setting changed
5859                    enabled = pm.getApplicationEnabledSetting(packageName,
5860                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5861                } catch (Exception e) {
5862                    // No such package/component; probably racing with uninstall.  In any
5863                    // event it means we have nothing further to do here.
5864                    return;
5865                }
5866                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5867                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5868                if (packageDisabled) {
5869                    // Entire package is disabled.
5870                    // No need to continue to check component states.
5871                    disabledClasses = null;
5872                    break;
5873                }
5874            } else {
5875                try {
5876                    enabled = pm.getComponentEnabledSetting(
5877                            new ComponentName(packageName, changedClass),
5878                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5879                } catch (Exception e) {
5880                    // As above, probably racing with uninstall.
5881                    return;
5882                }
5883                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5884                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5885                    if (disabledClasses == null) {
5886                        disabledClasses = new ArraySet<>(changedClasses.length);
5887                    }
5888                    disabledClasses.add(changedClass);
5889                }
5890            }
5891        }
5892
5893        if (!packageDisabled && disabledClasses == null) {
5894            // Nothing to do here...
5895            return;
5896        }
5897
5898        // Clean-up disabled activities.
5899        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5900                packageName, disabledClasses, true, false, userId) && mBooted) {
5901            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5902            mStackSupervisor.scheduleIdleLocked();
5903        }
5904
5905        // Clean-up disabled tasks
5906        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5907
5908        // Clean-up disabled services.
5909        mServices.bringDownDisabledPackageServicesLocked(
5910                packageName, disabledClasses, userId, false, killProcess, true);
5911
5912        // Clean-up disabled providers.
5913        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5914        mProviderMap.collectPackageProvidersLocked(
5915                packageName, disabledClasses, true, false, userId, providers);
5916        for (int i = providers.size() - 1; i >= 0; i--) {
5917            removeDyingProviderLocked(null, providers.get(i), true);
5918        }
5919
5920        // Clean-up disabled broadcast receivers.
5921        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5922            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5923                    packageName, disabledClasses, userId, true);
5924        }
5925
5926    }
5927
5928    final boolean forceStopPackageLocked(String packageName, int appId,
5929            boolean callerWillRestart, boolean purgeCache, boolean doit,
5930            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5931        int i;
5932
5933        if (userId == UserHandle.USER_ALL && packageName == null) {
5934            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5935        }
5936
5937        if (appId < 0 && packageName != null) {
5938            try {
5939                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5940                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5941            } catch (RemoteException e) {
5942            }
5943        }
5944
5945        if (doit) {
5946            if (packageName != null) {
5947                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5948                        + " user=" + userId + ": " + reason);
5949            } else {
5950                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5951            }
5952
5953            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5954        }
5955
5956        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5957                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5958                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5959
5960        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5961                packageName, null, doit, evenPersistent, userId)) {
5962            if (!doit) {
5963                return true;
5964            }
5965            didSomething = true;
5966        }
5967
5968        if (mServices.bringDownDisabledPackageServicesLocked(
5969                packageName, null, userId, evenPersistent, true, doit)) {
5970            if (!doit) {
5971                return true;
5972            }
5973            didSomething = true;
5974        }
5975
5976        if (packageName == null) {
5977            // Remove all sticky broadcasts from this user.
5978            mStickyBroadcasts.remove(userId);
5979        }
5980
5981        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5982        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5983                userId, providers)) {
5984            if (!doit) {
5985                return true;
5986            }
5987            didSomething = true;
5988        }
5989        for (i = providers.size() - 1; i >= 0; i--) {
5990            removeDyingProviderLocked(null, providers.get(i), true);
5991        }
5992
5993        // Remove transient permissions granted from/to this package/user
5994        removeUriPermissionsForPackageLocked(packageName, userId, false);
5995
5996        if (doit) {
5997            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5998                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5999                        packageName, null, userId, doit);
6000            }
6001        }
6002
6003        if (packageName == null || uninstalling) {
6004            // Remove pending intents.  For now we only do this when force
6005            // stopping users, because we have some problems when doing this
6006            // for packages -- app widgets are not currently cleaned up for
6007            // such packages, so they can be left with bad pending intents.
6008            if (mIntentSenderRecords.size() > 0) {
6009                Iterator<WeakReference<PendingIntentRecord>> it
6010                        = mIntentSenderRecords.values().iterator();
6011                while (it.hasNext()) {
6012                    WeakReference<PendingIntentRecord> wpir = it.next();
6013                    if (wpir == null) {
6014                        it.remove();
6015                        continue;
6016                    }
6017                    PendingIntentRecord pir = wpir.get();
6018                    if (pir == null) {
6019                        it.remove();
6020                        continue;
6021                    }
6022                    if (packageName == null) {
6023                        // Stopping user, remove all objects for the user.
6024                        if (pir.key.userId != userId) {
6025                            // Not the same user, skip it.
6026                            continue;
6027                        }
6028                    } else {
6029                        if (UserHandle.getAppId(pir.uid) != appId) {
6030                            // Different app id, skip it.
6031                            continue;
6032                        }
6033                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6034                            // Different user, skip it.
6035                            continue;
6036                        }
6037                        if (!pir.key.packageName.equals(packageName)) {
6038                            // Different package, skip it.
6039                            continue;
6040                        }
6041                    }
6042                    if (!doit) {
6043                        return true;
6044                    }
6045                    didSomething = true;
6046                    it.remove();
6047                    pir.canceled = true;
6048                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6049                        pir.key.activity.pendingResults.remove(pir.ref);
6050                    }
6051                }
6052            }
6053        }
6054
6055        if (doit) {
6056            if (purgeCache && packageName != null) {
6057                AttributeCache ac = AttributeCache.instance();
6058                if (ac != null) {
6059                    ac.removePackage(packageName);
6060                }
6061            }
6062            if (mBooted) {
6063                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6064                mStackSupervisor.scheduleIdleLocked();
6065            }
6066        }
6067
6068        return didSomething;
6069    }
6070
6071    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6072        ProcessRecord old = mProcessNames.remove(name, uid);
6073        if (old != null) {
6074            old.uidRecord.numProcs--;
6075            if (old.uidRecord.numProcs == 0) {
6076                // No more processes using this uid, tell clients it is gone.
6077                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6078                        "No more processes in " + old.uidRecord);
6079                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6080                mActiveUids.remove(uid);
6081                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6082            }
6083            old.uidRecord = null;
6084        }
6085        mIsolatedProcesses.remove(uid);
6086        return old;
6087    }
6088
6089    private final void addProcessNameLocked(ProcessRecord proc) {
6090        // We shouldn't already have a process under this name, but just in case we
6091        // need to clean up whatever may be there now.
6092        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6093        if (old == proc && proc.persistent) {
6094            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6095            Slog.w(TAG, "Re-adding persistent process " + proc);
6096        } else if (old != null) {
6097            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6098        }
6099        UidRecord uidRec = mActiveUids.get(proc.uid);
6100        if (uidRec == null) {
6101            uidRec = new UidRecord(proc.uid);
6102            // This is the first appearance of the uid, report it now!
6103            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6104                    "Creating new process uid: " + uidRec);
6105            mActiveUids.put(proc.uid, uidRec);
6106            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6107            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6108        }
6109        proc.uidRecord = uidRec;
6110        uidRec.numProcs++;
6111        mProcessNames.put(proc.processName, proc.uid, proc);
6112        if (proc.isolated) {
6113            mIsolatedProcesses.put(proc.uid, proc);
6114        }
6115    }
6116
6117    boolean removeProcessLocked(ProcessRecord app,
6118            boolean callerWillRestart, boolean allowRestart, String reason) {
6119        final String name = app.processName;
6120        final int uid = app.uid;
6121        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6122            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6123
6124        removeProcessNameLocked(name, uid);
6125        if (mHeavyWeightProcess == app) {
6126            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6127                    mHeavyWeightProcess.userId, 0));
6128            mHeavyWeightProcess = null;
6129        }
6130        boolean needRestart = false;
6131        if (app.pid > 0 && app.pid != MY_PID) {
6132            int pid = app.pid;
6133            synchronized (mPidsSelfLocked) {
6134                mPidsSelfLocked.remove(pid);
6135                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6136            }
6137            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6138            if (app.isolated) {
6139                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6140            }
6141            boolean willRestart = false;
6142            if (app.persistent && !app.isolated) {
6143                if (!callerWillRestart) {
6144                    willRestart = true;
6145                } else {
6146                    needRestart = true;
6147                }
6148            }
6149            app.kill(reason, true);
6150            handleAppDiedLocked(app, willRestart, allowRestart);
6151            if (willRestart) {
6152                removeLruProcessLocked(app);
6153                addAppLocked(app.info, false, null /* ABI override */);
6154            }
6155        } else {
6156            mRemovedProcesses.add(app);
6157        }
6158
6159        return needRestart;
6160    }
6161
6162    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6163        cleanupAppInLaunchingProvidersLocked(app, true);
6164        removeProcessLocked(app, false, true, "timeout publishing content providers");
6165    }
6166
6167    private final void processStartTimedOutLocked(ProcessRecord app) {
6168        final int pid = app.pid;
6169        boolean gone = false;
6170        synchronized (mPidsSelfLocked) {
6171            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6172            if (knownApp != null && knownApp.thread == null) {
6173                mPidsSelfLocked.remove(pid);
6174                gone = true;
6175            }
6176        }
6177
6178        if (gone) {
6179            Slog.w(TAG, "Process " + app + " failed to attach");
6180            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6181                    pid, app.uid, app.processName);
6182            removeProcessNameLocked(app.processName, app.uid);
6183            if (mHeavyWeightProcess == app) {
6184                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6185                        mHeavyWeightProcess.userId, 0));
6186                mHeavyWeightProcess = null;
6187            }
6188            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6189            if (app.isolated) {
6190                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6191            }
6192            // Take care of any launching providers waiting for this process.
6193            cleanupAppInLaunchingProvidersLocked(app, true);
6194            // Take care of any services that are waiting for the process.
6195            mServices.processStartTimedOutLocked(app);
6196            app.kill("start timeout", true);
6197            removeLruProcessLocked(app);
6198            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6199                Slog.w(TAG, "Unattached app died before backup, skipping");
6200                try {
6201                    IBackupManager bm = IBackupManager.Stub.asInterface(
6202                            ServiceManager.getService(Context.BACKUP_SERVICE));
6203                    bm.agentDisconnected(app.info.packageName);
6204                } catch (RemoteException e) {
6205                    // Can't happen; the backup manager is local
6206                }
6207            }
6208            if (isPendingBroadcastProcessLocked(pid)) {
6209                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6210                skipPendingBroadcastLocked(pid);
6211            }
6212        } else {
6213            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6214        }
6215    }
6216
6217    private final boolean attachApplicationLocked(IApplicationThread thread,
6218            int pid) {
6219
6220        // Find the application record that is being attached...  either via
6221        // the pid if we are running in multiple processes, or just pull the
6222        // next app record if we are emulating process with anonymous threads.
6223        ProcessRecord app;
6224        if (pid != MY_PID && pid >= 0) {
6225            synchronized (mPidsSelfLocked) {
6226                app = mPidsSelfLocked.get(pid);
6227            }
6228        } else {
6229            app = null;
6230        }
6231
6232        if (app == null) {
6233            Slog.w(TAG, "No pending application record for pid " + pid
6234                    + " (IApplicationThread " + thread + "); dropping process");
6235            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6236            if (pid > 0 && pid != MY_PID) {
6237                Process.killProcessQuiet(pid);
6238                //TODO: killProcessGroup(app.info.uid, pid);
6239            } else {
6240                try {
6241                    thread.scheduleExit();
6242                } catch (Exception e) {
6243                    // Ignore exceptions.
6244                }
6245            }
6246            return false;
6247        }
6248
6249        // If this application record is still attached to a previous
6250        // process, clean it up now.
6251        if (app.thread != null) {
6252            handleAppDiedLocked(app, true, true);
6253        }
6254
6255        // Tell the process all about itself.
6256
6257        if (DEBUG_ALL) Slog.v(
6258                TAG, "Binding process pid " + pid + " to record " + app);
6259
6260        final String processName = app.processName;
6261        try {
6262            AppDeathRecipient adr = new AppDeathRecipient(
6263                    app, pid, thread);
6264            thread.asBinder().linkToDeath(adr, 0);
6265            app.deathRecipient = adr;
6266        } catch (RemoteException e) {
6267            app.resetPackageList(mProcessStats);
6268            startProcessLocked(app, "link fail", processName);
6269            return false;
6270        }
6271
6272        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6273
6274        app.makeActive(thread, mProcessStats);
6275        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6276        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6277        app.forcingToForeground = null;
6278        updateProcessForegroundLocked(app, false, false);
6279        app.hasShownUi = false;
6280        app.debugging = false;
6281        app.cached = false;
6282        app.killedByAm = false;
6283        app.unlocked = mContext.getSystemService(UserManager.class).isUserUnlocked(app.userId);
6284
6285        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6286
6287        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6288        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6289
6290        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6291            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6292            msg.obj = app;
6293            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6294        }
6295
6296        if (!normalMode) {
6297            Slog.i(TAG, "Launching preboot mode app: " + app);
6298        }
6299
6300        if (DEBUG_ALL) Slog.v(
6301            TAG, "New app record " + app
6302            + " thread=" + thread.asBinder() + " pid=" + pid);
6303        try {
6304            int testMode = IApplicationThread.DEBUG_OFF;
6305            if (mDebugApp != null && mDebugApp.equals(processName)) {
6306                testMode = mWaitForDebugger
6307                    ? IApplicationThread.DEBUG_WAIT
6308                    : IApplicationThread.DEBUG_ON;
6309                app.debugging = true;
6310                if (mDebugTransient) {
6311                    mDebugApp = mOrigDebugApp;
6312                    mWaitForDebugger = mOrigWaitForDebugger;
6313                }
6314            }
6315            String profileFile = app.instrumentationProfileFile;
6316            ParcelFileDescriptor profileFd = null;
6317            int samplingInterval = 0;
6318            boolean profileAutoStop = false;
6319            if (mProfileApp != null && mProfileApp.equals(processName)) {
6320                mProfileProc = app;
6321                profileFile = mProfileFile;
6322                profileFd = mProfileFd;
6323                samplingInterval = mSamplingInterval;
6324                profileAutoStop = mAutoStopProfiler;
6325            }
6326            boolean enableTrackAllocation = false;
6327            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6328                enableTrackAllocation = true;
6329                mTrackAllocationApp = null;
6330            }
6331
6332            // If the app is being launched for restore or full backup, set it up specially
6333            boolean isRestrictedBackupMode = false;
6334            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6335                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6336                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6337                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6338                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6339            }
6340
6341            notifyPackageUse(app.instrumentationInfo != null
6342                    ? app.instrumentationInfo.packageName
6343                    : app.info.packageName);
6344            if (app.instrumentationClass != null) {
6345                notifyPackageUse(app.instrumentationClass.getPackageName());
6346            }
6347            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6348                    + processName + " with config " + mConfiguration);
6349            ApplicationInfo appInfo = app.instrumentationInfo != null
6350                    ? app.instrumentationInfo : app.info;
6351            app.compat = compatibilityInfoForPackageLocked(appInfo);
6352            if (profileFd != null) {
6353                profileFd = profileFd.dup();
6354            }
6355            ProfilerInfo profilerInfo = profileFile == null ? null
6356                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6357            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6358                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6359                    app.instrumentationUiAutomationConnection, testMode,
6360                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6361                    isRestrictedBackupMode || !normalMode, app.persistent,
6362                    new Configuration(mConfiguration), app.compat,
6363                    getCommonServicesLocked(app.isolated),
6364                    mCoreSettingsObserver.getCoreSettingsLocked());
6365            updateLruProcessLocked(app, false, null);
6366            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6367        } catch (Exception e) {
6368            // todo: Yikes!  What should we do?  For now we will try to
6369            // start another process, but that could easily get us in
6370            // an infinite loop of restarting processes...
6371            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6372
6373            app.resetPackageList(mProcessStats);
6374            app.unlinkDeathRecipient();
6375            startProcessLocked(app, "bind fail", processName);
6376            return false;
6377        }
6378
6379        // Remove this record from the list of starting applications.
6380        mPersistentStartingProcesses.remove(app);
6381        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6382                "Attach application locked removing on hold: " + app);
6383        mProcessesOnHold.remove(app);
6384
6385        boolean badApp = false;
6386        boolean didSomething = false;
6387
6388        // See if the top visible activity is waiting to run in this process...
6389        if (normalMode) {
6390            try {
6391                if (mStackSupervisor.attachApplicationLocked(app)) {
6392                    didSomething = true;
6393                }
6394            } catch (Exception e) {
6395                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6396                badApp = true;
6397            }
6398        }
6399
6400        // Find any services that should be running in this process...
6401        if (!badApp) {
6402            try {
6403                didSomething |= mServices.attachApplicationLocked(app, processName);
6404            } catch (Exception e) {
6405                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6406                badApp = true;
6407            }
6408        }
6409
6410        // Check if a next-broadcast receiver is in this process...
6411        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6412            try {
6413                didSomething |= sendPendingBroadcastsLocked(app);
6414            } catch (Exception e) {
6415                // If the app died trying to launch the receiver we declare it 'bad'
6416                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6417                badApp = true;
6418            }
6419        }
6420
6421        // Check whether the next backup agent is in this process...
6422        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6423            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6424                    "New app is backup target, launching agent for " + app);
6425            notifyPackageUse(mBackupTarget.appInfo.packageName);
6426            try {
6427                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6428                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6429                        mBackupTarget.backupMode);
6430            } catch (Exception e) {
6431                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6432                badApp = true;
6433            }
6434        }
6435
6436        if (badApp) {
6437            app.kill("error during init", true);
6438            handleAppDiedLocked(app, false, true);
6439            return false;
6440        }
6441
6442        if (!didSomething) {
6443            updateOomAdjLocked();
6444        }
6445
6446        return true;
6447    }
6448
6449    @Override
6450    public final void attachApplication(IApplicationThread thread) {
6451        synchronized (this) {
6452            int callingPid = Binder.getCallingPid();
6453            final long origId = Binder.clearCallingIdentity();
6454            attachApplicationLocked(thread, callingPid);
6455            Binder.restoreCallingIdentity(origId);
6456        }
6457    }
6458
6459    @Override
6460    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6461        final long origId = Binder.clearCallingIdentity();
6462        synchronized (this) {
6463            ActivityStack stack = ActivityRecord.getStackLocked(token);
6464            if (stack != null) {
6465                ActivityRecord r =
6466                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6467                if (stopProfiling) {
6468                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6469                        try {
6470                            mProfileFd.close();
6471                        } catch (IOException e) {
6472                        }
6473                        clearProfilerLocked();
6474                    }
6475                }
6476            }
6477        }
6478        Binder.restoreCallingIdentity(origId);
6479    }
6480
6481    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6482        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6483                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6484    }
6485
6486    void enableScreenAfterBoot() {
6487        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6488                SystemClock.uptimeMillis());
6489        mWindowManager.enableScreenAfterBoot();
6490
6491        synchronized (this) {
6492            updateEventDispatchingLocked();
6493        }
6494    }
6495
6496    @Override
6497    public void showBootMessage(final CharSequence msg, final boolean always) {
6498        if (Binder.getCallingUid() != Process.myUid()) {
6499            // These days only the core system can call this, so apps can't get in
6500            // the way of what we show about running them.
6501        }
6502        mWindowManager.showBootMessage(msg, always);
6503    }
6504
6505    @Override
6506    public void keyguardWaitingForActivityDrawn() {
6507        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6508        final long token = Binder.clearCallingIdentity();
6509        try {
6510            synchronized (this) {
6511                if (DEBUG_LOCKSCREEN) logLockScreen("");
6512                mWindowManager.keyguardWaitingForActivityDrawn();
6513                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6514                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6515                    updateSleepIfNeededLocked();
6516                }
6517            }
6518        } finally {
6519            Binder.restoreCallingIdentity(token);
6520        }
6521    }
6522
6523    @Override
6524    public void keyguardGoingAway(int flags) {
6525        enforceNotIsolatedCaller("keyguardGoingAway");
6526        final long token = Binder.clearCallingIdentity();
6527        try {
6528            synchronized (this) {
6529                if (DEBUG_LOCKSCREEN) logLockScreen("");
6530                mWindowManager.keyguardGoingAway(flags);
6531                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6532                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6533                    updateSleepIfNeededLocked();
6534
6535                    // Some stack visibility might change (e.g. docked stack)
6536                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6537                }
6538            }
6539        } finally {
6540            Binder.restoreCallingIdentity(token);
6541        }
6542    }
6543
6544    final void finishBooting() {
6545        synchronized (this) {
6546            if (!mBootAnimationComplete) {
6547                mCallFinishBooting = true;
6548                return;
6549            }
6550            mCallFinishBooting = false;
6551        }
6552
6553        ArraySet<String> completedIsas = new ArraySet<String>();
6554        for (String abi : Build.SUPPORTED_ABIS) {
6555            Process.establishZygoteConnectionForAbi(abi);
6556            final String instructionSet = VMRuntime.getInstructionSet(abi);
6557            if (!completedIsas.contains(instructionSet)) {
6558                try {
6559                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6560                } catch (InstallerException e) {
6561                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6562                }
6563                completedIsas.add(instructionSet);
6564            }
6565        }
6566
6567        IntentFilter pkgFilter = new IntentFilter();
6568        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6569        pkgFilter.addDataScheme("package");
6570        mContext.registerReceiver(new BroadcastReceiver() {
6571            @Override
6572            public void onReceive(Context context, Intent intent) {
6573                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6574                if (pkgs != null) {
6575                    for (String pkg : pkgs) {
6576                        synchronized (ActivityManagerService.this) {
6577                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6578                                    0, "query restart")) {
6579                                setResultCode(Activity.RESULT_OK);
6580                                return;
6581                            }
6582                        }
6583                    }
6584                }
6585            }
6586        }, pkgFilter);
6587
6588        IntentFilter dumpheapFilter = new IntentFilter();
6589        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6590        mContext.registerReceiver(new BroadcastReceiver() {
6591            @Override
6592            public void onReceive(Context context, Intent intent) {
6593                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6594                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6595                } else {
6596                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6597                }
6598            }
6599        }, dumpheapFilter);
6600
6601        // Let system services know.
6602        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6603
6604        synchronized (this) {
6605            // Ensure that any processes we had put on hold are now started
6606            // up.
6607            final int NP = mProcessesOnHold.size();
6608            if (NP > 0) {
6609                ArrayList<ProcessRecord> procs =
6610                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6611                for (int ip=0; ip<NP; ip++) {
6612                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6613                            + procs.get(ip));
6614                    startProcessLocked(procs.get(ip), "on-hold", null);
6615                }
6616            }
6617
6618            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6619                // Start looking for apps that are abusing wake locks.
6620                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6621                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6622                // Tell anyone interested that we are done booting!
6623                SystemProperties.set("sys.boot_completed", "1");
6624
6625                // And trigger dev.bootcomplete if we are not showing encryption progress
6626                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6627                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6628                    SystemProperties.set("dev.bootcomplete", "1");
6629                }
6630                mUserController.sendBootCompletedLocked(
6631                        new IIntentReceiver.Stub() {
6632                            @Override
6633                            public void performReceive(Intent intent, int resultCode,
6634                                    String data, Bundle extras, boolean ordered,
6635                                    boolean sticky, int sendingUser) {
6636                                synchronized (ActivityManagerService.this) {
6637                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6638                                            true, false);
6639                                }
6640                            }
6641                        });
6642                scheduleStartProfilesLocked();
6643            }
6644        }
6645    }
6646
6647    @Override
6648    public void bootAnimationComplete() {
6649        final boolean callFinishBooting;
6650        synchronized (this) {
6651            callFinishBooting = mCallFinishBooting;
6652            mBootAnimationComplete = true;
6653        }
6654        if (callFinishBooting) {
6655            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6656            finishBooting();
6657            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6658        }
6659    }
6660
6661    final void ensureBootCompleted() {
6662        boolean booting;
6663        boolean enableScreen;
6664        synchronized (this) {
6665            booting = mBooting;
6666            mBooting = false;
6667            enableScreen = !mBooted;
6668            mBooted = true;
6669        }
6670
6671        if (booting) {
6672            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6673            finishBooting();
6674            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6675        }
6676
6677        if (enableScreen) {
6678            enableScreenAfterBoot();
6679        }
6680    }
6681
6682    @Override
6683    public final void activityResumed(IBinder token) {
6684        final long origId = Binder.clearCallingIdentity();
6685        synchronized(this) {
6686            ActivityStack stack = ActivityRecord.getStackLocked(token);
6687            if (stack != null) {
6688                stack.activityResumedLocked(token);
6689            }
6690        }
6691        Binder.restoreCallingIdentity(origId);
6692    }
6693
6694    @Override
6695    public final void activityPaused(IBinder token) {
6696        final long origId = Binder.clearCallingIdentity();
6697        synchronized(this) {
6698            ActivityStack stack = ActivityRecord.getStackLocked(token);
6699            if (stack != null) {
6700                stack.activityPausedLocked(token, false);
6701            }
6702        }
6703        Binder.restoreCallingIdentity(origId);
6704    }
6705
6706    @Override
6707    public final void activityStopped(IBinder token, Bundle icicle,
6708            PersistableBundle persistentState, CharSequence description) {
6709        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6710
6711        // Refuse possible leaked file descriptors
6712        if (icicle != null && icicle.hasFileDescriptors()) {
6713            throw new IllegalArgumentException("File descriptors passed in Bundle");
6714        }
6715
6716        final long origId = Binder.clearCallingIdentity();
6717
6718        synchronized (this) {
6719            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6720            if (r != null) {
6721                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6722            }
6723        }
6724
6725        trimApplications();
6726
6727        Binder.restoreCallingIdentity(origId);
6728    }
6729
6730    @Override
6731    public final void activityDestroyed(IBinder token) {
6732        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6733        synchronized (this) {
6734            ActivityStack stack = ActivityRecord.getStackLocked(token);
6735            if (stack != null) {
6736                stack.activityDestroyedLocked(token, "activityDestroyed");
6737            }
6738        }
6739    }
6740
6741    @Override
6742    public final void activityRelaunched(IBinder token) {
6743        final long origId = Binder.clearCallingIdentity();
6744        synchronized (this) {
6745            mStackSupervisor.activityRelaunchedLocked(token);
6746        }
6747        Binder.restoreCallingIdentity(origId);
6748    }
6749
6750    @Override
6751    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6752            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6753        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6754                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6755        synchronized (this) {
6756            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6757            if (record == null) {
6758                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6759                        + "found for: " + token);
6760            }
6761            record.setSizeConfigurations(horizontalSizeConfiguration,
6762                    verticalSizeConfigurations, smallestSizeConfigurations);
6763        }
6764    }
6765
6766    @Override
6767    public final void backgroundResourcesReleased(IBinder token) {
6768        final long origId = Binder.clearCallingIdentity();
6769        try {
6770            synchronized (this) {
6771                ActivityStack stack = ActivityRecord.getStackLocked(token);
6772                if (stack != null) {
6773                    stack.backgroundResourcesReleased();
6774                }
6775            }
6776        } finally {
6777            Binder.restoreCallingIdentity(origId);
6778        }
6779    }
6780
6781    @Override
6782    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6783        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6784    }
6785
6786    @Override
6787    public final void notifyEnterAnimationComplete(IBinder token) {
6788        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6789    }
6790
6791    @Override
6792    public String getCallingPackage(IBinder token) {
6793        synchronized (this) {
6794            ActivityRecord r = getCallingRecordLocked(token);
6795            return r != null ? r.info.packageName : null;
6796        }
6797    }
6798
6799    @Override
6800    public ComponentName getCallingActivity(IBinder token) {
6801        synchronized (this) {
6802            ActivityRecord r = getCallingRecordLocked(token);
6803            return r != null ? r.intent.getComponent() : null;
6804        }
6805    }
6806
6807    private ActivityRecord getCallingRecordLocked(IBinder token) {
6808        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6809        if (r == null) {
6810            return null;
6811        }
6812        return r.resultTo;
6813    }
6814
6815    @Override
6816    public ComponentName getActivityClassForToken(IBinder token) {
6817        synchronized(this) {
6818            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6819            if (r == null) {
6820                return null;
6821            }
6822            return r.intent.getComponent();
6823        }
6824    }
6825
6826    @Override
6827    public String getPackageForToken(IBinder token) {
6828        synchronized(this) {
6829            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6830            if (r == null) {
6831                return null;
6832            }
6833            return r.packageName;
6834        }
6835    }
6836
6837    @Override
6838    public boolean isRootVoiceInteraction(IBinder token) {
6839        synchronized(this) {
6840            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6841            if (r == null) {
6842                return false;
6843            }
6844            return r.rootVoiceInteraction;
6845        }
6846    }
6847
6848    @Override
6849    public IIntentSender getIntentSender(int type,
6850            String packageName, IBinder token, String resultWho,
6851            int requestCode, Intent[] intents, String[] resolvedTypes,
6852            int flags, Bundle bOptions, int userId) {
6853        enforceNotIsolatedCaller("getIntentSender");
6854        // Refuse possible leaked file descriptors
6855        if (intents != null) {
6856            if (intents.length < 1) {
6857                throw new IllegalArgumentException("Intents array length must be >= 1");
6858            }
6859            for (int i=0; i<intents.length; i++) {
6860                Intent intent = intents[i];
6861                if (intent != null) {
6862                    if (intent.hasFileDescriptors()) {
6863                        throw new IllegalArgumentException("File descriptors passed in Intent");
6864                    }
6865                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6866                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6867                        throw new IllegalArgumentException(
6868                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6869                    }
6870                    intents[i] = new Intent(intent);
6871                }
6872            }
6873            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6874                throw new IllegalArgumentException(
6875                        "Intent array length does not match resolvedTypes length");
6876            }
6877        }
6878        if (bOptions != null) {
6879            if (bOptions.hasFileDescriptors()) {
6880                throw new IllegalArgumentException("File descriptors passed in options");
6881            }
6882        }
6883
6884        synchronized(this) {
6885            int callingUid = Binder.getCallingUid();
6886            int origUserId = userId;
6887            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6888                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6889                    ALLOW_NON_FULL, "getIntentSender", null);
6890            if (origUserId == UserHandle.USER_CURRENT) {
6891                // We don't want to evaluate this until the pending intent is
6892                // actually executed.  However, we do want to always do the
6893                // security checking for it above.
6894                userId = UserHandle.USER_CURRENT;
6895            }
6896            try {
6897                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6898                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6899                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6900                    if (!UserHandle.isSameApp(callingUid, uid)) {
6901                        String msg = "Permission Denial: getIntentSender() from pid="
6902                            + Binder.getCallingPid()
6903                            + ", uid=" + Binder.getCallingUid()
6904                            + ", (need uid=" + uid + ")"
6905                            + " is not allowed to send as package " + packageName;
6906                        Slog.w(TAG, msg);
6907                        throw new SecurityException(msg);
6908                    }
6909                }
6910
6911                return getIntentSenderLocked(type, packageName, callingUid, userId,
6912                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6913
6914            } catch (RemoteException e) {
6915                throw new SecurityException(e);
6916            }
6917        }
6918    }
6919
6920    IIntentSender getIntentSenderLocked(int type, String packageName,
6921            int callingUid, int userId, IBinder token, String resultWho,
6922            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6923            Bundle bOptions) {
6924        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6925        ActivityRecord activity = null;
6926        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6927            activity = ActivityRecord.isInStackLocked(token);
6928            if (activity == null) {
6929                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6930                return null;
6931            }
6932            if (activity.finishing) {
6933                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6934                return null;
6935            }
6936        }
6937
6938        // We're going to be splicing together extras before sending, so we're
6939        // okay poking into any contained extras.
6940        if (intents != null) {
6941            for (int i = 0; i < intents.length; i++) {
6942                intents[i].setDefusable(true);
6943            }
6944        }
6945        Bundle.setDefusable(bOptions, true);
6946
6947        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6948        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6949        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6950        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6951                |PendingIntent.FLAG_UPDATE_CURRENT);
6952
6953        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6954                type, packageName, activity, resultWho,
6955                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6956        WeakReference<PendingIntentRecord> ref;
6957        ref = mIntentSenderRecords.get(key);
6958        PendingIntentRecord rec = ref != null ? ref.get() : null;
6959        if (rec != null) {
6960            if (!cancelCurrent) {
6961                if (updateCurrent) {
6962                    if (rec.key.requestIntent != null) {
6963                        rec.key.requestIntent.replaceExtras(intents != null ?
6964                                intents[intents.length - 1] : null);
6965                    }
6966                    if (intents != null) {
6967                        intents[intents.length-1] = rec.key.requestIntent;
6968                        rec.key.allIntents = intents;
6969                        rec.key.allResolvedTypes = resolvedTypes;
6970                    } else {
6971                        rec.key.allIntents = null;
6972                        rec.key.allResolvedTypes = null;
6973                    }
6974                }
6975                return rec;
6976            }
6977            rec.canceled = true;
6978            mIntentSenderRecords.remove(key);
6979        }
6980        if (noCreate) {
6981            return rec;
6982        }
6983        rec = new PendingIntentRecord(this, key, callingUid);
6984        mIntentSenderRecords.put(key, rec.ref);
6985        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6986            if (activity.pendingResults == null) {
6987                activity.pendingResults
6988                        = new HashSet<WeakReference<PendingIntentRecord>>();
6989            }
6990            activity.pendingResults.add(rec.ref);
6991        }
6992        return rec;
6993    }
6994
6995    @Override
6996    public void cancelIntentSender(IIntentSender sender) {
6997        if (!(sender instanceof PendingIntentRecord)) {
6998            return;
6999        }
7000        synchronized(this) {
7001            PendingIntentRecord rec = (PendingIntentRecord)sender;
7002            try {
7003                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7004                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7005                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7006                    String msg = "Permission Denial: cancelIntentSender() from pid="
7007                        + Binder.getCallingPid()
7008                        + ", uid=" + Binder.getCallingUid()
7009                        + " is not allowed to cancel packges "
7010                        + rec.key.packageName;
7011                    Slog.w(TAG, msg);
7012                    throw new SecurityException(msg);
7013                }
7014            } catch (RemoteException e) {
7015                throw new SecurityException(e);
7016            }
7017            cancelIntentSenderLocked(rec, true);
7018        }
7019    }
7020
7021    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7022        rec.canceled = true;
7023        mIntentSenderRecords.remove(rec.key);
7024        if (cleanActivity && rec.key.activity != null) {
7025            rec.key.activity.pendingResults.remove(rec.ref);
7026        }
7027    }
7028
7029    @Override
7030    public String getPackageForIntentSender(IIntentSender pendingResult) {
7031        if (!(pendingResult instanceof PendingIntentRecord)) {
7032            return null;
7033        }
7034        try {
7035            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7036            return res.key.packageName;
7037        } catch (ClassCastException e) {
7038        }
7039        return null;
7040    }
7041
7042    @Override
7043    public int getUidForIntentSender(IIntentSender sender) {
7044        if (sender instanceof PendingIntentRecord) {
7045            try {
7046                PendingIntentRecord res = (PendingIntentRecord)sender;
7047                return res.uid;
7048            } catch (ClassCastException e) {
7049            }
7050        }
7051        return -1;
7052    }
7053
7054    @Override
7055    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7056        if (!(pendingResult instanceof PendingIntentRecord)) {
7057            return false;
7058        }
7059        try {
7060            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7061            if (res.key.allIntents == null) {
7062                return false;
7063            }
7064            for (int i=0; i<res.key.allIntents.length; i++) {
7065                Intent intent = res.key.allIntents[i];
7066                if (intent.getPackage() != null && intent.getComponent() != null) {
7067                    return false;
7068                }
7069            }
7070            return true;
7071        } catch (ClassCastException e) {
7072        }
7073        return false;
7074    }
7075
7076    @Override
7077    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7078        if (!(pendingResult instanceof PendingIntentRecord)) {
7079            return false;
7080        }
7081        try {
7082            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7083            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7084                return true;
7085            }
7086            return false;
7087        } catch (ClassCastException e) {
7088        }
7089        return false;
7090    }
7091
7092    @Override
7093    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7094        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7095                "getIntentForIntentSender()");
7096        if (!(pendingResult instanceof PendingIntentRecord)) {
7097            return null;
7098        }
7099        try {
7100            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7101            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7102        } catch (ClassCastException e) {
7103        }
7104        return null;
7105    }
7106
7107    @Override
7108    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7109        if (!(pendingResult instanceof PendingIntentRecord)) {
7110            return null;
7111        }
7112        try {
7113            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7114            synchronized (this) {
7115                return getTagForIntentSenderLocked(res, prefix);
7116            }
7117        } catch (ClassCastException e) {
7118        }
7119        return null;
7120    }
7121
7122    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7123        final Intent intent = res.key.requestIntent;
7124        if (intent != null) {
7125            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7126                    || res.lastTagPrefix.equals(prefix))) {
7127                return res.lastTag;
7128            }
7129            res.lastTagPrefix = prefix;
7130            final StringBuilder sb = new StringBuilder(128);
7131            if (prefix != null) {
7132                sb.append(prefix);
7133            }
7134            if (intent.getAction() != null) {
7135                sb.append(intent.getAction());
7136            } else if (intent.getComponent() != null) {
7137                intent.getComponent().appendShortString(sb);
7138            } else {
7139                sb.append("?");
7140            }
7141            return res.lastTag = sb.toString();
7142        }
7143        return null;
7144    }
7145
7146    @Override
7147    public void setProcessLimit(int max) {
7148        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7149                "setProcessLimit()");
7150        synchronized (this) {
7151            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7152            mProcessLimitOverride = max;
7153        }
7154        trimApplications();
7155    }
7156
7157    @Override
7158    public int getProcessLimit() {
7159        synchronized (this) {
7160            return mProcessLimitOverride;
7161        }
7162    }
7163
7164    void foregroundTokenDied(ForegroundToken token) {
7165        synchronized (ActivityManagerService.this) {
7166            synchronized (mPidsSelfLocked) {
7167                ForegroundToken cur
7168                    = mForegroundProcesses.get(token.pid);
7169                if (cur != token) {
7170                    return;
7171                }
7172                mForegroundProcesses.remove(token.pid);
7173                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7174                if (pr == null) {
7175                    return;
7176                }
7177                pr.forcingToForeground = null;
7178                updateProcessForegroundLocked(pr, false, false);
7179            }
7180            updateOomAdjLocked();
7181        }
7182    }
7183
7184    @Override
7185    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7186        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7187                "setProcessForeground()");
7188        synchronized(this) {
7189            boolean changed = false;
7190
7191            synchronized (mPidsSelfLocked) {
7192                ProcessRecord pr = mPidsSelfLocked.get(pid);
7193                if (pr == null && isForeground) {
7194                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7195                    return;
7196                }
7197                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7198                if (oldToken != null) {
7199                    oldToken.token.unlinkToDeath(oldToken, 0);
7200                    mForegroundProcesses.remove(pid);
7201                    if (pr != null) {
7202                        pr.forcingToForeground = null;
7203                    }
7204                    changed = true;
7205                }
7206                if (isForeground && token != null) {
7207                    ForegroundToken newToken = new ForegroundToken() {
7208                        @Override
7209                        public void binderDied() {
7210                            foregroundTokenDied(this);
7211                        }
7212                    };
7213                    newToken.pid = pid;
7214                    newToken.token = token;
7215                    try {
7216                        token.linkToDeath(newToken, 0);
7217                        mForegroundProcesses.put(pid, newToken);
7218                        pr.forcingToForeground = token;
7219                        changed = true;
7220                    } catch (RemoteException e) {
7221                        // If the process died while doing this, we will later
7222                        // do the cleanup with the process death link.
7223                    }
7224                }
7225            }
7226
7227            if (changed) {
7228                updateOomAdjLocked();
7229            }
7230        }
7231    }
7232
7233    @Override
7234    public boolean isAppForeground(int uid) throws RemoteException {
7235        synchronized (this) {
7236            UidRecord uidRec = mActiveUids.get(uid);
7237            if (uidRec == null || uidRec.idle) {
7238                return false;
7239            }
7240            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7241        }
7242    }
7243
7244    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7245    // be guarded by permission checking.
7246    int getUidState(int uid) {
7247        synchronized (this) {
7248            UidRecord uidRec = mActiveUids.get(uid);
7249            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7250        }
7251    }
7252
7253    @Override
7254    public boolean isInMultiWindowMode(IBinder token) {
7255        final long origId = Binder.clearCallingIdentity();
7256        try {
7257            synchronized(this) {
7258                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7259                if (r == null) {
7260                    return false;
7261                }
7262                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7263                return !r.task.mFullscreen;
7264            }
7265        } finally {
7266            Binder.restoreCallingIdentity(origId);
7267        }
7268    }
7269
7270    @Override
7271    public boolean isInPictureInPictureMode(IBinder token) {
7272        final long origId = Binder.clearCallingIdentity();
7273        try {
7274            synchronized(this) {
7275                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7276                if (stack == null) {
7277                    return false;
7278                }
7279                return stack.mStackId == PINNED_STACK_ID;
7280            }
7281        } finally {
7282            Binder.restoreCallingIdentity(origId);
7283        }
7284    }
7285
7286    @Override
7287    public void enterPictureInPictureMode(IBinder token) {
7288        final long origId = Binder.clearCallingIdentity();
7289        try {
7290            synchronized(this) {
7291                if (!mSupportsPictureInPicture) {
7292                    throw new IllegalStateException("enterPictureInPictureMode: "
7293                            + "Device doesn't support picture-in-picture mode.");
7294                }
7295
7296                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7297
7298                if (r == null) {
7299                    throw new IllegalStateException("enterPictureInPictureMode: "
7300                            + "Can't find activity for token=" + token);
7301                }
7302
7303                if (!r.supportsPictureInPicture()) {
7304                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7305                            + "Picture-In-Picture not supported for r=" + r);
7306                }
7307
7308                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7309                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7310                        ? mDefaultPinnedStackBounds : null;
7311
7312                mStackSupervisor.moveActivityToPinnedStackLocked(
7313                        r, "enterPictureInPictureMode", bounds);
7314            }
7315        } finally {
7316            Binder.restoreCallingIdentity(origId);
7317        }
7318    }
7319
7320    // =========================================================
7321    // PROCESS INFO
7322    // =========================================================
7323
7324    static class ProcessInfoService extends IProcessInfoService.Stub {
7325        final ActivityManagerService mActivityManagerService;
7326        ProcessInfoService(ActivityManagerService activityManagerService) {
7327            mActivityManagerService = activityManagerService;
7328        }
7329
7330        @Override
7331        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7332            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7333                    /*in*/ pids, /*out*/ states, null);
7334        }
7335
7336        @Override
7337        public void getProcessStatesAndOomScoresFromPids(
7338                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7339            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7340                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7341        }
7342    }
7343
7344    /**
7345     * For each PID in the given input array, write the current process state
7346     * for that process into the states array, or -1 to indicate that no
7347     * process with the given PID exists. If scores array is provided, write
7348     * the oom score for the process into the scores array, with INVALID_ADJ
7349     * indicating the PID doesn't exist.
7350     */
7351    public void getProcessStatesAndOomScoresForPIDs(
7352            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7353        if (scores != null) {
7354            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7355                    "getProcessStatesAndOomScoresForPIDs()");
7356        }
7357
7358        if (pids == null) {
7359            throw new NullPointerException("pids");
7360        } else if (states == null) {
7361            throw new NullPointerException("states");
7362        } else if (pids.length != states.length) {
7363            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7364        } else if (scores != null && pids.length != scores.length) {
7365            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7366        }
7367
7368        synchronized (mPidsSelfLocked) {
7369            for (int i = 0; i < pids.length; i++) {
7370                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7371                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7372                        pr.curProcState;
7373                if (scores != null) {
7374                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7375                }
7376            }
7377        }
7378    }
7379
7380    // =========================================================
7381    // PERMISSIONS
7382    // =========================================================
7383
7384    static class PermissionController extends IPermissionController.Stub {
7385        ActivityManagerService mActivityManagerService;
7386        PermissionController(ActivityManagerService activityManagerService) {
7387            mActivityManagerService = activityManagerService;
7388        }
7389
7390        @Override
7391        public boolean checkPermission(String permission, int pid, int uid) {
7392            return mActivityManagerService.checkPermission(permission, pid,
7393                    uid) == PackageManager.PERMISSION_GRANTED;
7394        }
7395
7396        @Override
7397        public String[] getPackagesForUid(int uid) {
7398            return mActivityManagerService.mContext.getPackageManager()
7399                    .getPackagesForUid(uid);
7400        }
7401
7402        @Override
7403        public boolean isRuntimePermission(String permission) {
7404            try {
7405                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7406                        .getPermissionInfo(permission, 0);
7407                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7408            } catch (NameNotFoundException nnfe) {
7409                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7410            }
7411            return false;
7412        }
7413    }
7414
7415    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7416        @Override
7417        public int checkComponentPermission(String permission, int pid, int uid,
7418                int owningUid, boolean exported) {
7419            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7420                    owningUid, exported);
7421        }
7422
7423        @Override
7424        public Object getAMSLock() {
7425            return ActivityManagerService.this;
7426        }
7427    }
7428
7429    /**
7430     * This can be called with or without the global lock held.
7431     */
7432    int checkComponentPermission(String permission, int pid, int uid,
7433            int owningUid, boolean exported) {
7434        if (pid == MY_PID) {
7435            return PackageManager.PERMISSION_GRANTED;
7436        }
7437        return ActivityManager.checkComponentPermission(permission, uid,
7438                owningUid, exported);
7439    }
7440
7441    /**
7442     * As the only public entry point for permissions checking, this method
7443     * can enforce the semantic that requesting a check on a null global
7444     * permission is automatically denied.  (Internally a null permission
7445     * string is used when calling {@link #checkComponentPermission} in cases
7446     * when only uid-based security is needed.)
7447     *
7448     * This can be called with or without the global lock held.
7449     */
7450    @Override
7451    public int checkPermission(String permission, int pid, int uid) {
7452        if (permission == null) {
7453            return PackageManager.PERMISSION_DENIED;
7454        }
7455        return checkComponentPermission(permission, pid, uid, -1, true);
7456    }
7457
7458    @Override
7459    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7460        if (permission == null) {
7461            return PackageManager.PERMISSION_DENIED;
7462        }
7463
7464        // We might be performing an operation on behalf of an indirect binder
7465        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7466        // client identity accordingly before proceeding.
7467        Identity tlsIdentity = sCallerIdentity.get();
7468        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7469            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7470                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7471            uid = tlsIdentity.uid;
7472            pid = tlsIdentity.pid;
7473        }
7474
7475        return checkComponentPermission(permission, pid, uid, -1, true);
7476    }
7477
7478    /**
7479     * Binder IPC calls go through the public entry point.
7480     * This can be called with or without the global lock held.
7481     */
7482    int checkCallingPermission(String permission) {
7483        return checkPermission(permission,
7484                Binder.getCallingPid(),
7485                UserHandle.getAppId(Binder.getCallingUid()));
7486    }
7487
7488    /**
7489     * This can be called with or without the global lock held.
7490     */
7491    void enforceCallingPermission(String permission, String func) {
7492        if (checkCallingPermission(permission)
7493                == PackageManager.PERMISSION_GRANTED) {
7494            return;
7495        }
7496
7497        String msg = "Permission Denial: " + func + " from pid="
7498                + Binder.getCallingPid()
7499                + ", uid=" + Binder.getCallingUid()
7500                + " requires " + permission;
7501        Slog.w(TAG, msg);
7502        throw new SecurityException(msg);
7503    }
7504
7505    /**
7506     * Determine if UID is holding permissions required to access {@link Uri} in
7507     * the given {@link ProviderInfo}. Final permission checking is always done
7508     * in {@link ContentProvider}.
7509     */
7510    private final boolean checkHoldingPermissionsLocked(
7511            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7512        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7513                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7514        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7515            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7516                    != PERMISSION_GRANTED) {
7517                return false;
7518            }
7519        }
7520        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7521    }
7522
7523    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7524            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7525        if (pi.applicationInfo.uid == uid) {
7526            return true;
7527        } else if (!pi.exported) {
7528            return false;
7529        }
7530
7531        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7532        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7533        try {
7534            // check if target holds top-level <provider> permissions
7535            if (!readMet && pi.readPermission != null && considerUidPermissions
7536                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7537                readMet = true;
7538            }
7539            if (!writeMet && pi.writePermission != null && considerUidPermissions
7540                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7541                writeMet = true;
7542            }
7543
7544            // track if unprotected read/write is allowed; any denied
7545            // <path-permission> below removes this ability
7546            boolean allowDefaultRead = pi.readPermission == null;
7547            boolean allowDefaultWrite = pi.writePermission == null;
7548
7549            // check if target holds any <path-permission> that match uri
7550            final PathPermission[] pps = pi.pathPermissions;
7551            if (pps != null) {
7552                final String path = grantUri.uri.getPath();
7553                int i = pps.length;
7554                while (i > 0 && (!readMet || !writeMet)) {
7555                    i--;
7556                    PathPermission pp = pps[i];
7557                    if (pp.match(path)) {
7558                        if (!readMet) {
7559                            final String pprperm = pp.getReadPermission();
7560                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7561                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7562                                    + ": match=" + pp.match(path)
7563                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7564                            if (pprperm != null) {
7565                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7566                                        == PERMISSION_GRANTED) {
7567                                    readMet = true;
7568                                } else {
7569                                    allowDefaultRead = false;
7570                                }
7571                            }
7572                        }
7573                        if (!writeMet) {
7574                            final String ppwperm = pp.getWritePermission();
7575                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7576                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7577                                    + ": match=" + pp.match(path)
7578                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7579                            if (ppwperm != null) {
7580                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7581                                        == PERMISSION_GRANTED) {
7582                                    writeMet = true;
7583                                } else {
7584                                    allowDefaultWrite = false;
7585                                }
7586                            }
7587                        }
7588                    }
7589                }
7590            }
7591
7592            // grant unprotected <provider> read/write, if not blocked by
7593            // <path-permission> above
7594            if (allowDefaultRead) readMet = true;
7595            if (allowDefaultWrite) writeMet = true;
7596
7597        } catch (RemoteException e) {
7598            return false;
7599        }
7600
7601        return readMet && writeMet;
7602    }
7603
7604    public int getAppStartMode(int uid, String packageName) {
7605        synchronized (this) {
7606            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7607        }
7608    }
7609
7610    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7611            boolean allowWhenForeground) {
7612        UidRecord uidRec = mActiveUids.get(uid);
7613        if (!mLenientBackgroundCheck) {
7614            if (!allowWhenForeground || uidRec == null
7615                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7616                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7617                        packageName) != AppOpsManager.MODE_ALLOWED) {
7618                    return ActivityManager.APP_START_MODE_DELAYED;
7619                }
7620            }
7621
7622        } else if (uidRec == null || uidRec.idle) {
7623            if (callingPid >= 0) {
7624                ProcessRecord proc;
7625                synchronized (mPidsSelfLocked) {
7626                    proc = mPidsSelfLocked.get(callingPid);
7627                }
7628                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7629                    // Whoever is instigating this is in the foreground, so we will allow it
7630                    // to go through.
7631                    return ActivityManager.APP_START_MODE_NORMAL;
7632                }
7633            }
7634            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7635                    != AppOpsManager.MODE_ALLOWED) {
7636                return ActivityManager.APP_START_MODE_DELAYED;
7637            }
7638        }
7639        return ActivityManager.APP_START_MODE_NORMAL;
7640    }
7641
7642    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7643        ProviderInfo pi = null;
7644        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7645        if (cpr != null) {
7646            pi = cpr.info;
7647        } else {
7648            try {
7649                pi = AppGlobals.getPackageManager().resolveContentProvider(
7650                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7651            } catch (RemoteException ex) {
7652            }
7653        }
7654        return pi;
7655    }
7656
7657    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7658        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7659        if (targetUris != null) {
7660            return targetUris.get(grantUri);
7661        }
7662        return null;
7663    }
7664
7665    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7666            String targetPkg, int targetUid, GrantUri grantUri) {
7667        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7668        if (targetUris == null) {
7669            targetUris = Maps.newArrayMap();
7670            mGrantedUriPermissions.put(targetUid, targetUris);
7671        }
7672
7673        UriPermission perm = targetUris.get(grantUri);
7674        if (perm == null) {
7675            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7676            targetUris.put(grantUri, perm);
7677        }
7678
7679        return perm;
7680    }
7681
7682    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7683            final int modeFlags) {
7684        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7685        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7686                : UriPermission.STRENGTH_OWNED;
7687
7688        // Root gets to do everything.
7689        if (uid == 0) {
7690            return true;
7691        }
7692
7693        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7694        if (perms == null) return false;
7695
7696        // First look for exact match
7697        final UriPermission exactPerm = perms.get(grantUri);
7698        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7699            return true;
7700        }
7701
7702        // No exact match, look for prefixes
7703        final int N = perms.size();
7704        for (int i = 0; i < N; i++) {
7705            final UriPermission perm = perms.valueAt(i);
7706            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7707                    && perm.getStrength(modeFlags) >= minStrength) {
7708                return true;
7709            }
7710        }
7711
7712        return false;
7713    }
7714
7715    /**
7716     * @param uri This uri must NOT contain an embedded userId.
7717     * @param userId The userId in which the uri is to be resolved.
7718     */
7719    @Override
7720    public int checkUriPermission(Uri uri, int pid, int uid,
7721            final int modeFlags, int userId, IBinder callerToken) {
7722        enforceNotIsolatedCaller("checkUriPermission");
7723
7724        // Another redirected-binder-call permissions check as in
7725        // {@link checkPermissionWithToken}.
7726        Identity tlsIdentity = sCallerIdentity.get();
7727        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7728            uid = tlsIdentity.uid;
7729            pid = tlsIdentity.pid;
7730        }
7731
7732        // Our own process gets to do everything.
7733        if (pid == MY_PID) {
7734            return PackageManager.PERMISSION_GRANTED;
7735        }
7736        synchronized (this) {
7737            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7738                    ? PackageManager.PERMISSION_GRANTED
7739                    : PackageManager.PERMISSION_DENIED;
7740        }
7741    }
7742
7743    /**
7744     * Check if the targetPkg can be granted permission to access uri by
7745     * the callingUid using the given modeFlags.  Throws a security exception
7746     * if callingUid is not allowed to do this.  Returns the uid of the target
7747     * if the URI permission grant should be performed; returns -1 if it is not
7748     * needed (for example targetPkg already has permission to access the URI).
7749     * If you already know the uid of the target, you can supply it in
7750     * lastTargetUid else set that to -1.
7751     */
7752    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7753            final int modeFlags, int lastTargetUid) {
7754        if (!Intent.isAccessUriMode(modeFlags)) {
7755            return -1;
7756        }
7757
7758        if (targetPkg != null) {
7759            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7760                    "Checking grant " + targetPkg + " permission to " + grantUri);
7761        }
7762
7763        final IPackageManager pm = AppGlobals.getPackageManager();
7764
7765        // If this is not a content: uri, we can't do anything with it.
7766        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7767            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7768                    "Can't grant URI permission for non-content URI: " + grantUri);
7769            return -1;
7770        }
7771
7772        final String authority = grantUri.uri.getAuthority();
7773        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7774        if (pi == null) {
7775            Slog.w(TAG, "No content provider found for permission check: " +
7776                    grantUri.uri.toSafeString());
7777            return -1;
7778        }
7779
7780        int targetUid = lastTargetUid;
7781        if (targetUid < 0 && targetPkg != null) {
7782            try {
7783                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7784                        UserHandle.getUserId(callingUid));
7785                if (targetUid < 0) {
7786                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7787                            "Can't grant URI permission no uid for: " + targetPkg);
7788                    return -1;
7789                }
7790            } catch (RemoteException ex) {
7791                return -1;
7792            }
7793        }
7794
7795        if (targetUid >= 0) {
7796            // First...  does the target actually need this permission?
7797            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7798                // No need to grant the target this permission.
7799                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7800                        "Target " + targetPkg + " already has full permission to " + grantUri);
7801                return -1;
7802            }
7803        } else {
7804            // First...  there is no target package, so can anyone access it?
7805            boolean allowed = pi.exported;
7806            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7807                if (pi.readPermission != null) {
7808                    allowed = false;
7809                }
7810            }
7811            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7812                if (pi.writePermission != null) {
7813                    allowed = false;
7814                }
7815            }
7816            if (allowed) {
7817                return -1;
7818            }
7819        }
7820
7821        /* There is a special cross user grant if:
7822         * - The target is on another user.
7823         * - Apps on the current user can access the uri without any uid permissions.
7824         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7825         * grant uri permissions.
7826         */
7827        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7828                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7829                modeFlags, false /*without considering the uid permissions*/);
7830
7831        // Second...  is the provider allowing granting of URI permissions?
7832        if (!specialCrossUserGrant) {
7833            if (!pi.grantUriPermissions) {
7834                throw new SecurityException("Provider " + pi.packageName
7835                        + "/" + pi.name
7836                        + " does not allow granting of Uri permissions (uri "
7837                        + grantUri + ")");
7838            }
7839            if (pi.uriPermissionPatterns != null) {
7840                final int N = pi.uriPermissionPatterns.length;
7841                boolean allowed = false;
7842                for (int i=0; i<N; i++) {
7843                    if (pi.uriPermissionPatterns[i] != null
7844                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7845                        allowed = true;
7846                        break;
7847                    }
7848                }
7849                if (!allowed) {
7850                    throw new SecurityException("Provider " + pi.packageName
7851                            + "/" + pi.name
7852                            + " does not allow granting of permission to path of Uri "
7853                            + grantUri);
7854                }
7855            }
7856        }
7857
7858        // Third...  does the caller itself have permission to access
7859        // this uri?
7860        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7861            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7862                // Require they hold a strong enough Uri permission
7863                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7864                    throw new SecurityException("Uid " + callingUid
7865                            + " does not have permission to uri " + grantUri);
7866                }
7867            }
7868        }
7869        return targetUid;
7870    }
7871
7872    /**
7873     * @param uri This uri must NOT contain an embedded userId.
7874     * @param userId The userId in which the uri is to be resolved.
7875     */
7876    @Override
7877    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7878            final int modeFlags, int userId) {
7879        enforceNotIsolatedCaller("checkGrantUriPermission");
7880        synchronized(this) {
7881            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7882                    new GrantUri(userId, uri, false), modeFlags, -1);
7883        }
7884    }
7885
7886    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7887            final int modeFlags, UriPermissionOwner owner) {
7888        if (!Intent.isAccessUriMode(modeFlags)) {
7889            return;
7890        }
7891
7892        // So here we are: the caller has the assumed permission
7893        // to the uri, and the target doesn't.  Let's now give this to
7894        // the target.
7895
7896        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7897                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7898
7899        final String authority = grantUri.uri.getAuthority();
7900        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7901        if (pi == null) {
7902            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7903            return;
7904        }
7905
7906        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7907            grantUri.prefix = true;
7908        }
7909        final UriPermission perm = findOrCreateUriPermissionLocked(
7910                pi.packageName, targetPkg, targetUid, grantUri);
7911        perm.grantModes(modeFlags, owner);
7912    }
7913
7914    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7915            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7916        if (targetPkg == null) {
7917            throw new NullPointerException("targetPkg");
7918        }
7919        int targetUid;
7920        final IPackageManager pm = AppGlobals.getPackageManager();
7921        try {
7922            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7923        } catch (RemoteException ex) {
7924            return;
7925        }
7926
7927        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7928                targetUid);
7929        if (targetUid < 0) {
7930            return;
7931        }
7932
7933        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7934                owner);
7935    }
7936
7937    static class NeededUriGrants extends ArrayList<GrantUri> {
7938        final String targetPkg;
7939        final int targetUid;
7940        final int flags;
7941
7942        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7943            this.targetPkg = targetPkg;
7944            this.targetUid = targetUid;
7945            this.flags = flags;
7946        }
7947    }
7948
7949    /**
7950     * Like checkGrantUriPermissionLocked, but takes an Intent.
7951     */
7952    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7953            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7954        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7955                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7956                + " clip=" + (intent != null ? intent.getClipData() : null)
7957                + " from " + intent + "; flags=0x"
7958                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7959
7960        if (targetPkg == null) {
7961            throw new NullPointerException("targetPkg");
7962        }
7963
7964        if (intent == null) {
7965            return null;
7966        }
7967        Uri data = intent.getData();
7968        ClipData clip = intent.getClipData();
7969        if (data == null && clip == null) {
7970            return null;
7971        }
7972        // Default userId for uris in the intent (if they don't specify it themselves)
7973        int contentUserHint = intent.getContentUserHint();
7974        if (contentUserHint == UserHandle.USER_CURRENT) {
7975            contentUserHint = UserHandle.getUserId(callingUid);
7976        }
7977        final IPackageManager pm = AppGlobals.getPackageManager();
7978        int targetUid;
7979        if (needed != null) {
7980            targetUid = needed.targetUid;
7981        } else {
7982            try {
7983                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7984                        targetUserId);
7985            } catch (RemoteException ex) {
7986                return null;
7987            }
7988            if (targetUid < 0) {
7989                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7990                        "Can't grant URI permission no uid for: " + targetPkg
7991                        + " on user " + targetUserId);
7992                return null;
7993            }
7994        }
7995        if (data != null) {
7996            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7997            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7998                    targetUid);
7999            if (targetUid > 0) {
8000                if (needed == null) {
8001                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8002                }
8003                needed.add(grantUri);
8004            }
8005        }
8006        if (clip != null) {
8007            for (int i=0; i<clip.getItemCount(); i++) {
8008                Uri uri = clip.getItemAt(i).getUri();
8009                if (uri != null) {
8010                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8011                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8012                            targetUid);
8013                    if (targetUid > 0) {
8014                        if (needed == null) {
8015                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8016                        }
8017                        needed.add(grantUri);
8018                    }
8019                } else {
8020                    Intent clipIntent = clip.getItemAt(i).getIntent();
8021                    if (clipIntent != null) {
8022                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8023                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8024                        if (newNeeded != null) {
8025                            needed = newNeeded;
8026                        }
8027                    }
8028                }
8029            }
8030        }
8031
8032        return needed;
8033    }
8034
8035    /**
8036     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8037     */
8038    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8039            UriPermissionOwner owner) {
8040        if (needed != null) {
8041            for (int i=0; i<needed.size(); i++) {
8042                GrantUri grantUri = needed.get(i);
8043                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8044                        grantUri, needed.flags, owner);
8045            }
8046        }
8047    }
8048
8049    void grantUriPermissionFromIntentLocked(int callingUid,
8050            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8051        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8052                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8053        if (needed == null) {
8054            return;
8055        }
8056
8057        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8058    }
8059
8060    /**
8061     * @param uri This uri must NOT contain an embedded userId.
8062     * @param userId The userId in which the uri is to be resolved.
8063     */
8064    @Override
8065    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8066            final int modeFlags, int userId) {
8067        enforceNotIsolatedCaller("grantUriPermission");
8068        GrantUri grantUri = new GrantUri(userId, uri, false);
8069        synchronized(this) {
8070            final ProcessRecord r = getRecordForAppLocked(caller);
8071            if (r == null) {
8072                throw new SecurityException("Unable to find app for caller "
8073                        + caller
8074                        + " when granting permission to uri " + grantUri);
8075            }
8076            if (targetPkg == null) {
8077                throw new IllegalArgumentException("null target");
8078            }
8079            if (grantUri == null) {
8080                throw new IllegalArgumentException("null uri");
8081            }
8082
8083            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8084                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8085                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8086                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8087
8088            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8089                    UserHandle.getUserId(r.uid));
8090        }
8091    }
8092
8093    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8094        if (perm.modeFlags == 0) {
8095            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8096                    perm.targetUid);
8097            if (perms != null) {
8098                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8099                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8100
8101                perms.remove(perm.uri);
8102                if (perms.isEmpty()) {
8103                    mGrantedUriPermissions.remove(perm.targetUid);
8104                }
8105            }
8106        }
8107    }
8108
8109    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8110        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8111                "Revoking all granted permissions to " + grantUri);
8112
8113        final IPackageManager pm = AppGlobals.getPackageManager();
8114        final String authority = grantUri.uri.getAuthority();
8115        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8116        if (pi == null) {
8117            Slog.w(TAG, "No content provider found for permission revoke: "
8118                    + grantUri.toSafeString());
8119            return;
8120        }
8121
8122        // Does the caller have this permission on the URI?
8123        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8124            // If they don't have direct access to the URI, then revoke any
8125            // ownerless URI permissions that have been granted to them.
8126            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8127            if (perms != null) {
8128                boolean persistChanged = false;
8129                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8130                    final UriPermission perm = it.next();
8131                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8132                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8133                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8134                                "Revoking non-owned " + perm.targetUid
8135                                + " permission to " + perm.uri);
8136                        persistChanged |= perm.revokeModes(
8137                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8138                        if (perm.modeFlags == 0) {
8139                            it.remove();
8140                        }
8141                    }
8142                }
8143                if (perms.isEmpty()) {
8144                    mGrantedUriPermissions.remove(callingUid);
8145                }
8146                if (persistChanged) {
8147                    schedulePersistUriGrants();
8148                }
8149            }
8150            return;
8151        }
8152
8153        boolean persistChanged = false;
8154
8155        // Go through all of the permissions and remove any that match.
8156        int N = mGrantedUriPermissions.size();
8157        for (int i = 0; i < N; i++) {
8158            final int targetUid = mGrantedUriPermissions.keyAt(i);
8159            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8160
8161            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8162                final UriPermission perm = it.next();
8163                if (perm.uri.sourceUserId == grantUri.sourceUserId
8164                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8165                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8166                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8167                    persistChanged |= perm.revokeModes(
8168                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8169                    if (perm.modeFlags == 0) {
8170                        it.remove();
8171                    }
8172                }
8173            }
8174
8175            if (perms.isEmpty()) {
8176                mGrantedUriPermissions.remove(targetUid);
8177                N--;
8178                i--;
8179            }
8180        }
8181
8182        if (persistChanged) {
8183            schedulePersistUriGrants();
8184        }
8185    }
8186
8187    /**
8188     * @param uri This uri must NOT contain an embedded userId.
8189     * @param userId The userId in which the uri is to be resolved.
8190     */
8191    @Override
8192    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8193            int userId) {
8194        enforceNotIsolatedCaller("revokeUriPermission");
8195        synchronized(this) {
8196            final ProcessRecord r = getRecordForAppLocked(caller);
8197            if (r == null) {
8198                throw new SecurityException("Unable to find app for caller "
8199                        + caller
8200                        + " when revoking permission to uri " + uri);
8201            }
8202            if (uri == null) {
8203                Slog.w(TAG, "revokeUriPermission: null uri");
8204                return;
8205            }
8206
8207            if (!Intent.isAccessUriMode(modeFlags)) {
8208                return;
8209            }
8210
8211            final String authority = uri.getAuthority();
8212            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8213            if (pi == null) {
8214                Slog.w(TAG, "No content provider found for permission revoke: "
8215                        + uri.toSafeString());
8216                return;
8217            }
8218
8219            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8220        }
8221    }
8222
8223    /**
8224     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8225     * given package.
8226     *
8227     * @param packageName Package name to match, or {@code null} to apply to all
8228     *            packages.
8229     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8230     *            to all users.
8231     * @param persistable If persistable grants should be removed.
8232     */
8233    private void removeUriPermissionsForPackageLocked(
8234            String packageName, int userHandle, boolean persistable) {
8235        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8236            throw new IllegalArgumentException("Must narrow by either package or user");
8237        }
8238
8239        boolean persistChanged = false;
8240
8241        int N = mGrantedUriPermissions.size();
8242        for (int i = 0; i < N; i++) {
8243            final int targetUid = mGrantedUriPermissions.keyAt(i);
8244            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8245
8246            // Only inspect grants matching user
8247            if (userHandle == UserHandle.USER_ALL
8248                    || userHandle == UserHandle.getUserId(targetUid)) {
8249                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8250                    final UriPermission perm = it.next();
8251
8252                    // Only inspect grants matching package
8253                    if (packageName == null || perm.sourcePkg.equals(packageName)
8254                            || perm.targetPkg.equals(packageName)) {
8255                        persistChanged |= perm.revokeModes(persistable
8256                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8257
8258                        // Only remove when no modes remain; any persisted grants
8259                        // will keep this alive.
8260                        if (perm.modeFlags == 0) {
8261                            it.remove();
8262                        }
8263                    }
8264                }
8265
8266                if (perms.isEmpty()) {
8267                    mGrantedUriPermissions.remove(targetUid);
8268                    N--;
8269                    i--;
8270                }
8271            }
8272        }
8273
8274        if (persistChanged) {
8275            schedulePersistUriGrants();
8276        }
8277    }
8278
8279    @Override
8280    public IBinder newUriPermissionOwner(String name) {
8281        enforceNotIsolatedCaller("newUriPermissionOwner");
8282        synchronized(this) {
8283            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8284            return owner.getExternalTokenLocked();
8285        }
8286    }
8287
8288    @Override
8289    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8290        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8291        synchronized(this) {
8292            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8293            if (r == null) {
8294                throw new IllegalArgumentException("Activity does not exist; token="
8295                        + activityToken);
8296            }
8297            return r.getUriPermissionsLocked().getExternalTokenLocked();
8298        }
8299    }
8300    /**
8301     * @param uri This uri must NOT contain an embedded userId.
8302     * @param sourceUserId The userId in which the uri is to be resolved.
8303     * @param targetUserId The userId of the app that receives the grant.
8304     */
8305    @Override
8306    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8307            final int modeFlags, int sourceUserId, int targetUserId) {
8308        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8309                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8310                "grantUriPermissionFromOwner", null);
8311        synchronized(this) {
8312            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8313            if (owner == null) {
8314                throw new IllegalArgumentException("Unknown owner: " + token);
8315            }
8316            if (fromUid != Binder.getCallingUid()) {
8317                if (Binder.getCallingUid() != Process.myUid()) {
8318                    // Only system code can grant URI permissions on behalf
8319                    // of other users.
8320                    throw new SecurityException("nice try");
8321                }
8322            }
8323            if (targetPkg == null) {
8324                throw new IllegalArgumentException("null target");
8325            }
8326            if (uri == null) {
8327                throw new IllegalArgumentException("null uri");
8328            }
8329
8330            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8331                    modeFlags, owner, targetUserId);
8332        }
8333    }
8334
8335    /**
8336     * @param uri This uri must NOT contain an embedded userId.
8337     * @param userId The userId in which the uri is to be resolved.
8338     */
8339    @Override
8340    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8341        synchronized(this) {
8342            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8343            if (owner == null) {
8344                throw new IllegalArgumentException("Unknown owner: " + token);
8345            }
8346
8347            if (uri == null) {
8348                owner.removeUriPermissionsLocked(mode);
8349            } else {
8350                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8351            }
8352        }
8353    }
8354
8355    private void schedulePersistUriGrants() {
8356        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8357            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8358                    10 * DateUtils.SECOND_IN_MILLIS);
8359        }
8360    }
8361
8362    private void writeGrantedUriPermissions() {
8363        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8364
8365        // Snapshot permissions so we can persist without lock
8366        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8367        synchronized (this) {
8368            final int size = mGrantedUriPermissions.size();
8369            for (int i = 0; i < size; i++) {
8370                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8371                for (UriPermission perm : perms.values()) {
8372                    if (perm.persistedModeFlags != 0) {
8373                        persist.add(perm.snapshot());
8374                    }
8375                }
8376            }
8377        }
8378
8379        FileOutputStream fos = null;
8380        try {
8381            fos = mGrantFile.startWrite();
8382
8383            XmlSerializer out = new FastXmlSerializer();
8384            out.setOutput(fos, StandardCharsets.UTF_8.name());
8385            out.startDocument(null, true);
8386            out.startTag(null, TAG_URI_GRANTS);
8387            for (UriPermission.Snapshot perm : persist) {
8388                out.startTag(null, TAG_URI_GRANT);
8389                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8390                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8391                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8392                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8393                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8394                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8395                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8396                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8397                out.endTag(null, TAG_URI_GRANT);
8398            }
8399            out.endTag(null, TAG_URI_GRANTS);
8400            out.endDocument();
8401
8402            mGrantFile.finishWrite(fos);
8403        } catch (IOException e) {
8404            if (fos != null) {
8405                mGrantFile.failWrite(fos);
8406            }
8407        }
8408    }
8409
8410    private void readGrantedUriPermissionsLocked() {
8411        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8412
8413        final long now = System.currentTimeMillis();
8414
8415        FileInputStream fis = null;
8416        try {
8417            fis = mGrantFile.openRead();
8418            final XmlPullParser in = Xml.newPullParser();
8419            in.setInput(fis, StandardCharsets.UTF_8.name());
8420
8421            int type;
8422            while ((type = in.next()) != END_DOCUMENT) {
8423                final String tag = in.getName();
8424                if (type == START_TAG) {
8425                    if (TAG_URI_GRANT.equals(tag)) {
8426                        final int sourceUserId;
8427                        final int targetUserId;
8428                        final int userHandle = readIntAttribute(in,
8429                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8430                        if (userHandle != UserHandle.USER_NULL) {
8431                            // For backwards compatibility.
8432                            sourceUserId = userHandle;
8433                            targetUserId = userHandle;
8434                        } else {
8435                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8436                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8437                        }
8438                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8439                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8440                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8441                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8442                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8443                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8444
8445                        // Sanity check that provider still belongs to source package
8446                        final ProviderInfo pi = getProviderInfoLocked(
8447                                uri.getAuthority(), sourceUserId);
8448                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8449                            int targetUid = -1;
8450                            try {
8451                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8452                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8453                            } catch (RemoteException e) {
8454                            }
8455                            if (targetUid != -1) {
8456                                final UriPermission perm = findOrCreateUriPermissionLocked(
8457                                        sourcePkg, targetPkg, targetUid,
8458                                        new GrantUri(sourceUserId, uri, prefix));
8459                                perm.initPersistedModes(modeFlags, createdTime);
8460                            }
8461                        } else {
8462                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8463                                    + " but instead found " + pi);
8464                        }
8465                    }
8466                }
8467            }
8468        } catch (FileNotFoundException e) {
8469            // Missing grants is okay
8470        } catch (IOException e) {
8471            Slog.wtf(TAG, "Failed reading Uri grants", e);
8472        } catch (XmlPullParserException e) {
8473            Slog.wtf(TAG, "Failed reading Uri grants", e);
8474        } finally {
8475            IoUtils.closeQuietly(fis);
8476        }
8477    }
8478
8479    /**
8480     * @param uri This uri must NOT contain an embedded userId.
8481     * @param userId The userId in which the uri is to be resolved.
8482     */
8483    @Override
8484    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8485        enforceNotIsolatedCaller("takePersistableUriPermission");
8486
8487        Preconditions.checkFlagsArgument(modeFlags,
8488                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8489
8490        synchronized (this) {
8491            final int callingUid = Binder.getCallingUid();
8492            boolean persistChanged = false;
8493            GrantUri grantUri = new GrantUri(userId, uri, false);
8494
8495            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8496                    new GrantUri(userId, uri, false));
8497            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8498                    new GrantUri(userId, uri, true));
8499
8500            final boolean exactValid = (exactPerm != null)
8501                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8502            final boolean prefixValid = (prefixPerm != null)
8503                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8504
8505            if (!(exactValid || prefixValid)) {
8506                throw new SecurityException("No persistable permission grants found for UID "
8507                        + callingUid + " and Uri " + grantUri.toSafeString());
8508            }
8509
8510            if (exactValid) {
8511                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8512            }
8513            if (prefixValid) {
8514                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8515            }
8516
8517            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8518
8519            if (persistChanged) {
8520                schedulePersistUriGrants();
8521            }
8522        }
8523    }
8524
8525    /**
8526     * @param uri This uri must NOT contain an embedded userId.
8527     * @param userId The userId in which the uri is to be resolved.
8528     */
8529    @Override
8530    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8531        enforceNotIsolatedCaller("releasePersistableUriPermission");
8532
8533        Preconditions.checkFlagsArgument(modeFlags,
8534                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8535
8536        synchronized (this) {
8537            final int callingUid = Binder.getCallingUid();
8538            boolean persistChanged = false;
8539
8540            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8541                    new GrantUri(userId, uri, false));
8542            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8543                    new GrantUri(userId, uri, true));
8544            if (exactPerm == null && prefixPerm == null) {
8545                throw new SecurityException("No permission grants found for UID " + callingUid
8546                        + " and Uri " + uri.toSafeString());
8547            }
8548
8549            if (exactPerm != null) {
8550                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8551                removeUriPermissionIfNeededLocked(exactPerm);
8552            }
8553            if (prefixPerm != null) {
8554                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8555                removeUriPermissionIfNeededLocked(prefixPerm);
8556            }
8557
8558            if (persistChanged) {
8559                schedulePersistUriGrants();
8560            }
8561        }
8562    }
8563
8564    /**
8565     * Prune any older {@link UriPermission} for the given UID until outstanding
8566     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8567     *
8568     * @return if any mutations occured that require persisting.
8569     */
8570    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8571        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8572        if (perms == null) return false;
8573        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8574
8575        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8576        for (UriPermission perm : perms.values()) {
8577            if (perm.persistedModeFlags != 0) {
8578                persisted.add(perm);
8579            }
8580        }
8581
8582        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8583        if (trimCount <= 0) return false;
8584
8585        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8586        for (int i = 0; i < trimCount; i++) {
8587            final UriPermission perm = persisted.get(i);
8588
8589            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8590                    "Trimming grant created at " + perm.persistedCreateTime);
8591
8592            perm.releasePersistableModes(~0);
8593            removeUriPermissionIfNeededLocked(perm);
8594        }
8595
8596        return true;
8597    }
8598
8599    @Override
8600    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8601            String packageName, boolean incoming) {
8602        enforceNotIsolatedCaller("getPersistedUriPermissions");
8603        Preconditions.checkNotNull(packageName, "packageName");
8604
8605        final int callingUid = Binder.getCallingUid();
8606        final IPackageManager pm = AppGlobals.getPackageManager();
8607        try {
8608            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8609                    UserHandle.getUserId(callingUid));
8610            if (packageUid != callingUid) {
8611                throw new SecurityException(
8612                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8613            }
8614        } catch (RemoteException e) {
8615            throw new SecurityException("Failed to verify package name ownership");
8616        }
8617
8618        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8619        synchronized (this) {
8620            if (incoming) {
8621                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8622                        callingUid);
8623                if (perms == null) {
8624                    Slog.w(TAG, "No permission grants found for " + packageName);
8625                } else {
8626                    for (UriPermission perm : perms.values()) {
8627                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8628                            result.add(perm.buildPersistedPublicApiObject());
8629                        }
8630                    }
8631                }
8632            } else {
8633                final int size = mGrantedUriPermissions.size();
8634                for (int i = 0; i < size; i++) {
8635                    final ArrayMap<GrantUri, UriPermission> perms =
8636                            mGrantedUriPermissions.valueAt(i);
8637                    for (UriPermission perm : perms.values()) {
8638                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8639                            result.add(perm.buildPersistedPublicApiObject());
8640                        }
8641                    }
8642                }
8643            }
8644        }
8645        return new ParceledListSlice<android.content.UriPermission>(result);
8646    }
8647
8648    @Override
8649    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8650            String packageName, int userId) {
8651        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8652                "getGrantedUriPermissions");
8653
8654        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8655        synchronized (this) {
8656            final int size = mGrantedUriPermissions.size();
8657            for (int i = 0; i < size; i++) {
8658                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8659                for (UriPermission perm : perms.values()) {
8660                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8661                            && perm.persistedModeFlags != 0) {
8662                        result.add(perm.buildPersistedPublicApiObject());
8663                    }
8664                }
8665            }
8666        }
8667        return new ParceledListSlice<android.content.UriPermission>(result);
8668    }
8669
8670    @Override
8671    public void clearGrantedUriPermissions(String packageName, int userId) {
8672        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8673                "clearGrantedUriPermissions");
8674        removeUriPermissionsForPackageLocked(packageName, userId, true);
8675    }
8676
8677    @Override
8678    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8679        synchronized (this) {
8680            ProcessRecord app =
8681                who != null ? getRecordForAppLocked(who) : null;
8682            if (app == null) return;
8683
8684            Message msg = Message.obtain();
8685            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8686            msg.obj = app;
8687            msg.arg1 = waiting ? 1 : 0;
8688            mUiHandler.sendMessage(msg);
8689        }
8690    }
8691
8692    @Override
8693    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8694        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8695        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8696        outInfo.availMem = Process.getFreeMemory();
8697        outInfo.totalMem = Process.getTotalMemory();
8698        outInfo.threshold = homeAppMem;
8699        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8700        outInfo.hiddenAppThreshold = cachedAppMem;
8701        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8702                ProcessList.SERVICE_ADJ);
8703        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8704                ProcessList.VISIBLE_APP_ADJ);
8705        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8706                ProcessList.FOREGROUND_APP_ADJ);
8707    }
8708
8709    // =========================================================
8710    // TASK MANAGEMENT
8711    // =========================================================
8712
8713    @Override
8714    public List<IAppTask> getAppTasks(String callingPackage) {
8715        int callingUid = Binder.getCallingUid();
8716        long ident = Binder.clearCallingIdentity();
8717
8718        synchronized(this) {
8719            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8720            try {
8721                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8722
8723                final int N = mRecentTasks.size();
8724                for (int i = 0; i < N; i++) {
8725                    TaskRecord tr = mRecentTasks.get(i);
8726                    // Skip tasks that do not match the caller.  We don't need to verify
8727                    // callingPackage, because we are also limiting to callingUid and know
8728                    // that will limit to the correct security sandbox.
8729                    if (tr.effectiveUid != callingUid) {
8730                        continue;
8731                    }
8732                    Intent intent = tr.getBaseIntent();
8733                    if (intent == null ||
8734                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8735                        continue;
8736                    }
8737                    ActivityManager.RecentTaskInfo taskInfo =
8738                            createRecentTaskInfoFromTaskRecord(tr);
8739                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8740                    list.add(taskImpl);
8741                }
8742            } finally {
8743                Binder.restoreCallingIdentity(ident);
8744            }
8745            return list;
8746        }
8747    }
8748
8749    @Override
8750    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8751        final int callingUid = Binder.getCallingUid();
8752        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8753
8754        synchronized(this) {
8755            if (DEBUG_ALL) Slog.v(
8756                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8757
8758            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8759                    callingUid);
8760
8761            // TODO: Improve with MRU list from all ActivityStacks.
8762            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8763        }
8764
8765        return list;
8766    }
8767
8768    /**
8769     * Creates a new RecentTaskInfo from a TaskRecord.
8770     */
8771    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8772        // Update the task description to reflect any changes in the task stack
8773        tr.updateTaskDescription();
8774
8775        // Compose the recent task info
8776        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8777        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8778        rti.persistentId = tr.taskId;
8779        rti.baseIntent = new Intent(tr.getBaseIntent());
8780        rti.origActivity = tr.origActivity;
8781        rti.realActivity = tr.realActivity;
8782        rti.description = tr.lastDescription;
8783        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8784        rti.userId = tr.userId;
8785        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8786        rti.firstActiveTime = tr.firstActiveTime;
8787        rti.lastActiveTime = tr.lastActiveTime;
8788        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8789        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8790        rti.numActivities = 0;
8791        if (tr.mBounds != null) {
8792            rti.bounds = new Rect(tr.mBounds);
8793        }
8794        rti.isDockable = tr.canGoInDockedStack();
8795
8796        ActivityRecord base = null;
8797        ActivityRecord top = null;
8798        ActivityRecord tmp;
8799
8800        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8801            tmp = tr.mActivities.get(i);
8802            if (tmp.finishing) {
8803                continue;
8804            }
8805            base = tmp;
8806            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8807                top = base;
8808            }
8809            rti.numActivities++;
8810        }
8811
8812        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8813        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8814
8815        return rti;
8816    }
8817
8818    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8819        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8820                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8821        if (!allowed) {
8822            if (checkPermission(android.Manifest.permission.GET_TASKS,
8823                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8824                // Temporary compatibility: some existing apps on the system image may
8825                // still be requesting the old permission and not switched to the new
8826                // one; if so, we'll still allow them full access.  This means we need
8827                // to see if they are holding the old permission and are a system app.
8828                try {
8829                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8830                        allowed = true;
8831                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8832                                + " is using old GET_TASKS but privileged; allowing");
8833                    }
8834                } catch (RemoteException e) {
8835                }
8836            }
8837        }
8838        if (!allowed) {
8839            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8840                    + " does not hold REAL_GET_TASKS; limiting output");
8841        }
8842        return allowed;
8843    }
8844
8845    @Override
8846    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8847        final int callingUid = Binder.getCallingUid();
8848        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8849                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8850
8851        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8852        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8853        synchronized (this) {
8854            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8855                    callingUid);
8856            final boolean detailed = checkCallingPermission(
8857                    android.Manifest.permission.GET_DETAILED_TASKS)
8858                    == PackageManager.PERMISSION_GRANTED;
8859
8860            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8861                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8862                return Collections.emptyList();
8863            }
8864            mRecentTasks.loadUserRecentsLocked(userId);
8865
8866            final int recentsCount = mRecentTasks.size();
8867            ArrayList<ActivityManager.RecentTaskInfo> res =
8868                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8869
8870            final Set<Integer> includedUsers;
8871            if (includeProfiles) {
8872                includedUsers = mUserController.getProfileIds(userId);
8873            } else {
8874                includedUsers = new HashSet<>();
8875            }
8876            includedUsers.add(Integer.valueOf(userId));
8877
8878            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8879                TaskRecord tr = mRecentTasks.get(i);
8880                // Only add calling user or related users recent tasks
8881                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8882                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8883                    continue;
8884                }
8885
8886                if (tr.realActivitySuspended) {
8887                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8888                    continue;
8889                }
8890
8891                // Return the entry if desired by the caller.  We always return
8892                // the first entry, because callers always expect this to be the
8893                // foreground app.  We may filter others if the caller has
8894                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8895                // we should exclude the entry.
8896
8897                if (i == 0
8898                        || withExcluded
8899                        || (tr.intent == null)
8900                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8901                                == 0)) {
8902                    if (!allowed) {
8903                        // If the caller doesn't have the GET_TASKS permission, then only
8904                        // allow them to see a small subset of tasks -- their own and home.
8905                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8906                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8907                            continue;
8908                        }
8909                    }
8910                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8911                        if (tr.stack != null && tr.stack.isHomeStack()) {
8912                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8913                                    "Skipping, home stack task: " + tr);
8914                            continue;
8915                        }
8916                    }
8917                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8918                        final ActivityStack stack = tr.stack;
8919                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8920                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8921                                    "Skipping, top task in docked stack: " + tr);
8922                            continue;
8923                        }
8924                    }
8925                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8926                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8927                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8928                                    "Skipping, pinned stack task: " + tr);
8929                            continue;
8930                        }
8931                    }
8932                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8933                        // Don't include auto remove tasks that are finished or finishing.
8934                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8935                                "Skipping, auto-remove without activity: " + tr);
8936                        continue;
8937                    }
8938                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8939                            && !tr.isAvailable) {
8940                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8941                                "Skipping, unavail real act: " + tr);
8942                        continue;
8943                    }
8944
8945                    if (!tr.mUserSetupComplete) {
8946                        // Don't include task launched while user is not done setting-up.
8947                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8948                                "Skipping, user setup not complete: " + tr);
8949                        continue;
8950                    }
8951
8952                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8953                    if (!detailed) {
8954                        rti.baseIntent.replaceExtras((Bundle)null);
8955                    }
8956
8957                    res.add(rti);
8958                    maxNum--;
8959                }
8960            }
8961            return res;
8962        }
8963    }
8964
8965    @Override
8966    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8967        synchronized (this) {
8968            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8969                    "getTaskThumbnail()");
8970            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8971                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8972            if (tr != null) {
8973                return tr.getTaskThumbnailLocked();
8974            }
8975        }
8976        return null;
8977    }
8978
8979    @Override
8980    public int addAppTask(IBinder activityToken, Intent intent,
8981            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8982        final int callingUid = Binder.getCallingUid();
8983        final long callingIdent = Binder.clearCallingIdentity();
8984
8985        try {
8986            synchronized (this) {
8987                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8988                if (r == null) {
8989                    throw new IllegalArgumentException("Activity does not exist; token="
8990                            + activityToken);
8991                }
8992                ComponentName comp = intent.getComponent();
8993                if (comp == null) {
8994                    throw new IllegalArgumentException("Intent " + intent
8995                            + " must specify explicit component");
8996                }
8997                if (thumbnail.getWidth() != mThumbnailWidth
8998                        || thumbnail.getHeight() != mThumbnailHeight) {
8999                    throw new IllegalArgumentException("Bad thumbnail size: got "
9000                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9001                            + mThumbnailWidth + "x" + mThumbnailHeight);
9002                }
9003                if (intent.getSelector() != null) {
9004                    intent.setSelector(null);
9005                }
9006                if (intent.getSourceBounds() != null) {
9007                    intent.setSourceBounds(null);
9008                }
9009                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9010                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9011                        // The caller has added this as an auto-remove task...  that makes no
9012                        // sense, so turn off auto-remove.
9013                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9014                    }
9015                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9016                    // Must be a new task.
9017                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9018                }
9019                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9020                    mLastAddedTaskActivity = null;
9021                }
9022                ActivityInfo ainfo = mLastAddedTaskActivity;
9023                if (ainfo == null) {
9024                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9025                            comp, 0, UserHandle.getUserId(callingUid));
9026                    if (ainfo.applicationInfo.uid != callingUid) {
9027                        throw new SecurityException(
9028                                "Can't add task for another application: target uid="
9029                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9030                    }
9031                }
9032
9033                // Use the full screen as the context for the task thumbnail
9034                final Point displaySize = new Point();
9035                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9036                r.task.stack.getDisplaySize(displaySize);
9037                thumbnailInfo.taskWidth = displaySize.x;
9038                thumbnailInfo.taskHeight = displaySize.y;
9039                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9040
9041                TaskRecord task = new TaskRecord(this,
9042                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9043                        ainfo, intent, description, thumbnailInfo);
9044
9045                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9046                if (trimIdx >= 0) {
9047                    // If this would have caused a trim, then we'll abort because that
9048                    // means it would be added at the end of the list but then just removed.
9049                    return INVALID_TASK_ID;
9050                }
9051
9052                final int N = mRecentTasks.size();
9053                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9054                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9055                    tr.removedFromRecents();
9056                }
9057
9058                task.inRecents = true;
9059                mRecentTasks.add(task);
9060                r.task.stack.addTask(task, false, "addAppTask");
9061
9062                task.setLastThumbnailLocked(thumbnail);
9063                task.freeLastThumbnail();
9064
9065                return task.taskId;
9066            }
9067        } finally {
9068            Binder.restoreCallingIdentity(callingIdent);
9069        }
9070    }
9071
9072    @Override
9073    public Point getAppTaskThumbnailSize() {
9074        synchronized (this) {
9075            return new Point(mThumbnailWidth,  mThumbnailHeight);
9076        }
9077    }
9078
9079    @Override
9080    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9081        synchronized (this) {
9082            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9083            if (r != null) {
9084                r.setTaskDescription(td);
9085                r.task.updateTaskDescription();
9086            }
9087        }
9088    }
9089
9090    @Override
9091    public void setTaskResizeable(int taskId, int resizeableMode) {
9092        synchronized (this) {
9093            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9094                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9095            if (task == null) {
9096                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9097                return;
9098            }
9099            if (task.mResizeMode != resizeableMode) {
9100                task.mResizeMode = resizeableMode;
9101                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9102                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9103                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9104            }
9105        }
9106    }
9107
9108    @Override
9109    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9110        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9111        long ident = Binder.clearCallingIdentity();
9112        try {
9113            synchronized (this) {
9114                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9115                if (task == null) {
9116                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9117                    return;
9118                }
9119                int stackId = task.stack.mStackId;
9120                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9121                // in crop windows resize mode or if the task size is affected by the docked stack
9122                // changing size. No need to update configuration.
9123                if (bounds != null && task.inCropWindowsResizeMode()
9124                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9125                    mWindowManager.scrollTask(task.taskId, bounds);
9126                    return;
9127                }
9128
9129                // Place the task in the right stack if it isn't there already based on
9130                // the requested bounds.
9131                // The stack transition logic is:
9132                // - a null bounds on a freeform task moves that task to fullscreen
9133                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9134                //   that task to freeform
9135                // - otherwise the task is not moved
9136                if (!StackId.isTaskResizeAllowed(stackId)) {
9137                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9138                }
9139                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9140                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9141                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9142                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9143                }
9144                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9145                if (stackId != task.stack.mStackId) {
9146                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9147                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9148                    preserveWindow = false;
9149                }
9150
9151                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9152                        false /* deferResume */);
9153            }
9154        } finally {
9155            Binder.restoreCallingIdentity(ident);
9156        }
9157    }
9158
9159    @Override
9160    public Rect getTaskBounds(int taskId) {
9161        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9162        long ident = Binder.clearCallingIdentity();
9163        Rect rect = new Rect();
9164        try {
9165            synchronized (this) {
9166                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9167                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9168                if (task == null) {
9169                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9170                    return rect;
9171                }
9172                if (task.stack != null) {
9173                    // Return the bounds from window manager since it will be adjusted for various
9174                    // things like the presense of a docked stack for tasks that aren't resizeable.
9175                    mWindowManager.getTaskBounds(task.taskId, rect);
9176                } else {
9177                    // Task isn't in window manager yet since it isn't associated with a stack.
9178                    // Return the persist value from activity manager
9179                    if (task.mBounds != null) {
9180                        rect.set(task.mBounds);
9181                    } else if (task.mLastNonFullscreenBounds != null) {
9182                        rect.set(task.mLastNonFullscreenBounds);
9183                    }
9184                }
9185            }
9186        } finally {
9187            Binder.restoreCallingIdentity(ident);
9188        }
9189        return rect;
9190    }
9191
9192    @Override
9193    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9194        if (userId != UserHandle.getCallingUserId()) {
9195            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9196                    "getTaskDescriptionIcon");
9197        }
9198        final File passedIconFile = new File(filePath);
9199        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9200                passedIconFile.getName());
9201        if (!legitIconFile.getPath().equals(filePath)
9202                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9203            throw new IllegalArgumentException("Bad file path: " + filePath
9204                    + " passed for userId " + userId);
9205        }
9206        return mRecentTasks.getTaskDescriptionIcon(filePath);
9207    }
9208
9209    @Override
9210    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9211            throws RemoteException {
9212        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9213                opts.getCustomInPlaceResId() == 0) {
9214            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9215                    "with valid animation");
9216        }
9217        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9218        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9219                opts.getCustomInPlaceResId());
9220        mWindowManager.executeAppTransition();
9221    }
9222
9223    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9224            boolean removeFromRecents) {
9225        if (removeFromRecents) {
9226            mRecentTasks.remove(tr);
9227            tr.removedFromRecents();
9228        }
9229        ComponentName component = tr.getBaseIntent().getComponent();
9230        if (component == null) {
9231            Slog.w(TAG, "No component for base intent of task: " + tr);
9232            return;
9233        }
9234
9235        // Find any running services associated with this app and stop if needed.
9236        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9237
9238        if (!killProcess) {
9239            return;
9240        }
9241
9242        // Determine if the process(es) for this task should be killed.
9243        final String pkg = component.getPackageName();
9244        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9245        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9246        for (int i = 0; i < pmap.size(); i++) {
9247
9248            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9249            for (int j = 0; j < uids.size(); j++) {
9250                ProcessRecord proc = uids.valueAt(j);
9251                if (proc.userId != tr.userId) {
9252                    // Don't kill process for a different user.
9253                    continue;
9254                }
9255                if (proc == mHomeProcess) {
9256                    // Don't kill the home process along with tasks from the same package.
9257                    continue;
9258                }
9259                if (!proc.pkgList.containsKey(pkg)) {
9260                    // Don't kill process that is not associated with this task.
9261                    continue;
9262                }
9263
9264                for (int k = 0; k < proc.activities.size(); k++) {
9265                    TaskRecord otherTask = proc.activities.get(k).task;
9266                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9267                        // Don't kill process(es) that has an activity in a different task that is
9268                        // also in recents.
9269                        return;
9270                    }
9271                }
9272
9273                if (proc.foregroundServices) {
9274                    // Don't kill process(es) with foreground service.
9275                    return;
9276                }
9277
9278                // Add process to kill list.
9279                procsToKill.add(proc);
9280            }
9281        }
9282
9283        // Kill the running processes.
9284        for (int i = 0; i < procsToKill.size(); i++) {
9285            ProcessRecord pr = procsToKill.get(i);
9286            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9287                    && pr.curReceiver == null) {
9288                pr.kill("remove task", true);
9289            } else {
9290                // We delay killing processes that are not in the background or running a receiver.
9291                pr.waitingToKill = "remove task";
9292            }
9293        }
9294    }
9295
9296    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9297        // Remove all tasks with activities in the specified package from the list of recent tasks
9298        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9299            TaskRecord tr = mRecentTasks.get(i);
9300            if (tr.userId != userId) continue;
9301
9302            ComponentName cn = tr.intent.getComponent();
9303            if (cn != null && cn.getPackageName().equals(packageName)) {
9304                // If the package name matches, remove the task.
9305                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9306            }
9307        }
9308    }
9309
9310    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9311            int userId) {
9312
9313        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9314            TaskRecord tr = mRecentTasks.get(i);
9315            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9316                continue;
9317            }
9318
9319            ComponentName cn = tr.intent.getComponent();
9320            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9321                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9322            if (sameComponent) {
9323                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9324            }
9325        }
9326    }
9327
9328    /**
9329     * Removes the task with the specified task id.
9330     *
9331     * @param taskId Identifier of the task to be removed.
9332     * @param killProcess Kill any process associated with the task if possible.
9333     * @param removeFromRecents Whether to also remove the task from recents.
9334     * @return Returns true if the given task was found and removed.
9335     */
9336    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9337            boolean removeFromRecents) {
9338        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9339                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9340        if (tr != null) {
9341            tr.removeTaskActivitiesLocked();
9342            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9343            if (tr.isPersistable) {
9344                notifyTaskPersisterLocked(null, true);
9345            }
9346            return true;
9347        }
9348        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9349        return false;
9350    }
9351
9352    @Override
9353    public void removeStack(int stackId) {
9354        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9355        if (stackId == HOME_STACK_ID) {
9356            throw new IllegalArgumentException("Removing home stack is not allowed.");
9357        }
9358
9359        synchronized (this) {
9360            final long ident = Binder.clearCallingIdentity();
9361            try {
9362                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9363                if (stack == null) {
9364                    return;
9365                }
9366                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9367                for (int i = tasks.size() - 1; i >= 0; i--) {
9368                    removeTaskByIdLocked(
9369                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9370                }
9371            } finally {
9372                Binder.restoreCallingIdentity(ident);
9373            }
9374        }
9375    }
9376
9377    @Override
9378    public boolean removeTask(int taskId) {
9379        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9380        synchronized (this) {
9381            final long ident = Binder.clearCallingIdentity();
9382            try {
9383                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9384            } finally {
9385                Binder.restoreCallingIdentity(ident);
9386            }
9387        }
9388    }
9389
9390    /**
9391     * TODO: Add mController hook
9392     */
9393    @Override
9394    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9395        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9396
9397        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9398        synchronized(this) {
9399            moveTaskToFrontLocked(taskId, flags, bOptions);
9400        }
9401    }
9402
9403    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9404        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9405
9406        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9407                Binder.getCallingUid(), -1, -1, "Task to front")) {
9408            ActivityOptions.abort(options);
9409            return;
9410        }
9411        final long origId = Binder.clearCallingIdentity();
9412        try {
9413            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9414            if (task == null) {
9415                Slog.d(TAG, "Could not find task for id: "+ taskId);
9416                return;
9417            }
9418            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9419                mStackSupervisor.showLockTaskToast();
9420                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9421                return;
9422            }
9423            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9424            if (prev != null && prev.isRecentsActivity()) {
9425                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9426            }
9427            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9428        } finally {
9429            Binder.restoreCallingIdentity(origId);
9430        }
9431        ActivityOptions.abort(options);
9432    }
9433
9434    /**
9435     * Moves an activity, and all of the other activities within the same task, to the bottom
9436     * of the history stack.  The activity's order within the task is unchanged.
9437     *
9438     * @param token A reference to the activity we wish to move
9439     * @param nonRoot If false then this only works if the activity is the root
9440     *                of a task; if true it will work for any activity in a task.
9441     * @return Returns true if the move completed, false if not.
9442     */
9443    @Override
9444    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9445        enforceNotIsolatedCaller("moveActivityTaskToBack");
9446        synchronized(this) {
9447            final long origId = Binder.clearCallingIdentity();
9448            try {
9449                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9450                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9451                if (task != null) {
9452                    if (mStackSupervisor.isLockedTask(task)) {
9453                        mStackSupervisor.showLockTaskToast();
9454                        return false;
9455                    }
9456                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9457                }
9458            } finally {
9459                Binder.restoreCallingIdentity(origId);
9460            }
9461        }
9462        return false;
9463    }
9464
9465    @Override
9466    public void moveTaskBackwards(int task) {
9467        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9468                "moveTaskBackwards()");
9469
9470        synchronized(this) {
9471            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9472                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9473                return;
9474            }
9475            final long origId = Binder.clearCallingIdentity();
9476            moveTaskBackwardsLocked(task);
9477            Binder.restoreCallingIdentity(origId);
9478        }
9479    }
9480
9481    private final void moveTaskBackwardsLocked(int task) {
9482        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9483    }
9484
9485    @Override
9486    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9487            IActivityContainerCallback callback) throws RemoteException {
9488        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9489        synchronized (this) {
9490            if (parentActivityToken == null) {
9491                throw new IllegalArgumentException("parent token must not be null");
9492            }
9493            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9494            if (r == null) {
9495                return null;
9496            }
9497            if (callback == null) {
9498                throw new IllegalArgumentException("callback must not be null");
9499            }
9500            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9501        }
9502    }
9503
9504    @Override
9505    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9506        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9507        synchronized (this) {
9508            mStackSupervisor.deleteActivityContainer(container);
9509        }
9510    }
9511
9512    @Override
9513    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9514        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9515        synchronized (this) {
9516            final int stackId = mStackSupervisor.getNextStackId();
9517            final ActivityStack stack =
9518                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9519            if (stack == null) {
9520                return null;
9521            }
9522            return stack.mActivityContainer;
9523        }
9524    }
9525
9526    @Override
9527    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9528        synchronized (this) {
9529            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9530            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9531                return stack.mActivityContainer.getDisplayId();
9532            }
9533            return Display.DEFAULT_DISPLAY;
9534        }
9535    }
9536
9537    @Override
9538    public int getActivityStackId(IBinder token) throws RemoteException {
9539        synchronized (this) {
9540            ActivityStack stack = ActivityRecord.getStackLocked(token);
9541            if (stack == null) {
9542                return INVALID_STACK_ID;
9543            }
9544            return stack.mStackId;
9545        }
9546    }
9547
9548    @Override
9549    public void exitFreeformMode(IBinder token) throws RemoteException {
9550        synchronized (this) {
9551            long ident = Binder.clearCallingIdentity();
9552            try {
9553                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9554                if (r == null) {
9555                    throw new IllegalArgumentException(
9556                            "exitFreeformMode: No activity record matching token=" + token);
9557                }
9558                final ActivityStack stack = r.getStackLocked(token);
9559                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9560                    throw new IllegalStateException(
9561                            "exitFreeformMode: You can only go fullscreen from freeform.");
9562                }
9563                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9564                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9565                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9566            } finally {
9567                Binder.restoreCallingIdentity(ident);
9568            }
9569        }
9570    }
9571
9572    @Override
9573    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9574        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9575        if (stackId == HOME_STACK_ID) {
9576            throw new IllegalArgumentException(
9577                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9578        }
9579        synchronized (this) {
9580            long ident = Binder.clearCallingIdentity();
9581            try {
9582                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9583                        + " to stackId=" + stackId + " toTop=" + toTop);
9584                if (stackId == DOCKED_STACK_ID) {
9585                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9586                            null /* initialBounds */);
9587                }
9588                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9589                        "moveTaskToStack", ANIMATE);
9590            } finally {
9591                Binder.restoreCallingIdentity(ident);
9592            }
9593        }
9594    }
9595
9596    @Override
9597    public void swapDockedAndFullscreenStack() throws RemoteException {
9598        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9599        synchronized (this) {
9600            long ident = Binder.clearCallingIdentity();
9601            try {
9602                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9603                        FULLSCREEN_WORKSPACE_STACK_ID);
9604                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9605                        : null;
9606                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9607                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9608                        : null;
9609                if (topTask == null || tasks == null || tasks.size() == 0) {
9610                    Slog.w(TAG,
9611                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9612                    return;
9613                }
9614
9615                // TODO: App transition
9616                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9617
9618                // Defer the resume so resume/pausing while moving stacks is dangerous.
9619                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9620                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9621                        ANIMATE, true /* deferResume */);
9622                final int size = tasks.size();
9623                for (int i = 0; i < size; i++) {
9624                    final int id = tasks.get(i).taskId;
9625                    if (id == topTask.taskId) {
9626                        continue;
9627                    }
9628                    mStackSupervisor.moveTaskToStackLocked(id,
9629                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9630                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9631                }
9632
9633                // Because we deferred the resume, to avoid conflicts with stack switches while
9634                // resuming, we need to do it after all the tasks are moved.
9635                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9636                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9637
9638                mWindowManager.executeAppTransition();
9639            } finally {
9640                Binder.restoreCallingIdentity(ident);
9641            }
9642        }
9643    }
9644
9645    /**
9646     * Moves the input task to the docked stack.
9647     *
9648     * @param taskId Id of task to move.
9649     * @param createMode The mode the docked stack should be created in if it doesn't exist
9650     *                   already. See
9651     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9652     *                   and
9653     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9654     * @param toTop If the task and stack should be moved to the top.
9655     * @param animate Whether we should play an animation for the moving the task
9656     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9657     *                      docked stack. Pass {@code null} to use default bounds.
9658     */
9659    @Override
9660    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9661            Rect initialBounds) {
9662        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9663        synchronized (this) {
9664            long ident = Binder.clearCallingIdentity();
9665            try {
9666                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9667                        + " to createMode=" + createMode + " toTop=" + toTop);
9668                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9669                return mStackSupervisor.moveTaskToStackLocked(
9670                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9671                        "moveTaskToDockedStack", animate);
9672            } finally {
9673                Binder.restoreCallingIdentity(ident);
9674            }
9675        }
9676    }
9677
9678    /**
9679     * Moves the top activity in the input stackId to the pinned stack.
9680     *
9681     * @param stackId Id of stack to move the top activity to pinned stack.
9682     * @param bounds Bounds to use for pinned stack.
9683     *
9684     * @return True if the top activity of the input stack was successfully moved to the pinned
9685     *          stack.
9686     */
9687    @Override
9688    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9689        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9690        synchronized (this) {
9691            if (!mSupportsPictureInPicture) {
9692                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9693                        + "Device doesn't support picture-in-pciture mode");
9694            }
9695
9696            long ident = Binder.clearCallingIdentity();
9697            try {
9698                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9699            } finally {
9700                Binder.restoreCallingIdentity(ident);
9701            }
9702        }
9703    }
9704
9705    @Override
9706    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9707            boolean preserveWindows, boolean animate, int animationDuration) {
9708        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9709        long ident = Binder.clearCallingIdentity();
9710        try {
9711            synchronized (this) {
9712                if (animate) {
9713                    if (stackId == PINNED_STACK_ID) {
9714                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9715                    } else {
9716                        throw new IllegalArgumentException("Stack: " + stackId
9717                                + " doesn't support animated resize.");
9718                    }
9719                } else {
9720                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9721                            null /* tempTaskInsetBounds */, preserveWindows,
9722                            allowResizeInDockedMode);
9723                }
9724            }
9725        } finally {
9726            Binder.restoreCallingIdentity(ident);
9727        }
9728    }
9729
9730    @Override
9731    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9732            Rect tempDockedTaskInsetBounds,
9733            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9734        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9735                "resizeDockedStack()");
9736        long ident = Binder.clearCallingIdentity();
9737        try {
9738            synchronized (this) {
9739                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9740                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9741                        PRESERVE_WINDOWS);
9742            }
9743        } finally {
9744            Binder.restoreCallingIdentity(ident);
9745        }
9746    }
9747
9748    @Override
9749    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9750        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9751                "resizePinnedStack()");
9752        final long ident = Binder.clearCallingIdentity();
9753        try {
9754            synchronized (this) {
9755                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9756            }
9757        } finally {
9758            Binder.restoreCallingIdentity(ident);
9759        }
9760    }
9761
9762    @Override
9763    public void positionTaskInStack(int taskId, int stackId, int position) {
9764        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9765        if (stackId == HOME_STACK_ID) {
9766            throw new IllegalArgumentException(
9767                    "positionTaskInStack: Attempt to change the position of task "
9768                    + taskId + " in/to home stack");
9769        }
9770        synchronized (this) {
9771            long ident = Binder.clearCallingIdentity();
9772            try {
9773                if (DEBUG_STACK) Slog.d(TAG_STACK,
9774                        "positionTaskInStack: positioning task=" + taskId
9775                        + " in stackId=" + stackId + " at position=" + position);
9776                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9777            } finally {
9778                Binder.restoreCallingIdentity(ident);
9779            }
9780        }
9781    }
9782
9783    @Override
9784    public List<StackInfo> getAllStackInfos() {
9785        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9786        long ident = Binder.clearCallingIdentity();
9787        try {
9788            synchronized (this) {
9789                return mStackSupervisor.getAllStackInfosLocked();
9790            }
9791        } finally {
9792            Binder.restoreCallingIdentity(ident);
9793        }
9794    }
9795
9796    @Override
9797    public StackInfo getStackInfo(int stackId) {
9798        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9799        long ident = Binder.clearCallingIdentity();
9800        try {
9801            synchronized (this) {
9802                return mStackSupervisor.getStackInfoLocked(stackId);
9803            }
9804        } finally {
9805            Binder.restoreCallingIdentity(ident);
9806        }
9807    }
9808
9809    @Override
9810    public boolean isInHomeStack(int taskId) {
9811        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9812        long ident = Binder.clearCallingIdentity();
9813        try {
9814            synchronized (this) {
9815                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9816                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9817                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9818            }
9819        } finally {
9820            Binder.restoreCallingIdentity(ident);
9821        }
9822    }
9823
9824    @Override
9825    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9826        synchronized(this) {
9827            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9828        }
9829    }
9830
9831    @Override
9832    public void updateDeviceOwner(String packageName) {
9833        final int callingUid = Binder.getCallingUid();
9834        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9835            throw new SecurityException("updateDeviceOwner called from non-system process");
9836        }
9837        synchronized (this) {
9838            mDeviceOwnerName = packageName;
9839        }
9840    }
9841
9842    @Override
9843    public void updateLockTaskPackages(int userId, String[] packages) {
9844        final int callingUid = Binder.getCallingUid();
9845        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9846            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9847                    "updateLockTaskPackages()");
9848        }
9849        synchronized (this) {
9850            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9851                    Arrays.toString(packages));
9852            mLockTaskPackages.put(userId, packages);
9853            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9854        }
9855    }
9856
9857
9858    void startLockTaskModeLocked(TaskRecord task) {
9859        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9860        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9861            return;
9862        }
9863
9864        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9865        // is initiated by system after the pinning request was shown and locked mode is initiated
9866        // by an authorized app directly
9867        final int callingUid = Binder.getCallingUid();
9868        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9869        long ident = Binder.clearCallingIdentity();
9870        try {
9871            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9872            if (!isSystemInitiated) {
9873                task.mLockTaskUid = callingUid;
9874                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9875                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9876                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9877                    StatusBarManagerInternal statusBarManager =
9878                            LocalServices.getService(StatusBarManagerInternal.class);
9879                    if (statusBarManager != null) {
9880                        statusBarManager.showScreenPinningRequest();
9881                    }
9882                    return;
9883                }
9884
9885                if (stack == null || task != stack.topTask()) {
9886                    throw new IllegalArgumentException("Invalid task, not in foreground");
9887                }
9888            }
9889            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9890                    "Locking fully");
9891            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9892                    ActivityManager.LOCK_TASK_MODE_PINNED :
9893                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9894                    "startLockTask", true);
9895        } finally {
9896            Binder.restoreCallingIdentity(ident);
9897        }
9898    }
9899
9900    @Override
9901    public void startLockTaskMode(int taskId) {
9902        synchronized (this) {
9903            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9904            if (task != null) {
9905                startLockTaskModeLocked(task);
9906            }
9907        }
9908    }
9909
9910    @Override
9911    public void startLockTaskMode(IBinder token) {
9912        synchronized (this) {
9913            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9914            if (r == null) {
9915                return;
9916            }
9917            final TaskRecord task = r.task;
9918            if (task != null) {
9919                startLockTaskModeLocked(task);
9920            }
9921        }
9922    }
9923
9924    @Override
9925    public void startLockTaskModeOnCurrent() throws RemoteException {
9926        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9927        long ident = Binder.clearCallingIdentity();
9928        try {
9929            synchronized (this) {
9930                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9931                if (r != null) {
9932                    startLockTaskModeLocked(r.task);
9933                }
9934            }
9935        } finally {
9936            Binder.restoreCallingIdentity(ident);
9937        }
9938    }
9939
9940    @Override
9941    public void stopLockTaskMode() {
9942        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9943        if (lockTask == null) {
9944            // Our work here is done.
9945            return;
9946        }
9947
9948        final int callingUid = Binder.getCallingUid();
9949        final int lockTaskUid = lockTask.mLockTaskUid;
9950        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9951        // It is possible lockTaskMode was started by the system process because
9952        // android:lockTaskMode is set to a locking value in the application manifest instead of
9953        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9954        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9955        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9956                callingUid != lockTaskUid
9957                && (lockTaskUid != 0
9958                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9959            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9960                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9961        }
9962
9963        long ident = Binder.clearCallingIdentity();
9964        try {
9965            Log.d(TAG, "stopLockTaskMode");
9966            // Stop lock task
9967            synchronized (this) {
9968                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9969                        "stopLockTask", true);
9970            }
9971        } finally {
9972            Binder.restoreCallingIdentity(ident);
9973        }
9974    }
9975
9976    @Override
9977    public void stopLockTaskModeOnCurrent() throws RemoteException {
9978        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9979        long ident = Binder.clearCallingIdentity();
9980        try {
9981            stopLockTaskMode();
9982        } finally {
9983            Binder.restoreCallingIdentity(ident);
9984        }
9985    }
9986
9987    @Override
9988    public boolean isInLockTaskMode() {
9989        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9990    }
9991
9992    @Override
9993    public int getLockTaskModeState() {
9994        synchronized (this) {
9995            return mStackSupervisor.getLockTaskModeState();
9996        }
9997    }
9998
9999    @Override
10000    public void showLockTaskEscapeMessage(IBinder token) {
10001        synchronized (this) {
10002            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10003            if (r == null) {
10004                return;
10005            }
10006            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10007        }
10008    }
10009
10010    // =========================================================
10011    // CONTENT PROVIDERS
10012    // =========================================================
10013
10014    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10015        List<ProviderInfo> providers = null;
10016        try {
10017            providers = AppGlobals.getPackageManager()
10018                    .queryContentProviders(app.processName, app.uid,
10019                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10020                                    | MATCH_DEBUG_TRIAGED_MISSING)
10021                    .getList();
10022        } catch (RemoteException ex) {
10023        }
10024        if (DEBUG_MU) Slog.v(TAG_MU,
10025                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10026        int userId = app.userId;
10027        if (providers != null) {
10028            int N = providers.size();
10029            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10030            for (int i=0; i<N; i++) {
10031                ProviderInfo cpi =
10032                    (ProviderInfo)providers.get(i);
10033                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10034                        cpi.name, cpi.flags);
10035                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10036                    // This is a singleton provider, but a user besides the
10037                    // default user is asking to initialize a process it runs
10038                    // in...  well, no, it doesn't actually run in this process,
10039                    // it runs in the process of the default user.  Get rid of it.
10040                    providers.remove(i);
10041                    N--;
10042                    i--;
10043                    continue;
10044                }
10045
10046                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10047                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10048                if (cpr == null) {
10049                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10050                    mProviderMap.putProviderByClass(comp, cpr);
10051                }
10052                if (DEBUG_MU) Slog.v(TAG_MU,
10053                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10054                app.pubProviders.put(cpi.name, cpr);
10055                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10056                    // Don't add this if it is a platform component that is marked
10057                    // to run in multiple processes, because this is actually
10058                    // part of the framework so doesn't make sense to track as a
10059                    // separate apk in the process.
10060                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10061                            mProcessStats);
10062                }
10063                notifyPackageUse(cpi.applicationInfo.packageName);
10064            }
10065        }
10066        return providers;
10067    }
10068
10069    /**
10070     * Check if {@link ProcessRecord} has a possible chance at accessing the
10071     * given {@link ProviderInfo}. Final permission checking is always done
10072     * in {@link ContentProvider}.
10073     */
10074    private final String checkContentProviderPermissionLocked(
10075            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10076        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10077        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10078        boolean checkedGrants = false;
10079        if (checkUser) {
10080            // Looking for cross-user grants before enforcing the typical cross-users permissions
10081            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10082            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10083                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10084                    return null;
10085                }
10086                checkedGrants = true;
10087            }
10088            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10089                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10090            if (userId != tmpTargetUserId) {
10091                // When we actually went to determine the final targer user ID, this ended
10092                // up different than our initial check for the authority.  This is because
10093                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10094                // SELF.  So we need to re-check the grants again.
10095                checkedGrants = false;
10096            }
10097        }
10098        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10099                cpi.applicationInfo.uid, cpi.exported)
10100                == PackageManager.PERMISSION_GRANTED) {
10101            return null;
10102        }
10103        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10104                cpi.applicationInfo.uid, cpi.exported)
10105                == PackageManager.PERMISSION_GRANTED) {
10106            return null;
10107        }
10108
10109        PathPermission[] pps = cpi.pathPermissions;
10110        if (pps != null) {
10111            int i = pps.length;
10112            while (i > 0) {
10113                i--;
10114                PathPermission pp = pps[i];
10115                String pprperm = pp.getReadPermission();
10116                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10117                        cpi.applicationInfo.uid, cpi.exported)
10118                        == PackageManager.PERMISSION_GRANTED) {
10119                    return null;
10120                }
10121                String ppwperm = pp.getWritePermission();
10122                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10123                        cpi.applicationInfo.uid, cpi.exported)
10124                        == PackageManager.PERMISSION_GRANTED) {
10125                    return null;
10126                }
10127            }
10128        }
10129        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10130            return null;
10131        }
10132
10133        String msg;
10134        if (!cpi.exported) {
10135            msg = "Permission Denial: opening provider " + cpi.name
10136                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10137                    + ", uid=" + callingUid + ") that is not exported from uid "
10138                    + cpi.applicationInfo.uid;
10139        } else {
10140            msg = "Permission Denial: opening provider " + cpi.name
10141                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10142                    + ", uid=" + callingUid + ") requires "
10143                    + cpi.readPermission + " or " + cpi.writePermission;
10144        }
10145        Slog.w(TAG, msg);
10146        return msg;
10147    }
10148
10149    /**
10150     * Returns if the ContentProvider has granted a uri to callingUid
10151     */
10152    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10153        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10154        if (perms != null) {
10155            for (int i=perms.size()-1; i>=0; i--) {
10156                GrantUri grantUri = perms.keyAt(i);
10157                if (grantUri.sourceUserId == userId || !checkUser) {
10158                    if (matchesProvider(grantUri.uri, cpi)) {
10159                        return true;
10160                    }
10161                }
10162            }
10163        }
10164        return false;
10165    }
10166
10167    /**
10168     * Returns true if the uri authority is one of the authorities specified in the provider.
10169     */
10170    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10171        String uriAuth = uri.getAuthority();
10172        String cpiAuth = cpi.authority;
10173        if (cpiAuth.indexOf(';') == -1) {
10174            return cpiAuth.equals(uriAuth);
10175        }
10176        String[] cpiAuths = cpiAuth.split(";");
10177        int length = cpiAuths.length;
10178        for (int i = 0; i < length; i++) {
10179            if (cpiAuths[i].equals(uriAuth)) return true;
10180        }
10181        return false;
10182    }
10183
10184    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10185            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10186        if (r != null) {
10187            for (int i=0; i<r.conProviders.size(); i++) {
10188                ContentProviderConnection conn = r.conProviders.get(i);
10189                if (conn.provider == cpr) {
10190                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10191                            "Adding provider requested by "
10192                            + r.processName + " from process "
10193                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10194                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10195                    if (stable) {
10196                        conn.stableCount++;
10197                        conn.numStableIncs++;
10198                    } else {
10199                        conn.unstableCount++;
10200                        conn.numUnstableIncs++;
10201                    }
10202                    return conn;
10203                }
10204            }
10205            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10206            if (stable) {
10207                conn.stableCount = 1;
10208                conn.numStableIncs = 1;
10209            } else {
10210                conn.unstableCount = 1;
10211                conn.numUnstableIncs = 1;
10212            }
10213            cpr.connections.add(conn);
10214            r.conProviders.add(conn);
10215            startAssociationLocked(r.uid, r.processName, r.curProcState,
10216                    cpr.uid, cpr.name, cpr.info.processName);
10217            return conn;
10218        }
10219        cpr.addExternalProcessHandleLocked(externalProcessToken);
10220        return null;
10221    }
10222
10223    boolean decProviderCountLocked(ContentProviderConnection conn,
10224            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10225        if (conn != null) {
10226            cpr = conn.provider;
10227            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10228                    "Removing provider requested by "
10229                    + conn.client.processName + " from process "
10230                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10231                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10232            if (stable) {
10233                conn.stableCount--;
10234            } else {
10235                conn.unstableCount--;
10236            }
10237            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10238                cpr.connections.remove(conn);
10239                conn.client.conProviders.remove(conn);
10240                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10241                    // The client is more important than last activity -- note the time this
10242                    // is happening, so we keep the old provider process around a bit as last
10243                    // activity to avoid thrashing it.
10244                    if (cpr.proc != null) {
10245                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10246                    }
10247                }
10248                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10249                return true;
10250            }
10251            return false;
10252        }
10253        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10254        return false;
10255    }
10256
10257    private void checkTime(long startTime, String where) {
10258        long now = SystemClock.elapsedRealtime();
10259        if ((now-startTime) > 1000) {
10260            // If we are taking more than a second, log about it.
10261            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10262        }
10263    }
10264
10265    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10266            String name, IBinder token, boolean stable, int userId) {
10267        ContentProviderRecord cpr;
10268        ContentProviderConnection conn = null;
10269        ProviderInfo cpi = null;
10270
10271        synchronized(this) {
10272            long startTime = SystemClock.elapsedRealtime();
10273
10274            ProcessRecord r = null;
10275            if (caller != null) {
10276                r = getRecordForAppLocked(caller);
10277                if (r == null) {
10278                    throw new SecurityException(
10279                            "Unable to find app for caller " + caller
10280                          + " (pid=" + Binder.getCallingPid()
10281                          + ") when getting content provider " + name);
10282                }
10283            }
10284
10285            boolean checkCrossUser = true;
10286
10287            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10288
10289            // First check if this content provider has been published...
10290            cpr = mProviderMap.getProviderByName(name, userId);
10291            // If that didn't work, check if it exists for user 0 and then
10292            // verify that it's a singleton provider before using it.
10293            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10294                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10295                if (cpr != null) {
10296                    cpi = cpr.info;
10297                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10298                            cpi.name, cpi.flags)
10299                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10300                        userId = UserHandle.USER_SYSTEM;
10301                        checkCrossUser = false;
10302                    } else {
10303                        cpr = null;
10304                        cpi = null;
10305                    }
10306                }
10307            }
10308
10309            boolean providerRunning = cpr != null;
10310            if (providerRunning) {
10311                cpi = cpr.info;
10312                String msg;
10313                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10314                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10315                        != null) {
10316                    throw new SecurityException(msg);
10317                }
10318                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10319
10320                if (r != null && cpr.canRunHere(r)) {
10321                    // This provider has been published or is in the process
10322                    // of being published...  but it is also allowed to run
10323                    // in the caller's process, so don't make a connection
10324                    // and just let the caller instantiate its own instance.
10325                    ContentProviderHolder holder = cpr.newHolder(null);
10326                    // don't give caller the provider object, it needs
10327                    // to make its own.
10328                    holder.provider = null;
10329                    return holder;
10330                }
10331
10332                final long origId = Binder.clearCallingIdentity();
10333
10334                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10335
10336                // In this case the provider instance already exists, so we can
10337                // return it right away.
10338                conn = incProviderCountLocked(r, cpr, token, stable);
10339                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10340                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10341                        // If this is a perceptible app accessing the provider,
10342                        // make sure to count it as being accessed and thus
10343                        // back up on the LRU list.  This is good because
10344                        // content providers are often expensive to start.
10345                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10346                        updateLruProcessLocked(cpr.proc, false, null);
10347                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10348                    }
10349                }
10350
10351                if (cpr.proc != null) {
10352                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10353                    boolean success = updateOomAdjLocked(cpr.proc);
10354                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10355                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10356                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10357                    // NOTE: there is still a race here where a signal could be
10358                    // pending on the process even though we managed to update its
10359                    // adj level.  Not sure what to do about this, but at least
10360                    // the race is now smaller.
10361                    if (!success) {
10362                        // Uh oh...  it looks like the provider's process
10363                        // has been killed on us.  We need to wait for a new
10364                        // process to be started, and make sure its death
10365                        // doesn't kill our process.
10366                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10367                                + " is crashing; detaching " + r);
10368                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10369                        checkTime(startTime, "getContentProviderImpl: before appDied");
10370                        appDiedLocked(cpr.proc);
10371                        checkTime(startTime, "getContentProviderImpl: after appDied");
10372                        if (!lastRef) {
10373                            // This wasn't the last ref our process had on
10374                            // the provider...  we have now been killed, bail.
10375                            return null;
10376                        }
10377                        providerRunning = false;
10378                        conn = null;
10379                    }
10380                }
10381
10382                Binder.restoreCallingIdentity(origId);
10383            }
10384
10385            if (!providerRunning) {
10386                try {
10387                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10388                    cpi = AppGlobals.getPackageManager().
10389                        resolveContentProvider(name,
10390                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10391                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10392                } catch (RemoteException ex) {
10393                }
10394                if (cpi == null) {
10395                    return null;
10396                }
10397                // If the provider is a singleton AND
10398                // (it's a call within the same user || the provider is a
10399                // privileged app)
10400                // Then allow connecting to the singleton provider
10401                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10402                        cpi.name, cpi.flags)
10403                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10404                if (singleton) {
10405                    userId = UserHandle.USER_SYSTEM;
10406                }
10407                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10408                checkTime(startTime, "getContentProviderImpl: got app info for user");
10409
10410                String msg;
10411                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10412                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10413                        != null) {
10414                    throw new SecurityException(msg);
10415                }
10416                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10417
10418                if (!mProcessesReady
10419                        && !cpi.processName.equals("system")) {
10420                    // If this content provider does not run in the system
10421                    // process, and the system is not yet ready to run other
10422                    // processes, then fail fast instead of hanging.
10423                    throw new IllegalArgumentException(
10424                            "Attempt to launch content provider before system ready");
10425                }
10426
10427                // Make sure that the user who owns this provider is running.  If not,
10428                // we don't want to allow it to run.
10429                if (!mUserController.isUserRunningLocked(userId, 0)) {
10430                    Slog.w(TAG, "Unable to launch app "
10431                            + cpi.applicationInfo.packageName + "/"
10432                            + cpi.applicationInfo.uid + " for provider "
10433                            + name + ": user " + userId + " is stopped");
10434                    return null;
10435                }
10436
10437                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10438                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10439                cpr = mProviderMap.getProviderByClass(comp, userId);
10440                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10441                final boolean firstClass = cpr == null;
10442                if (firstClass) {
10443                    final long ident = Binder.clearCallingIdentity();
10444
10445                    // If permissions need a review before any of the app components can run,
10446                    // we return no provider and launch a review activity if the calling app
10447                    // is in the foreground.
10448                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10449                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10450                            return null;
10451                        }
10452                    }
10453
10454                    try {
10455                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10456                        ApplicationInfo ai =
10457                            AppGlobals.getPackageManager().
10458                                getApplicationInfo(
10459                                        cpi.applicationInfo.packageName,
10460                                        STOCK_PM_FLAGS, userId);
10461                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10462                        if (ai == null) {
10463                            Slog.w(TAG, "No package info for content provider "
10464                                    + cpi.name);
10465                            return null;
10466                        }
10467                        ai = getAppInfoForUser(ai, userId);
10468                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10469                    } catch (RemoteException ex) {
10470                        // pm is in same process, this will never happen.
10471                    } finally {
10472                        Binder.restoreCallingIdentity(ident);
10473                    }
10474                }
10475
10476                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10477
10478                if (r != null && cpr.canRunHere(r)) {
10479                    // If this is a multiprocess provider, then just return its
10480                    // info and allow the caller to instantiate it.  Only do
10481                    // this if the provider is the same user as the caller's
10482                    // process, or can run as root (so can be in any process).
10483                    return cpr.newHolder(null);
10484                }
10485
10486                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10487                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10488                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10489
10490                // This is single process, and our app is now connecting to it.
10491                // See if we are already in the process of launching this
10492                // provider.
10493                final int N = mLaunchingProviders.size();
10494                int i;
10495                for (i = 0; i < N; i++) {
10496                    if (mLaunchingProviders.get(i) == cpr) {
10497                        break;
10498                    }
10499                }
10500
10501                // If the provider is not already being launched, then get it
10502                // started.
10503                if (i >= N) {
10504                    final long origId = Binder.clearCallingIdentity();
10505
10506                    try {
10507                        // Content provider is now in use, its package can't be stopped.
10508                        try {
10509                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10510                            AppGlobals.getPackageManager().setPackageStoppedState(
10511                                    cpr.appInfo.packageName, false, userId);
10512                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10513                        } catch (RemoteException e) {
10514                        } catch (IllegalArgumentException e) {
10515                            Slog.w(TAG, "Failed trying to unstop package "
10516                                    + cpr.appInfo.packageName + ": " + e);
10517                        }
10518
10519                        // Use existing process if already started
10520                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10521                        ProcessRecord proc = getProcessRecordLocked(
10522                                cpi.processName, cpr.appInfo.uid, false);
10523                        if (proc != null && proc.thread != null) {
10524                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10525                                    "Installing in existing process " + proc);
10526                            if (!proc.pubProviders.containsKey(cpi.name)) {
10527                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10528                                proc.pubProviders.put(cpi.name, cpr);
10529                                try {
10530                                    proc.thread.scheduleInstallProvider(cpi);
10531                                } catch (RemoteException e) {
10532                                }
10533                            }
10534                        } else {
10535                            checkTime(startTime, "getContentProviderImpl: before start process");
10536                            proc = startProcessLocked(cpi.processName,
10537                                    cpr.appInfo, false, 0, "content provider",
10538                                    new ComponentName(cpi.applicationInfo.packageName,
10539                                            cpi.name), false, false, false);
10540                            checkTime(startTime, "getContentProviderImpl: after start process");
10541                            if (proc == null) {
10542                                Slog.w(TAG, "Unable to launch app "
10543                                        + cpi.applicationInfo.packageName + "/"
10544                                        + cpi.applicationInfo.uid + " for provider "
10545                                        + name + ": process is bad");
10546                                return null;
10547                            }
10548                        }
10549                        cpr.launchingApp = proc;
10550                        mLaunchingProviders.add(cpr);
10551                    } finally {
10552                        Binder.restoreCallingIdentity(origId);
10553                    }
10554                }
10555
10556                checkTime(startTime, "getContentProviderImpl: updating data structures");
10557
10558                // Make sure the provider is published (the same provider class
10559                // may be published under multiple names).
10560                if (firstClass) {
10561                    mProviderMap.putProviderByClass(comp, cpr);
10562                }
10563
10564                mProviderMap.putProviderByName(name, cpr);
10565                conn = incProviderCountLocked(r, cpr, token, stable);
10566                if (conn != null) {
10567                    conn.waiting = true;
10568                }
10569            }
10570            checkTime(startTime, "getContentProviderImpl: done!");
10571        }
10572
10573        // Wait for the provider to be published...
10574        synchronized (cpr) {
10575            while (cpr.provider == null) {
10576                if (cpr.launchingApp == null) {
10577                    Slog.w(TAG, "Unable to launch app "
10578                            + cpi.applicationInfo.packageName + "/"
10579                            + cpi.applicationInfo.uid + " for provider "
10580                            + name + ": launching app became null");
10581                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10582                            UserHandle.getUserId(cpi.applicationInfo.uid),
10583                            cpi.applicationInfo.packageName,
10584                            cpi.applicationInfo.uid, name);
10585                    return null;
10586                }
10587                try {
10588                    if (DEBUG_MU) Slog.v(TAG_MU,
10589                            "Waiting to start provider " + cpr
10590                            + " launchingApp=" + cpr.launchingApp);
10591                    if (conn != null) {
10592                        conn.waiting = true;
10593                    }
10594                    cpr.wait();
10595                } catch (InterruptedException ex) {
10596                } finally {
10597                    if (conn != null) {
10598                        conn.waiting = false;
10599                    }
10600                }
10601            }
10602        }
10603        return cpr != null ? cpr.newHolder(conn) : null;
10604    }
10605
10606    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10607            ProcessRecord r, final int userId) {
10608        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10609                cpi.packageName, userId)) {
10610
10611            final boolean callerForeground = r == null || r.setSchedGroup
10612                    != ProcessList.SCHED_GROUP_BACKGROUND;
10613
10614            // Show a permission review UI only for starting from a foreground app
10615            if (!callerForeground) {
10616                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10617                        + cpi.packageName + " requires a permissions review");
10618                return false;
10619            }
10620
10621            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10622            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10623                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10624            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10625
10626            if (DEBUG_PERMISSIONS_REVIEW) {
10627                Slog.i(TAG, "u" + userId + " Launching permission review "
10628                        + "for package " + cpi.packageName);
10629            }
10630
10631            final UserHandle userHandle = new UserHandle(userId);
10632            mHandler.post(new Runnable() {
10633                @Override
10634                public void run() {
10635                    mContext.startActivityAsUser(intent, userHandle);
10636                }
10637            });
10638
10639            return false;
10640        }
10641
10642        return true;
10643    }
10644
10645    PackageManagerInternal getPackageManagerInternalLocked() {
10646        if (mPackageManagerInt == null) {
10647            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10648        }
10649        return mPackageManagerInt;
10650    }
10651
10652    @Override
10653    public final ContentProviderHolder getContentProvider(
10654            IApplicationThread caller, String name, int userId, boolean stable) {
10655        enforceNotIsolatedCaller("getContentProvider");
10656        if (caller == null) {
10657            String msg = "null IApplicationThread when getting content provider "
10658                    + name;
10659            Slog.w(TAG, msg);
10660            throw new SecurityException(msg);
10661        }
10662        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10663        // with cross-user grant.
10664        return getContentProviderImpl(caller, name, null, stable, userId);
10665    }
10666
10667    public ContentProviderHolder getContentProviderExternal(
10668            String name, int userId, IBinder token) {
10669        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10670            "Do not have permission in call getContentProviderExternal()");
10671        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10672                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10673        return getContentProviderExternalUnchecked(name, token, userId);
10674    }
10675
10676    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10677            IBinder token, int userId) {
10678        return getContentProviderImpl(null, name, token, true, userId);
10679    }
10680
10681    /**
10682     * Drop a content provider from a ProcessRecord's bookkeeping
10683     */
10684    public void removeContentProvider(IBinder connection, boolean stable) {
10685        enforceNotIsolatedCaller("removeContentProvider");
10686        long ident = Binder.clearCallingIdentity();
10687        try {
10688            synchronized (this) {
10689                ContentProviderConnection conn;
10690                try {
10691                    conn = (ContentProviderConnection)connection;
10692                } catch (ClassCastException e) {
10693                    String msg ="removeContentProvider: " + connection
10694                            + " not a ContentProviderConnection";
10695                    Slog.w(TAG, msg);
10696                    throw new IllegalArgumentException(msg);
10697                }
10698                if (conn == null) {
10699                    throw new NullPointerException("connection is null");
10700                }
10701                if (decProviderCountLocked(conn, null, null, stable)) {
10702                    updateOomAdjLocked();
10703                }
10704            }
10705        } finally {
10706            Binder.restoreCallingIdentity(ident);
10707        }
10708    }
10709
10710    public void removeContentProviderExternal(String name, IBinder token) {
10711        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10712            "Do not have permission in call removeContentProviderExternal()");
10713        int userId = UserHandle.getCallingUserId();
10714        long ident = Binder.clearCallingIdentity();
10715        try {
10716            removeContentProviderExternalUnchecked(name, token, userId);
10717        } finally {
10718            Binder.restoreCallingIdentity(ident);
10719        }
10720    }
10721
10722    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10723        synchronized (this) {
10724            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10725            if(cpr == null) {
10726                //remove from mProvidersByClass
10727                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10728                return;
10729            }
10730
10731            //update content provider record entry info
10732            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10733            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10734            if (localCpr.hasExternalProcessHandles()) {
10735                if (localCpr.removeExternalProcessHandleLocked(token)) {
10736                    updateOomAdjLocked();
10737                } else {
10738                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10739                            + " with no external reference for token: "
10740                            + token + ".");
10741                }
10742            } else {
10743                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10744                        + " with no external references.");
10745            }
10746        }
10747    }
10748
10749    public final void publishContentProviders(IApplicationThread caller,
10750            List<ContentProviderHolder> providers) {
10751        if (providers == null) {
10752            return;
10753        }
10754
10755        enforceNotIsolatedCaller("publishContentProviders");
10756        synchronized (this) {
10757            final ProcessRecord r = getRecordForAppLocked(caller);
10758            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10759            if (r == null) {
10760                throw new SecurityException(
10761                        "Unable to find app for caller " + caller
10762                      + " (pid=" + Binder.getCallingPid()
10763                      + ") when publishing content providers");
10764            }
10765
10766            final long origId = Binder.clearCallingIdentity();
10767
10768            final int N = providers.size();
10769            for (int i = 0; i < N; i++) {
10770                ContentProviderHolder src = providers.get(i);
10771                if (src == null || src.info == null || src.provider == null) {
10772                    continue;
10773                }
10774                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10775                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10776                if (dst != null) {
10777                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10778                    mProviderMap.putProviderByClass(comp, dst);
10779                    String names[] = dst.info.authority.split(";");
10780                    for (int j = 0; j < names.length; j++) {
10781                        mProviderMap.putProviderByName(names[j], dst);
10782                    }
10783
10784                    int launchingCount = mLaunchingProviders.size();
10785                    int j;
10786                    boolean wasInLaunchingProviders = false;
10787                    for (j = 0; j < launchingCount; j++) {
10788                        if (mLaunchingProviders.get(j) == dst) {
10789                            mLaunchingProviders.remove(j);
10790                            wasInLaunchingProviders = true;
10791                            j--;
10792                            launchingCount--;
10793                        }
10794                    }
10795                    if (wasInLaunchingProviders) {
10796                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10797                    }
10798                    synchronized (dst) {
10799                        dst.provider = src.provider;
10800                        dst.proc = r;
10801                        dst.notifyAll();
10802                    }
10803                    updateOomAdjLocked(r);
10804                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10805                            src.info.authority);
10806                }
10807            }
10808
10809            Binder.restoreCallingIdentity(origId);
10810        }
10811    }
10812
10813    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10814        ContentProviderConnection conn;
10815        try {
10816            conn = (ContentProviderConnection)connection;
10817        } catch (ClassCastException e) {
10818            String msg ="refContentProvider: " + connection
10819                    + " not a ContentProviderConnection";
10820            Slog.w(TAG, msg);
10821            throw new IllegalArgumentException(msg);
10822        }
10823        if (conn == null) {
10824            throw new NullPointerException("connection is null");
10825        }
10826
10827        synchronized (this) {
10828            if (stable > 0) {
10829                conn.numStableIncs += stable;
10830            }
10831            stable = conn.stableCount + stable;
10832            if (stable < 0) {
10833                throw new IllegalStateException("stableCount < 0: " + stable);
10834            }
10835
10836            if (unstable > 0) {
10837                conn.numUnstableIncs += unstable;
10838            }
10839            unstable = conn.unstableCount + unstable;
10840            if (unstable < 0) {
10841                throw new IllegalStateException("unstableCount < 0: " + unstable);
10842            }
10843
10844            if ((stable+unstable) <= 0) {
10845                throw new IllegalStateException("ref counts can't go to zero here: stable="
10846                        + stable + " unstable=" + unstable);
10847            }
10848            conn.stableCount = stable;
10849            conn.unstableCount = unstable;
10850            return !conn.dead;
10851        }
10852    }
10853
10854    public void unstableProviderDied(IBinder connection) {
10855        ContentProviderConnection conn;
10856        try {
10857            conn = (ContentProviderConnection)connection;
10858        } catch (ClassCastException e) {
10859            String msg ="refContentProvider: " + connection
10860                    + " not a ContentProviderConnection";
10861            Slog.w(TAG, msg);
10862            throw new IllegalArgumentException(msg);
10863        }
10864        if (conn == null) {
10865            throw new NullPointerException("connection is null");
10866        }
10867
10868        // Safely retrieve the content provider associated with the connection.
10869        IContentProvider provider;
10870        synchronized (this) {
10871            provider = conn.provider.provider;
10872        }
10873
10874        if (provider == null) {
10875            // Um, yeah, we're way ahead of you.
10876            return;
10877        }
10878
10879        // Make sure the caller is being honest with us.
10880        if (provider.asBinder().pingBinder()) {
10881            // Er, no, still looks good to us.
10882            synchronized (this) {
10883                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10884                        + " says " + conn + " died, but we don't agree");
10885                return;
10886            }
10887        }
10888
10889        // Well look at that!  It's dead!
10890        synchronized (this) {
10891            if (conn.provider.provider != provider) {
10892                // But something changed...  good enough.
10893                return;
10894            }
10895
10896            ProcessRecord proc = conn.provider.proc;
10897            if (proc == null || proc.thread == null) {
10898                // Seems like the process is already cleaned up.
10899                return;
10900            }
10901
10902            // As far as we're concerned, this is just like receiving a
10903            // death notification...  just a bit prematurely.
10904            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10905                    + ") early provider death");
10906            final long ident = Binder.clearCallingIdentity();
10907            try {
10908                appDiedLocked(proc);
10909            } finally {
10910                Binder.restoreCallingIdentity(ident);
10911            }
10912        }
10913    }
10914
10915    @Override
10916    public void appNotRespondingViaProvider(IBinder connection) {
10917        enforceCallingPermission(
10918                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10919
10920        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10921        if (conn == null) {
10922            Slog.w(TAG, "ContentProviderConnection is null");
10923            return;
10924        }
10925
10926        final ProcessRecord host = conn.provider.proc;
10927        if (host == null) {
10928            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10929            return;
10930        }
10931
10932        mHandler.post(new Runnable() {
10933            @Override
10934            public void run() {
10935                mAppErrors.appNotResponding(host, null, null, false,
10936                        "ContentProvider not responding");
10937            }
10938        });
10939    }
10940
10941    public final void installSystemProviders() {
10942        List<ProviderInfo> providers;
10943        synchronized (this) {
10944            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10945            providers = generateApplicationProvidersLocked(app);
10946            if (providers != null) {
10947                for (int i=providers.size()-1; i>=0; i--) {
10948                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10949                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10950                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10951                                + ": not system .apk");
10952                        providers.remove(i);
10953                    }
10954                }
10955            }
10956        }
10957        if (providers != null) {
10958            mSystemThread.installSystemProviders(providers);
10959        }
10960
10961        mCoreSettingsObserver = new CoreSettingsObserver(this);
10962        mFontScaleSettingObserver = new FontScaleSettingObserver();
10963
10964        //mUsageStatsService.monitorPackages();
10965    }
10966
10967    private void startPersistentApps(int matchFlags) {
10968        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
10969
10970        synchronized (this) {
10971            try {
10972                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
10973                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
10974                for (ApplicationInfo app : apps) {
10975                    if (!"android".equals(app.packageName)) {
10976                        addAppLocked(app, false, null /* ABI override */);
10977                    }
10978                }
10979            } catch (RemoteException ex) {
10980            }
10981        }
10982    }
10983
10984    /**
10985     * When a user is unlocked, we need to install encryption-unaware providers
10986     * belonging to any running apps.
10987     */
10988    private void installEncryptionUnawareProviders(int userId) {
10989        if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
10990            // TODO: eventually pivot this back to look at current user state,
10991            // similar to the comment in UserManager.isUserUnlocked(), but for
10992            // now, if we started apps when "unlocked" then unaware providers
10993            // have already been spun up.
10994            return;
10995        }
10996
10997        // We're only interested in providers that are encryption unaware, and
10998        // we don't care about uninstalled apps, since there's no way they're
10999        // running at this point.
11000        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11001
11002        synchronized (this) {
11003            final int NP = mProcessNames.getMap().size();
11004            for (int ip = 0; ip < NP; ip++) {
11005                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11006                final int NA = apps.size();
11007                for (int ia = 0; ia < NA; ia++) {
11008                    final ProcessRecord app = apps.valueAt(ia);
11009                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11010
11011                    final int NG = app.pkgList.size();
11012                    for (int ig = 0; ig < NG; ig++) {
11013                        try {
11014                            final String pkgName = app.pkgList.keyAt(ig);
11015                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11016                                    .getPackageInfo(pkgName, matchFlags, userId);
11017                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11018                                for (ProviderInfo provInfo : pkgInfo.providers) {
11019                                    Log.v(TAG, "Installing " + provInfo);
11020                                    app.thread.scheduleInstallProvider(provInfo);
11021                                }
11022                            }
11023                        } catch (RemoteException ignored) {
11024                        }
11025                    }
11026                }
11027            }
11028        }
11029    }
11030
11031    /**
11032     * Allows apps to retrieve the MIME type of a URI.
11033     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11034     * users, then it does not need permission to access the ContentProvider.
11035     * Either, it needs cross-user uri grants.
11036     *
11037     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11038     *
11039     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11040     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11041     */
11042    public String getProviderMimeType(Uri uri, int userId) {
11043        enforceNotIsolatedCaller("getProviderMimeType");
11044        final String name = uri.getAuthority();
11045        int callingUid = Binder.getCallingUid();
11046        int callingPid = Binder.getCallingPid();
11047        long ident = 0;
11048        boolean clearedIdentity = false;
11049        synchronized (this) {
11050            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11051        }
11052        if (canClearIdentity(callingPid, callingUid, userId)) {
11053            clearedIdentity = true;
11054            ident = Binder.clearCallingIdentity();
11055        }
11056        ContentProviderHolder holder = null;
11057        try {
11058            holder = getContentProviderExternalUnchecked(name, null, userId);
11059            if (holder != null) {
11060                return holder.provider.getType(uri);
11061            }
11062        } catch (RemoteException e) {
11063            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11064            return null;
11065        } finally {
11066            // We need to clear the identity to call removeContentProviderExternalUnchecked
11067            if (!clearedIdentity) {
11068                ident = Binder.clearCallingIdentity();
11069            }
11070            try {
11071                if (holder != null) {
11072                    removeContentProviderExternalUnchecked(name, null, userId);
11073                }
11074            } finally {
11075                Binder.restoreCallingIdentity(ident);
11076            }
11077        }
11078
11079        return null;
11080    }
11081
11082    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11083        if (UserHandle.getUserId(callingUid) == userId) {
11084            return true;
11085        }
11086        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11087                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11088                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11089                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11090                return true;
11091        }
11092        return false;
11093    }
11094
11095    // =========================================================
11096    // GLOBAL MANAGEMENT
11097    // =========================================================
11098
11099    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11100            boolean isolated, int isolatedUid) {
11101        String proc = customProcess != null ? customProcess : info.processName;
11102        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11103        final int userId = UserHandle.getUserId(info.uid);
11104        int uid = info.uid;
11105        if (isolated) {
11106            if (isolatedUid == 0) {
11107                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11108                while (true) {
11109                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11110                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11111                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11112                    }
11113                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11114                    mNextIsolatedProcessUid++;
11115                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11116                        // No process for this uid, use it.
11117                        break;
11118                    }
11119                    stepsLeft--;
11120                    if (stepsLeft <= 0) {
11121                        return null;
11122                    }
11123                }
11124            } else {
11125                // Special case for startIsolatedProcess (internal only), where
11126                // the uid of the isolated process is specified by the caller.
11127                uid = isolatedUid;
11128            }
11129        }
11130        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11131        if (!mBooted && !mBooting
11132                && userId == UserHandle.USER_SYSTEM
11133                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11134            r.persistent = true;
11135        }
11136        addProcessNameLocked(r);
11137        return r;
11138    }
11139
11140    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11141            String abiOverride) {
11142        ProcessRecord app;
11143        if (!isolated) {
11144            app = getProcessRecordLocked(info.processName, info.uid, true);
11145        } else {
11146            app = null;
11147        }
11148
11149        if (app == null) {
11150            app = newProcessRecordLocked(info, null, isolated, 0);
11151            updateLruProcessLocked(app, false, null);
11152            updateOomAdjLocked();
11153        }
11154
11155        // This package really, really can not be stopped.
11156        try {
11157            AppGlobals.getPackageManager().setPackageStoppedState(
11158                    info.packageName, false, UserHandle.getUserId(app.uid));
11159        } catch (RemoteException e) {
11160        } catch (IllegalArgumentException e) {
11161            Slog.w(TAG, "Failed trying to unstop package "
11162                    + info.packageName + ": " + e);
11163        }
11164
11165        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11166            app.persistent = true;
11167            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11168        }
11169        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11170            mPersistentStartingProcesses.add(app);
11171            startProcessLocked(app, "added application", app.processName, abiOverride,
11172                    null /* entryPoint */, null /* entryPointArgs */);
11173        }
11174
11175        return app;
11176    }
11177
11178    public void unhandledBack() {
11179        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11180                "unhandledBack()");
11181
11182        synchronized(this) {
11183            final long origId = Binder.clearCallingIdentity();
11184            try {
11185                getFocusedStack().unhandledBackLocked();
11186            } finally {
11187                Binder.restoreCallingIdentity(origId);
11188            }
11189        }
11190    }
11191
11192    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11193        enforceNotIsolatedCaller("openContentUri");
11194        final int userId = UserHandle.getCallingUserId();
11195        String name = uri.getAuthority();
11196        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11197        ParcelFileDescriptor pfd = null;
11198        if (cph != null) {
11199            // We record the binder invoker's uid in thread-local storage before
11200            // going to the content provider to open the file.  Later, in the code
11201            // that handles all permissions checks, we look for this uid and use
11202            // that rather than the Activity Manager's own uid.  The effect is that
11203            // we do the check against the caller's permissions even though it looks
11204            // to the content provider like the Activity Manager itself is making
11205            // the request.
11206            Binder token = new Binder();
11207            sCallerIdentity.set(new Identity(
11208                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11209            try {
11210                pfd = cph.provider.openFile(null, uri, "r", null, token);
11211            } catch (FileNotFoundException e) {
11212                // do nothing; pfd will be returned null
11213            } finally {
11214                // Ensure that whatever happens, we clean up the identity state
11215                sCallerIdentity.remove();
11216                // Ensure we're done with the provider.
11217                removeContentProviderExternalUnchecked(name, null, userId);
11218            }
11219        } else {
11220            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11221        }
11222        return pfd;
11223    }
11224
11225    // Actually is sleeping or shutting down or whatever else in the future
11226    // is an inactive state.
11227    public boolean isSleepingOrShuttingDown() {
11228        return isSleeping() || mShuttingDown;
11229    }
11230
11231    public boolean isSleeping() {
11232        return mSleeping;
11233    }
11234
11235    void onWakefulnessChanged(int wakefulness) {
11236        synchronized(this) {
11237            mWakefulness = wakefulness;
11238            updateSleepIfNeededLocked();
11239        }
11240    }
11241
11242    void finishRunningVoiceLocked() {
11243        if (mRunningVoice != null) {
11244            mRunningVoice = null;
11245            mVoiceWakeLock.release();
11246            updateSleepIfNeededLocked();
11247        }
11248    }
11249
11250    void startTimeTrackingFocusedActivityLocked() {
11251        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11252            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11253        }
11254    }
11255
11256    void updateSleepIfNeededLocked() {
11257        if (mSleeping && !shouldSleepLocked()) {
11258            mSleeping = false;
11259            startTimeTrackingFocusedActivityLocked();
11260            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11261            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11262            updateOomAdjLocked();
11263        } else if (!mSleeping && shouldSleepLocked()) {
11264            mSleeping = true;
11265            if (mCurAppTimeTracker != null) {
11266                mCurAppTimeTracker.stop();
11267            }
11268            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11269            mStackSupervisor.goingToSleepLocked();
11270            updateOomAdjLocked();
11271
11272            // Initialize the wake times of all processes.
11273            checkExcessivePowerUsageLocked(false);
11274            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11275            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11276            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11277        }
11278    }
11279
11280    private boolean shouldSleepLocked() {
11281        // Resume applications while running a voice interactor.
11282        if (mRunningVoice != null) {
11283            return false;
11284        }
11285
11286        // TODO: Transform the lock screen state into a sleep token instead.
11287        switch (mWakefulness) {
11288            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11289            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11290            case PowerManagerInternal.WAKEFULNESS_DOZING:
11291                // Pause applications whenever the lock screen is shown or any sleep
11292                // tokens have been acquired.
11293                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11294            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11295            default:
11296                // If we're asleep then pause applications unconditionally.
11297                return true;
11298        }
11299    }
11300
11301    /** Pokes the task persister. */
11302    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11303        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11304    }
11305
11306    /** Notifies all listeners when the task stack has changed. */
11307    void notifyTaskStackChangedLocked() {
11308        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11309        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11310        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11311        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11312    }
11313
11314    /** Notifies all listeners when an Activity is pinned. */
11315    void notifyActivityPinnedLocked() {
11316        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11317        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11318    }
11319
11320    /**
11321     * Notifies all listeners when an attempt was made to start an an activity that is already
11322     * running in the pinned stack and the activity was not actually started, but the task is
11323     * either brought to the front or a new Intent is delivered to it.
11324     */
11325    void notifyPinnedActivityRestartAttemptLocked() {
11326        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11327        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11328    }
11329
11330    /** Notifies all listeners when the pinned stack animation ends. */
11331    @Override
11332    public void notifyPinnedStackAnimationEnded() {
11333        synchronized (this) {
11334            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11335            mHandler.obtainMessage(
11336                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11337        }
11338    }
11339
11340    @Override
11341    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11342        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11343    }
11344
11345    @Override
11346    public boolean shutdown(int timeout) {
11347        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11348                != PackageManager.PERMISSION_GRANTED) {
11349            throw new SecurityException("Requires permission "
11350                    + android.Manifest.permission.SHUTDOWN);
11351        }
11352
11353        boolean timedout = false;
11354
11355        synchronized(this) {
11356            mShuttingDown = true;
11357            updateEventDispatchingLocked();
11358            timedout = mStackSupervisor.shutdownLocked(timeout);
11359        }
11360
11361        mAppOpsService.shutdown();
11362        if (mUsageStatsService != null) {
11363            mUsageStatsService.prepareShutdown();
11364        }
11365        mBatteryStatsService.shutdown();
11366        synchronized (this) {
11367            mProcessStats.shutdownLocked();
11368            notifyTaskPersisterLocked(null, true);
11369        }
11370
11371        return timedout;
11372    }
11373
11374    public final void activitySlept(IBinder token) {
11375        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11376
11377        final long origId = Binder.clearCallingIdentity();
11378
11379        synchronized (this) {
11380            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11381            if (r != null) {
11382                mStackSupervisor.activitySleptLocked(r);
11383            }
11384        }
11385
11386        Binder.restoreCallingIdentity(origId);
11387    }
11388
11389    private String lockScreenShownToString() {
11390        switch (mLockScreenShown) {
11391            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11392            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11393            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11394            default: return "Unknown=" + mLockScreenShown;
11395        }
11396    }
11397
11398    void logLockScreen(String msg) {
11399        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11400                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11401                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11402                + " mSleeping=" + mSleeping);
11403    }
11404
11405    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11406        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11407        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11408        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11409            boolean wasRunningVoice = mRunningVoice != null;
11410            mRunningVoice = session;
11411            if (!wasRunningVoice) {
11412                mVoiceWakeLock.acquire();
11413                updateSleepIfNeededLocked();
11414            }
11415        }
11416    }
11417
11418    private void updateEventDispatchingLocked() {
11419        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11420    }
11421
11422    public void setLockScreenShown(boolean shown) {
11423        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11424                != PackageManager.PERMISSION_GRANTED) {
11425            throw new SecurityException("Requires permission "
11426                    + android.Manifest.permission.DEVICE_POWER);
11427        }
11428
11429        synchronized(this) {
11430            long ident = Binder.clearCallingIdentity();
11431            try {
11432                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11433                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11434                updateSleepIfNeededLocked();
11435            } finally {
11436                Binder.restoreCallingIdentity(ident);
11437            }
11438        }
11439    }
11440
11441    @Override
11442    public void notifyLockedProfile(@UserIdInt int userId) {
11443        try {
11444            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11445                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11446            }
11447        } catch (RemoteException ex) {
11448            throw new SecurityException("Fail to check is caller a privileged app", ex);
11449        }
11450
11451        synchronized (this) {
11452            if (mStackSupervisor.isFocusedUserLockedProfile()) {
11453                final long ident = Binder.clearCallingIdentity();
11454                try {
11455                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11456                    // Get the focused task before launching launcher.
11457
11458                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11459
11460                        // If there is no device lock, we will show the profile's credential page.
11461                        // startActivityFromRecentsInner is intercepted and will forward user to it.
11462                        if (mFocusedActivity != null) {
11463                            mStackSupervisor.startActivityFromRecentsInner(
11464                                    mFocusedActivity.task.taskId, null);
11465                        }
11466                    } else {
11467                        // Showing launcher to avoid user entering credential twice.
11468                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11469                    }
11470                } finally {
11471                    Binder.restoreCallingIdentity(ident);
11472                }
11473            }
11474        }
11475    }
11476
11477    @Override
11478    public void stopAppSwitches() {
11479        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11480                != PackageManager.PERMISSION_GRANTED) {
11481            throw new SecurityException("viewquires permission "
11482                    + android.Manifest.permission.STOP_APP_SWITCHES);
11483        }
11484
11485        synchronized(this) {
11486            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11487                    + APP_SWITCH_DELAY_TIME;
11488            mDidAppSwitch = false;
11489            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11490            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11491            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11492        }
11493    }
11494
11495    public void resumeAppSwitches() {
11496        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11497                != PackageManager.PERMISSION_GRANTED) {
11498            throw new SecurityException("Requires permission "
11499                    + android.Manifest.permission.STOP_APP_SWITCHES);
11500        }
11501
11502        synchronized(this) {
11503            // Note that we don't execute any pending app switches... we will
11504            // let those wait until either the timeout, or the next start
11505            // activity request.
11506            mAppSwitchesAllowedTime = 0;
11507        }
11508    }
11509
11510    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11511            int callingPid, int callingUid, String name) {
11512        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11513            return true;
11514        }
11515
11516        int perm = checkComponentPermission(
11517                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11518                sourceUid, -1, true);
11519        if (perm == PackageManager.PERMISSION_GRANTED) {
11520            return true;
11521        }
11522
11523        // If the actual IPC caller is different from the logical source, then
11524        // also see if they are allowed to control app switches.
11525        if (callingUid != -1 && callingUid != sourceUid) {
11526            perm = checkComponentPermission(
11527                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11528                    callingUid, -1, true);
11529            if (perm == PackageManager.PERMISSION_GRANTED) {
11530                return true;
11531            }
11532        }
11533
11534        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11535        return false;
11536    }
11537
11538    public void setDebugApp(String packageName, boolean waitForDebugger,
11539            boolean persistent) {
11540        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11541                "setDebugApp()");
11542
11543        long ident = Binder.clearCallingIdentity();
11544        try {
11545            // Note that this is not really thread safe if there are multiple
11546            // callers into it at the same time, but that's not a situation we
11547            // care about.
11548            if (persistent) {
11549                final ContentResolver resolver = mContext.getContentResolver();
11550                Settings.Global.putString(
11551                    resolver, Settings.Global.DEBUG_APP,
11552                    packageName);
11553                Settings.Global.putInt(
11554                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11555                    waitForDebugger ? 1 : 0);
11556            }
11557
11558            synchronized (this) {
11559                if (!persistent) {
11560                    mOrigDebugApp = mDebugApp;
11561                    mOrigWaitForDebugger = mWaitForDebugger;
11562                }
11563                mDebugApp = packageName;
11564                mWaitForDebugger = waitForDebugger;
11565                mDebugTransient = !persistent;
11566                if (packageName != null) {
11567                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11568                            false, UserHandle.USER_ALL, "set debug app");
11569                }
11570            }
11571        } finally {
11572            Binder.restoreCallingIdentity(ident);
11573        }
11574    }
11575
11576    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11577        synchronized (this) {
11578            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11579            if (!isDebuggable) {
11580                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11581                    throw new SecurityException("Process not debuggable: " + app.packageName);
11582                }
11583            }
11584
11585            mTrackAllocationApp = processName;
11586        }
11587    }
11588
11589    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11590        synchronized (this) {
11591            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11592            if (!isDebuggable) {
11593                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11594                    throw new SecurityException("Process not debuggable: " + app.packageName);
11595                }
11596            }
11597            mProfileApp = processName;
11598            mProfileFile = profilerInfo.profileFile;
11599            if (mProfileFd != null) {
11600                try {
11601                    mProfileFd.close();
11602                } catch (IOException e) {
11603                }
11604                mProfileFd = null;
11605            }
11606            mProfileFd = profilerInfo.profileFd;
11607            mSamplingInterval = profilerInfo.samplingInterval;
11608            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11609            mProfileType = 0;
11610        }
11611    }
11612
11613    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11614        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11615        if (!isDebuggable) {
11616            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11617                throw new SecurityException("Process not debuggable: " + app.packageName);
11618            }
11619        }
11620        mNativeDebuggingApp = processName;
11621    }
11622
11623    @Override
11624    public void setAlwaysFinish(boolean enabled) {
11625        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11626                "setAlwaysFinish()");
11627
11628        long ident = Binder.clearCallingIdentity();
11629        try {
11630            Settings.Global.putInt(
11631                    mContext.getContentResolver(),
11632                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11633
11634            synchronized (this) {
11635                mAlwaysFinishActivities = enabled;
11636            }
11637        } finally {
11638            Binder.restoreCallingIdentity(ident);
11639        }
11640    }
11641
11642    @Override
11643    public void setLenientBackgroundCheck(boolean enabled) {
11644        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11645                "setLenientBackgroundCheck()");
11646
11647        long ident = Binder.clearCallingIdentity();
11648        try {
11649            Settings.Global.putInt(
11650                    mContext.getContentResolver(),
11651                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11652
11653            synchronized (this) {
11654                mLenientBackgroundCheck = enabled;
11655            }
11656        } finally {
11657            Binder.restoreCallingIdentity(ident);
11658        }
11659    }
11660
11661    @Override
11662    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11663        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11664                "setActivityController()");
11665        synchronized (this) {
11666            mController = controller;
11667            mControllerIsAMonkey = imAMonkey;
11668            Watchdog.getInstance().setActivityController(controller);
11669        }
11670    }
11671
11672    @Override
11673    public void setUserIsMonkey(boolean userIsMonkey) {
11674        synchronized (this) {
11675            synchronized (mPidsSelfLocked) {
11676                final int callingPid = Binder.getCallingPid();
11677                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11678                if (precessRecord == null) {
11679                    throw new SecurityException("Unknown process: " + callingPid);
11680                }
11681                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11682                    throw new SecurityException("Only an instrumentation process "
11683                            + "with a UiAutomation can call setUserIsMonkey");
11684                }
11685            }
11686            mUserIsMonkey = userIsMonkey;
11687        }
11688    }
11689
11690    @Override
11691    public boolean isUserAMonkey() {
11692        synchronized (this) {
11693            // If there is a controller also implies the user is a monkey.
11694            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11695        }
11696    }
11697
11698    public void requestBugReport(int bugreportType) {
11699        String service = null;
11700        switch (bugreportType) {
11701            case ActivityManager.BUGREPORT_OPTION_FULL:
11702                service = "bugreport";
11703                break;
11704            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11705                service = "bugreportplus";
11706                break;
11707            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11708                service = "bugreportremote";
11709                break;
11710        }
11711        if (service == null) {
11712            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11713                    + bugreportType);
11714        }
11715        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11716        SystemProperties.set("ctl.start", service);
11717    }
11718
11719    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11720        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11721    }
11722
11723    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11724        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11725            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11726        }
11727        return KEY_DISPATCHING_TIMEOUT;
11728    }
11729
11730    @Override
11731    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11732        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11733                != PackageManager.PERMISSION_GRANTED) {
11734            throw new SecurityException("Requires permission "
11735                    + android.Manifest.permission.FILTER_EVENTS);
11736        }
11737        ProcessRecord proc;
11738        long timeout;
11739        synchronized (this) {
11740            synchronized (mPidsSelfLocked) {
11741                proc = mPidsSelfLocked.get(pid);
11742            }
11743            timeout = getInputDispatchingTimeoutLocked(proc);
11744        }
11745
11746        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11747            return -1;
11748        }
11749
11750        return timeout;
11751    }
11752
11753    /**
11754     * Handle input dispatching timeouts.
11755     * Returns whether input dispatching should be aborted or not.
11756     */
11757    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11758            final ActivityRecord activity, final ActivityRecord parent,
11759            final boolean aboveSystem, String reason) {
11760        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11761                != PackageManager.PERMISSION_GRANTED) {
11762            throw new SecurityException("Requires permission "
11763                    + android.Manifest.permission.FILTER_EVENTS);
11764        }
11765
11766        final String annotation;
11767        if (reason == null) {
11768            annotation = "Input dispatching timed out";
11769        } else {
11770            annotation = "Input dispatching timed out (" + reason + ")";
11771        }
11772
11773        if (proc != null) {
11774            synchronized (this) {
11775                if (proc.debugging) {
11776                    return false;
11777                }
11778
11779                if (mDidDexOpt) {
11780                    // Give more time since we were dexopting.
11781                    mDidDexOpt = false;
11782                    return false;
11783                }
11784
11785                if (proc.instrumentationClass != null) {
11786                    Bundle info = new Bundle();
11787                    info.putString("shortMsg", "keyDispatchingTimedOut");
11788                    info.putString("longMsg", annotation);
11789                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11790                    return true;
11791                }
11792            }
11793            mHandler.post(new Runnable() {
11794                @Override
11795                public void run() {
11796                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11797                }
11798            });
11799        }
11800
11801        return true;
11802    }
11803
11804    @Override
11805    public Bundle getAssistContextExtras(int requestType) {
11806        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11807                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11808        if (pae == null) {
11809            return null;
11810        }
11811        synchronized (pae) {
11812            while (!pae.haveResult) {
11813                try {
11814                    pae.wait();
11815                } catch (InterruptedException e) {
11816                }
11817            }
11818        }
11819        synchronized (this) {
11820            buildAssistBundleLocked(pae, pae.result);
11821            mPendingAssistExtras.remove(pae);
11822            mUiHandler.removeCallbacks(pae);
11823        }
11824        return pae.extras;
11825    }
11826
11827    @Override
11828    public boolean isAssistDataAllowedOnCurrentActivity() {
11829        int userId;
11830        synchronized (this) {
11831            userId = mUserController.getCurrentUserIdLocked();
11832            ActivityRecord activity = getFocusedStack().topActivity();
11833            if (activity == null) {
11834                return false;
11835            }
11836            userId = activity.userId;
11837        }
11838        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11839                Context.DEVICE_POLICY_SERVICE);
11840        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11841    }
11842
11843    @Override
11844    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11845        long ident = Binder.clearCallingIdentity();
11846        try {
11847            synchronized (this) {
11848                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11849                ActivityRecord top = getFocusedStack().topActivity();
11850                if (top != caller) {
11851                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11852                            + " is not current top " + top);
11853                    return false;
11854                }
11855                if (!top.nowVisible) {
11856                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11857                            + " is not visible");
11858                    return false;
11859                }
11860            }
11861            AssistUtils utils = new AssistUtils(mContext);
11862            return utils.showSessionForActiveService(args,
11863                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11864        } finally {
11865            Binder.restoreCallingIdentity(ident);
11866        }
11867    }
11868
11869    @Override
11870    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11871            IBinder activityToken) {
11872        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11873                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11874    }
11875
11876    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11877            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11878            long timeout) {
11879        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11880                "enqueueAssistContext()");
11881        synchronized (this) {
11882            ActivityRecord activity = getFocusedStack().topActivity();
11883            if (activity == null) {
11884                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11885                return null;
11886            }
11887            if (activity.app == null || activity.app.thread == null) {
11888                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11889                return null;
11890            }
11891            if (activityToken != null) {
11892                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11893                if (activity != caller) {
11894                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11895                            + " is not current top " + activity);
11896                    return null;
11897                }
11898            }
11899            PendingAssistExtras pae;
11900            Bundle extras = new Bundle();
11901            if (args != null) {
11902                extras.putAll(args);
11903            }
11904            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11905            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11906            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11907            try {
11908                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11909                        requestType);
11910                mPendingAssistExtras.add(pae);
11911                mUiHandler.postDelayed(pae, timeout);
11912            } catch (RemoteException e) {
11913                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11914                return null;
11915            }
11916            return pae;
11917        }
11918    }
11919
11920    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11921        IResultReceiver receiver;
11922        synchronized (this) {
11923            mPendingAssistExtras.remove(pae);
11924            receiver = pae.receiver;
11925        }
11926        if (receiver != null) {
11927            // Caller wants result sent back to them.
11928            try {
11929                pae.receiver.send(0, null);
11930            } catch (RemoteException e) {
11931            }
11932        }
11933    }
11934
11935    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11936        if (result != null) {
11937            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11938        }
11939        if (pae.hint != null) {
11940            pae.extras.putBoolean(pae.hint, true);
11941        }
11942    }
11943
11944    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11945            AssistContent content, Uri referrer) {
11946        PendingAssistExtras pae = (PendingAssistExtras)token;
11947        synchronized (pae) {
11948            pae.result = extras;
11949            pae.structure = structure;
11950            pae.content = content;
11951            if (referrer != null) {
11952                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11953            }
11954            pae.haveResult = true;
11955            pae.notifyAll();
11956            if (pae.intent == null && pae.receiver == null) {
11957                // Caller is just waiting for the result.
11958                return;
11959            }
11960        }
11961
11962        // We are now ready to launch the assist activity.
11963        IResultReceiver sendReceiver = null;
11964        Bundle sendBundle = null;
11965        synchronized (this) {
11966            buildAssistBundleLocked(pae, extras);
11967            boolean exists = mPendingAssistExtras.remove(pae);
11968            mUiHandler.removeCallbacks(pae);
11969            if (!exists) {
11970                // Timed out.
11971                return;
11972            }
11973            if ((sendReceiver=pae.receiver) != null) {
11974                // Caller wants result sent back to them.
11975                sendBundle = new Bundle();
11976                sendBundle.putBundle("data", pae.extras);
11977                sendBundle.putParcelable("structure", pae.structure);
11978                sendBundle.putParcelable("content", pae.content);
11979            }
11980        }
11981        if (sendReceiver != null) {
11982            try {
11983                sendReceiver.send(0, sendBundle);
11984            } catch (RemoteException e) {
11985            }
11986            return;
11987        }
11988
11989        long ident = Binder.clearCallingIdentity();
11990        try {
11991            pae.intent.replaceExtras(pae.extras);
11992            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11993                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11994                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11995            closeSystemDialogs("assist");
11996            try {
11997                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11998            } catch (ActivityNotFoundException e) {
11999                Slog.w(TAG, "No activity to handle assist action.", e);
12000            }
12001        } finally {
12002            Binder.restoreCallingIdentity(ident);
12003        }
12004    }
12005
12006    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12007            Bundle args) {
12008        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
12009                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12010    }
12011
12012    public void registerProcessObserver(IProcessObserver observer) {
12013        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12014                "registerProcessObserver()");
12015        synchronized (this) {
12016            mProcessObservers.register(observer);
12017        }
12018    }
12019
12020    @Override
12021    public void unregisterProcessObserver(IProcessObserver observer) {
12022        synchronized (this) {
12023            mProcessObservers.unregister(observer);
12024        }
12025    }
12026
12027    @Override
12028    public void registerUidObserver(IUidObserver observer, int which) {
12029        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12030                "registerUidObserver()");
12031        synchronized (this) {
12032            mUidObservers.register(observer, which);
12033        }
12034    }
12035
12036    @Override
12037    public void unregisterUidObserver(IUidObserver observer) {
12038        synchronized (this) {
12039            mUidObservers.unregister(observer);
12040        }
12041    }
12042
12043    @Override
12044    public boolean convertFromTranslucent(IBinder token) {
12045        final long origId = Binder.clearCallingIdentity();
12046        try {
12047            synchronized (this) {
12048                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12049                if (r == null) {
12050                    return false;
12051                }
12052                final boolean translucentChanged = r.changeWindowTranslucency(true);
12053                if (translucentChanged) {
12054                    r.task.stack.releaseBackgroundResources(r);
12055                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12056                }
12057                mWindowManager.setAppFullscreen(token, true);
12058                return translucentChanged;
12059            }
12060        } finally {
12061            Binder.restoreCallingIdentity(origId);
12062        }
12063    }
12064
12065    @Override
12066    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12067        final long origId = Binder.clearCallingIdentity();
12068        try {
12069            synchronized (this) {
12070                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12071                if (r == null) {
12072                    return false;
12073                }
12074                int index = r.task.mActivities.lastIndexOf(r);
12075                if (index > 0) {
12076                    ActivityRecord under = r.task.mActivities.get(index - 1);
12077                    under.returningOptions = options;
12078                }
12079                final boolean translucentChanged = r.changeWindowTranslucency(false);
12080                if (translucentChanged) {
12081                    r.task.stack.convertActivityToTranslucent(r);
12082                }
12083                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12084                mWindowManager.setAppFullscreen(token, false);
12085                return translucentChanged;
12086            }
12087        } finally {
12088            Binder.restoreCallingIdentity(origId);
12089        }
12090    }
12091
12092    @Override
12093    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12094        final long origId = Binder.clearCallingIdentity();
12095        try {
12096            synchronized (this) {
12097                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12098                if (r != null) {
12099                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12100                }
12101            }
12102            return false;
12103        } finally {
12104            Binder.restoreCallingIdentity(origId);
12105        }
12106    }
12107
12108    @Override
12109    public boolean isBackgroundVisibleBehind(IBinder token) {
12110        final long origId = Binder.clearCallingIdentity();
12111        try {
12112            synchronized (this) {
12113                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12114                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12115                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12116                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12117                return visible;
12118            }
12119        } finally {
12120            Binder.restoreCallingIdentity(origId);
12121        }
12122    }
12123
12124    @Override
12125    public ActivityOptions getActivityOptions(IBinder token) {
12126        final long origId = Binder.clearCallingIdentity();
12127        try {
12128            synchronized (this) {
12129                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12130                if (r != null) {
12131                    final ActivityOptions activityOptions = r.pendingOptions;
12132                    r.pendingOptions = null;
12133                    return activityOptions;
12134                }
12135                return null;
12136            }
12137        } finally {
12138            Binder.restoreCallingIdentity(origId);
12139        }
12140    }
12141
12142    @Override
12143    public void setImmersive(IBinder token, boolean immersive) {
12144        synchronized(this) {
12145            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12146            if (r == null) {
12147                throw new IllegalArgumentException();
12148            }
12149            r.immersive = immersive;
12150
12151            // update associated state if we're frontmost
12152            if (r == mFocusedActivity) {
12153                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12154                applyUpdateLockStateLocked(r);
12155            }
12156        }
12157    }
12158
12159    @Override
12160    public boolean isImmersive(IBinder token) {
12161        synchronized (this) {
12162            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12163            if (r == null) {
12164                throw new IllegalArgumentException();
12165            }
12166            return r.immersive;
12167        }
12168    }
12169
12170    @Override
12171    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12172        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12173            throw new UnsupportedOperationException("VR mode not supported on this device!");
12174        }
12175
12176        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12177
12178        ActivityRecord r;
12179        synchronized (this) {
12180            r = ActivityRecord.isInStackLocked(token);
12181        }
12182
12183        if (r == null) {
12184            throw new IllegalArgumentException();
12185        }
12186
12187        int err;
12188        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12189                VrManagerInternal.NO_ERROR) {
12190            return err;
12191        }
12192
12193        synchronized(this) {
12194            r.requestedVrComponent = (enabled) ? packageName : null;
12195
12196            // Update associated state if this activity is currently focused
12197            if (r == mFocusedActivity) {
12198                applyUpdateVrModeLocked(r);
12199            }
12200            return 0;
12201        }
12202    }
12203
12204    @Override
12205    public boolean isVrModePackageEnabled(ComponentName packageName) {
12206        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12207            throw new UnsupportedOperationException("VR mode not supported on this device!");
12208        }
12209
12210        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12211
12212        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12213                VrManagerInternal.NO_ERROR;
12214    }
12215
12216    public boolean isTopActivityImmersive() {
12217        enforceNotIsolatedCaller("startActivity");
12218        synchronized (this) {
12219            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12220            return (r != null) ? r.immersive : false;
12221        }
12222    }
12223
12224    @Override
12225    public boolean isTopOfTask(IBinder token) {
12226        synchronized (this) {
12227            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12228            if (r == null) {
12229                throw new IllegalArgumentException();
12230            }
12231            return r.task.getTopActivity() == r;
12232        }
12233    }
12234
12235    public final void enterSafeMode() {
12236        synchronized(this) {
12237            // It only makes sense to do this before the system is ready
12238            // and started launching other packages.
12239            if (!mSystemReady) {
12240                try {
12241                    AppGlobals.getPackageManager().enterSafeMode();
12242                } catch (RemoteException e) {
12243                }
12244            }
12245
12246            mSafeMode = true;
12247        }
12248    }
12249
12250    public final void showSafeModeOverlay() {
12251        View v = LayoutInflater.from(mContext).inflate(
12252                com.android.internal.R.layout.safe_mode, null);
12253        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12254        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12255        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12256        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12257        lp.gravity = Gravity.BOTTOM | Gravity.START;
12258        lp.format = v.getBackground().getOpacity();
12259        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12260                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12261        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12262        ((WindowManager)mContext.getSystemService(
12263                Context.WINDOW_SERVICE)).addView(v, lp);
12264    }
12265
12266    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12267        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12268            return;
12269        }
12270        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12271        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12272        synchronized (stats) {
12273            if (mBatteryStatsService.isOnBattery()) {
12274                mBatteryStatsService.enforceCallingPermission();
12275                int MY_UID = Binder.getCallingUid();
12276                final int uid;
12277                if (sender == null) {
12278                    uid = sourceUid;
12279                } else {
12280                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12281                }
12282                BatteryStatsImpl.Uid.Pkg pkg =
12283                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12284                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12285                pkg.noteWakeupAlarmLocked(tag);
12286            }
12287        }
12288    }
12289
12290    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12291        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12292            return;
12293        }
12294        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12295        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12296        synchronized (stats) {
12297            mBatteryStatsService.enforceCallingPermission();
12298            int MY_UID = Binder.getCallingUid();
12299            final int uid;
12300            if (sender == null) {
12301                uid = sourceUid;
12302            } else {
12303                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12304            }
12305            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12306        }
12307    }
12308
12309    public void noteAlarmFinish(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.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12325        }
12326    }
12327
12328    public boolean killPids(int[] pids, String pReason, boolean secure) {
12329        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12330            throw new SecurityException("killPids only available to the system");
12331        }
12332        String reason = (pReason == null) ? "Unknown" : pReason;
12333        // XXX Note: don't acquire main activity lock here, because the window
12334        // manager calls in with its locks held.
12335
12336        boolean killed = false;
12337        synchronized (mPidsSelfLocked) {
12338            int worstType = 0;
12339            for (int i=0; i<pids.length; i++) {
12340                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12341                if (proc != null) {
12342                    int type = proc.setAdj;
12343                    if (type > worstType) {
12344                        worstType = type;
12345                    }
12346                }
12347            }
12348
12349            // If the worst oom_adj is somewhere in the cached proc LRU range,
12350            // then constrain it so we will kill all cached procs.
12351            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12352                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12353                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12354            }
12355
12356            // If this is not a secure call, don't let it kill processes that
12357            // are important.
12358            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12359                worstType = ProcessList.SERVICE_ADJ;
12360            }
12361
12362            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12363            for (int i=0; i<pids.length; i++) {
12364                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12365                if (proc == null) {
12366                    continue;
12367                }
12368                int adj = proc.setAdj;
12369                if (adj >= worstType && !proc.killedByAm) {
12370                    proc.kill(reason, true);
12371                    killed = true;
12372                }
12373            }
12374        }
12375        return killed;
12376    }
12377
12378    @Override
12379    public void killUid(int appId, int userId, String reason) {
12380        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12381        synchronized (this) {
12382            final long identity = Binder.clearCallingIdentity();
12383            try {
12384                killPackageProcessesLocked(null, appId, userId,
12385                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12386                        reason != null ? reason : "kill uid");
12387            } finally {
12388                Binder.restoreCallingIdentity(identity);
12389            }
12390        }
12391    }
12392
12393    @Override
12394    public boolean killProcessesBelowForeground(String reason) {
12395        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12396            throw new SecurityException("killProcessesBelowForeground() only available to system");
12397        }
12398
12399        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12400    }
12401
12402    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12403        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12404            throw new SecurityException("killProcessesBelowAdj() only available to system");
12405        }
12406
12407        boolean killed = false;
12408        synchronized (mPidsSelfLocked) {
12409            final int size = mPidsSelfLocked.size();
12410            for (int i = 0; i < size; i++) {
12411                final int pid = mPidsSelfLocked.keyAt(i);
12412                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12413                if (proc == null) continue;
12414
12415                final int adj = proc.setAdj;
12416                if (adj > belowAdj && !proc.killedByAm) {
12417                    proc.kill(reason, true);
12418                    killed = true;
12419                }
12420            }
12421        }
12422        return killed;
12423    }
12424
12425    @Override
12426    public void hang(final IBinder who, boolean allowRestart) {
12427        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12428                != PackageManager.PERMISSION_GRANTED) {
12429            throw new SecurityException("Requires permission "
12430                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12431        }
12432
12433        final IBinder.DeathRecipient death = new DeathRecipient() {
12434            @Override
12435            public void binderDied() {
12436                synchronized (this) {
12437                    notifyAll();
12438                }
12439            }
12440        };
12441
12442        try {
12443            who.linkToDeath(death, 0);
12444        } catch (RemoteException e) {
12445            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12446            return;
12447        }
12448
12449        synchronized (this) {
12450            Watchdog.getInstance().setAllowRestart(allowRestart);
12451            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12452            synchronized (death) {
12453                while (who.isBinderAlive()) {
12454                    try {
12455                        death.wait();
12456                    } catch (InterruptedException e) {
12457                    }
12458                }
12459            }
12460            Watchdog.getInstance().setAllowRestart(true);
12461        }
12462    }
12463
12464    @Override
12465    public void restart() {
12466        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12467                != PackageManager.PERMISSION_GRANTED) {
12468            throw new SecurityException("Requires permission "
12469                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12470        }
12471
12472        Log.i(TAG, "Sending shutdown broadcast...");
12473
12474        BroadcastReceiver br = new BroadcastReceiver() {
12475            @Override public void onReceive(Context context, Intent intent) {
12476                // Now the broadcast is done, finish up the low-level shutdown.
12477                Log.i(TAG, "Shutting down activity manager...");
12478                shutdown(10000);
12479                Log.i(TAG, "Shutdown complete, restarting!");
12480                Process.killProcess(Process.myPid());
12481                System.exit(10);
12482            }
12483        };
12484
12485        // First send the high-level shut down broadcast.
12486        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12487        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12488        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12489        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12490        mContext.sendOrderedBroadcastAsUser(intent,
12491                UserHandle.ALL, null, br, mHandler, 0, null, null);
12492        */
12493        br.onReceive(mContext, intent);
12494    }
12495
12496    private long getLowRamTimeSinceIdle(long now) {
12497        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12498    }
12499
12500    @Override
12501    public void performIdleMaintenance() {
12502        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12503                != PackageManager.PERMISSION_GRANTED) {
12504            throw new SecurityException("Requires permission "
12505                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12506        }
12507
12508        synchronized (this) {
12509            final long now = SystemClock.uptimeMillis();
12510            final long timeSinceLastIdle = now - mLastIdleTime;
12511            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12512            mLastIdleTime = now;
12513            mLowRamTimeSinceLastIdle = 0;
12514            if (mLowRamStartTime != 0) {
12515                mLowRamStartTime = now;
12516            }
12517
12518            StringBuilder sb = new StringBuilder(128);
12519            sb.append("Idle maintenance over ");
12520            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12521            sb.append(" low RAM for ");
12522            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12523            Slog.i(TAG, sb.toString());
12524
12525            // If at least 1/3 of our time since the last idle period has been spent
12526            // with RAM low, then we want to kill processes.
12527            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12528
12529            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12530                ProcessRecord proc = mLruProcesses.get(i);
12531                if (proc.notCachedSinceIdle) {
12532                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12533                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12534                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12535                        if (doKilling && proc.initialIdlePss != 0
12536                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12537                            sb = new StringBuilder(128);
12538                            sb.append("Kill");
12539                            sb.append(proc.processName);
12540                            sb.append(" in idle maint: pss=");
12541                            sb.append(proc.lastPss);
12542                            sb.append(", swapPss=");
12543                            sb.append(proc.lastSwapPss);
12544                            sb.append(", initialPss=");
12545                            sb.append(proc.initialIdlePss);
12546                            sb.append(", period=");
12547                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12548                            sb.append(", lowRamPeriod=");
12549                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12550                            Slog.wtfQuiet(TAG, sb.toString());
12551                            proc.kill("idle maint (pss " + proc.lastPss
12552                                    + " from " + proc.initialIdlePss + ")", true);
12553                        }
12554                    }
12555                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12556                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12557                    proc.notCachedSinceIdle = true;
12558                    proc.initialIdlePss = 0;
12559                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12560                            mTestPssMode, isSleeping(), now);
12561                }
12562            }
12563
12564            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12565            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12566        }
12567    }
12568
12569    private void retrieveSettings() {
12570        final ContentResolver resolver = mContext.getContentResolver();
12571        final boolean freeformWindowManagement =
12572                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12573                        || Settings.Global.getInt(
12574                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12575        final boolean supportsPictureInPicture =
12576                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12577
12578        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12579        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12580        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12581        final boolean alwaysFinishActivities =
12582                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12583        final boolean lenientBackgroundCheck =
12584                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12585        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12586        final boolean forceResizable = Settings.Global.getInt(
12587                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12588        // Transfer any global setting for forcing RTL layout, into a System Property
12589        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12590
12591        final Configuration configuration = new Configuration();
12592        Settings.System.getConfiguration(resolver, configuration);
12593        if (forceRtl) {
12594            // This will take care of setting the correct layout direction flags
12595            configuration.setLayoutDirection(configuration.locale);
12596        }
12597
12598        synchronized (this) {
12599            mDebugApp = mOrigDebugApp = debugApp;
12600            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12601            mAlwaysFinishActivities = alwaysFinishActivities;
12602            mLenientBackgroundCheck = lenientBackgroundCheck;
12603            mForceResizableActivities = forceResizable;
12604            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12605            if (supportsMultiWindow || forceResizable) {
12606                mSupportsMultiWindow = true;
12607                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12608                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12609            } else {
12610                mSupportsMultiWindow = false;
12611                mSupportsFreeformWindowManagement = false;
12612                mSupportsPictureInPicture = false;
12613            }
12614            // This happens before any activities are started, so we can
12615            // change mConfiguration in-place.
12616            updateConfigurationLocked(configuration, null, true);
12617            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12618                    "Initial config: " + mConfiguration);
12619
12620            // Load resources only after the current configuration has been set.
12621            final Resources res = mContext.getResources();
12622            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12623            mThumbnailWidth = res.getDimensionPixelSize(
12624                    com.android.internal.R.dimen.thumbnail_width);
12625            mThumbnailHeight = res.getDimensionPixelSize(
12626                    com.android.internal.R.dimen.thumbnail_height);
12627            mFullscreenThumbnailScale = res.getFraction(
12628                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12629            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12630                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12631            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12632                    com.android.internal.R.string.config_appsNotReportingCrashes));
12633        }
12634    }
12635
12636    public boolean testIsSystemReady() {
12637        // no need to synchronize(this) just to read & return the value
12638        return mSystemReady;
12639    }
12640
12641    public void systemReady(final Runnable goingCallback) {
12642        synchronized(this) {
12643            if (mSystemReady) {
12644                // If we're done calling all the receivers, run the next "boot phase" passed in
12645                // by the SystemServer
12646                if (goingCallback != null) {
12647                    goingCallback.run();
12648                }
12649                return;
12650            }
12651
12652            mLocalDeviceIdleController
12653                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12654
12655            // Make sure we have the current profile info, since it is needed for security checks.
12656            mUserController.onSystemReady();
12657            mRecentTasks.onSystemReadyLocked();
12658            mAppOpsService.systemReady();
12659            mSystemReady = true;
12660        }
12661
12662        ArrayList<ProcessRecord> procsToKill = null;
12663        synchronized(mPidsSelfLocked) {
12664            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12665                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12666                if (!isAllowedWhileBooting(proc.info)){
12667                    if (procsToKill == null) {
12668                        procsToKill = new ArrayList<ProcessRecord>();
12669                    }
12670                    procsToKill.add(proc);
12671                }
12672            }
12673        }
12674
12675        synchronized(this) {
12676            if (procsToKill != null) {
12677                for (int i=procsToKill.size()-1; i>=0; i--) {
12678                    ProcessRecord proc = procsToKill.get(i);
12679                    Slog.i(TAG, "Removing system update proc: " + proc);
12680                    removeProcessLocked(proc, true, false, "system update done");
12681                }
12682            }
12683
12684            // Now that we have cleaned up any update processes, we
12685            // are ready to start launching real processes and know that
12686            // we won't trample on them any more.
12687            mProcessesReady = true;
12688        }
12689
12690        Slog.i(TAG, "System now ready");
12691        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12692            SystemClock.uptimeMillis());
12693
12694        synchronized(this) {
12695            // Make sure we have no pre-ready processes sitting around.
12696
12697            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12698                ResolveInfo ri = mContext.getPackageManager()
12699                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12700                                STOCK_PM_FLAGS);
12701                CharSequence errorMsg = null;
12702                if (ri != null) {
12703                    ActivityInfo ai = ri.activityInfo;
12704                    ApplicationInfo app = ai.applicationInfo;
12705                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12706                        mTopAction = Intent.ACTION_FACTORY_TEST;
12707                        mTopData = null;
12708                        mTopComponent = new ComponentName(app.packageName,
12709                                ai.name);
12710                    } else {
12711                        errorMsg = mContext.getResources().getText(
12712                                com.android.internal.R.string.factorytest_not_system);
12713                    }
12714                } else {
12715                    errorMsg = mContext.getResources().getText(
12716                            com.android.internal.R.string.factorytest_no_action);
12717                }
12718                if (errorMsg != null) {
12719                    mTopAction = null;
12720                    mTopData = null;
12721                    mTopComponent = null;
12722                    Message msg = Message.obtain();
12723                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12724                    msg.getData().putCharSequence("msg", errorMsg);
12725                    mUiHandler.sendMessage(msg);
12726                }
12727            }
12728        }
12729
12730        retrieveSettings();
12731        final int currentUserId;
12732        synchronized (this) {
12733            currentUserId = mUserController.getCurrentUserIdLocked();
12734            readGrantedUriPermissionsLocked();
12735        }
12736
12737        if (goingCallback != null) goingCallback.run();
12738
12739        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12740                Integer.toString(currentUserId), currentUserId);
12741        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12742                Integer.toString(currentUserId), currentUserId);
12743        mSystemServiceManager.startUser(currentUserId);
12744
12745        synchronized (this) {
12746            // Only start up encryption-aware persistent apps; once user is
12747            // unlocked we'll come back around and start unaware apps
12748            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12749
12750            // Start up initial activity.
12751            mBooting = true;
12752            // Enable home activity for system user, so that the system can always boot
12753            if (UserManager.isSplitSystemUser()) {
12754                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12755                try {
12756                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12757                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12758                            UserHandle.USER_SYSTEM);
12759                } catch (RemoteException e) {
12760                    throw e.rethrowAsRuntimeException();
12761                }
12762            }
12763            startHomeActivityLocked(currentUserId, "systemReady");
12764
12765            try {
12766                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12767                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12768                            + " data partition or your device will be unstable.");
12769                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12770                }
12771            } catch (RemoteException e) {
12772            }
12773
12774            if (!Build.isBuildConsistent()) {
12775                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12776                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12777            }
12778
12779            long ident = Binder.clearCallingIdentity();
12780            try {
12781                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12782                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12783                        | Intent.FLAG_RECEIVER_FOREGROUND);
12784                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12785                broadcastIntentLocked(null, null, intent,
12786                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12787                        null, false, false, MY_PID, Process.SYSTEM_UID,
12788                        currentUserId);
12789                intent = new Intent(Intent.ACTION_USER_STARTING);
12790                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12791                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12792                broadcastIntentLocked(null, null, intent,
12793                        null, new IIntentReceiver.Stub() {
12794                            @Override
12795                            public void performReceive(Intent intent, int resultCode, String data,
12796                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12797                                    throws RemoteException {
12798                            }
12799                        }, 0, null, null,
12800                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12801                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12802            } catch (Throwable t) {
12803                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12804            } finally {
12805                Binder.restoreCallingIdentity(ident);
12806            }
12807            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12808            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12809        }
12810    }
12811
12812    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12813        synchronized (this) {
12814            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12815        }
12816    }
12817
12818    void skipCurrentReceiverLocked(ProcessRecord app) {
12819        for (BroadcastQueue queue : mBroadcastQueues) {
12820            queue.skipCurrentReceiverLocked(app);
12821        }
12822    }
12823
12824    /**
12825     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12826     * The application process will exit immediately after this call returns.
12827     * @param app object of the crashing app, null for the system server
12828     * @param crashInfo describing the exception
12829     */
12830    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12831        ProcessRecord r = findAppProcess(app, "Crash");
12832        final String processName = app == null ? "system_server"
12833                : (r == null ? "unknown" : r.processName);
12834
12835        handleApplicationCrashInner("crash", r, processName, crashInfo);
12836    }
12837
12838    /* Native crash reporting uses this inner version because it needs to be somewhat
12839     * decoupled from the AM-managed cleanup lifecycle
12840     */
12841    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12842            ApplicationErrorReport.CrashInfo crashInfo) {
12843        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12844                UserHandle.getUserId(Binder.getCallingUid()), processName,
12845                r == null ? -1 : r.info.flags,
12846                crashInfo.exceptionClassName,
12847                crashInfo.exceptionMessage,
12848                crashInfo.throwFileName,
12849                crashInfo.throwLineNumber);
12850
12851        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12852
12853        mAppErrors.crashApplication(r, crashInfo);
12854    }
12855
12856    public void handleApplicationStrictModeViolation(
12857            IBinder app,
12858            int violationMask,
12859            StrictMode.ViolationInfo info) {
12860        ProcessRecord r = findAppProcess(app, "StrictMode");
12861        if (r == null) {
12862            return;
12863        }
12864
12865        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12866            Integer stackFingerprint = info.hashCode();
12867            boolean logIt = true;
12868            synchronized (mAlreadyLoggedViolatedStacks) {
12869                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12870                    logIt = false;
12871                    // TODO: sub-sample into EventLog for these, with
12872                    // the info.durationMillis?  Then we'd get
12873                    // the relative pain numbers, without logging all
12874                    // the stack traces repeatedly.  We'd want to do
12875                    // likewise in the client code, which also does
12876                    // dup suppression, before the Binder call.
12877                } else {
12878                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12879                        mAlreadyLoggedViolatedStacks.clear();
12880                    }
12881                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12882                }
12883            }
12884            if (logIt) {
12885                logStrictModeViolationToDropBox(r, info);
12886            }
12887        }
12888
12889        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12890            AppErrorResult result = new AppErrorResult();
12891            synchronized (this) {
12892                final long origId = Binder.clearCallingIdentity();
12893
12894                Message msg = Message.obtain();
12895                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12896                HashMap<String, Object> data = new HashMap<String, Object>();
12897                data.put("result", result);
12898                data.put("app", r);
12899                data.put("violationMask", violationMask);
12900                data.put("info", info);
12901                msg.obj = data;
12902                mUiHandler.sendMessage(msg);
12903
12904                Binder.restoreCallingIdentity(origId);
12905            }
12906            int res = result.get();
12907            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12908        }
12909    }
12910
12911    // Depending on the policy in effect, there could be a bunch of
12912    // these in quick succession so we try to batch these together to
12913    // minimize disk writes, number of dropbox entries, and maximize
12914    // compression, by having more fewer, larger records.
12915    private void logStrictModeViolationToDropBox(
12916            ProcessRecord process,
12917            StrictMode.ViolationInfo info) {
12918        if (info == null) {
12919            return;
12920        }
12921        final boolean isSystemApp = process == null ||
12922                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12923                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12924        final String processName = process == null ? "unknown" : process.processName;
12925        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12926        final DropBoxManager dbox = (DropBoxManager)
12927                mContext.getSystemService(Context.DROPBOX_SERVICE);
12928
12929        // Exit early if the dropbox isn't configured to accept this report type.
12930        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12931
12932        boolean bufferWasEmpty;
12933        boolean needsFlush;
12934        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12935        synchronized (sb) {
12936            bufferWasEmpty = sb.length() == 0;
12937            appendDropBoxProcessHeaders(process, processName, sb);
12938            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12939            sb.append("System-App: ").append(isSystemApp).append("\n");
12940            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12941            if (info.violationNumThisLoop != 0) {
12942                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12943            }
12944            if (info.numAnimationsRunning != 0) {
12945                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12946            }
12947            if (info.broadcastIntentAction != null) {
12948                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12949            }
12950            if (info.durationMillis != -1) {
12951                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12952            }
12953            if (info.numInstances != -1) {
12954                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12955            }
12956            if (info.tags != null) {
12957                for (String tag : info.tags) {
12958                    sb.append("Span-Tag: ").append(tag).append("\n");
12959                }
12960            }
12961            sb.append("\n");
12962            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12963                sb.append(info.crashInfo.stackTrace);
12964                sb.append("\n");
12965            }
12966            if (info.message != null) {
12967                sb.append(info.message);
12968                sb.append("\n");
12969            }
12970
12971            // Only buffer up to ~64k.  Various logging bits truncate
12972            // things at 128k.
12973            needsFlush = (sb.length() > 64 * 1024);
12974        }
12975
12976        // Flush immediately if the buffer's grown too large, or this
12977        // is a non-system app.  Non-system apps are isolated with a
12978        // different tag & policy and not batched.
12979        //
12980        // Batching is useful during internal testing with
12981        // StrictMode settings turned up high.  Without batching,
12982        // thousands of separate files could be created on boot.
12983        if (!isSystemApp || needsFlush) {
12984            new Thread("Error dump: " + dropboxTag) {
12985                @Override
12986                public void run() {
12987                    String report;
12988                    synchronized (sb) {
12989                        report = sb.toString();
12990                        sb.delete(0, sb.length());
12991                        sb.trimToSize();
12992                    }
12993                    if (report.length() != 0) {
12994                        dbox.addText(dropboxTag, report);
12995                    }
12996                }
12997            }.start();
12998            return;
12999        }
13000
13001        // System app batching:
13002        if (!bufferWasEmpty) {
13003            // An existing dropbox-writing thread is outstanding, so
13004            // we don't need to start it up.  The existing thread will
13005            // catch the buffer appends we just did.
13006            return;
13007        }
13008
13009        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13010        // (After this point, we shouldn't access AMS internal data structures.)
13011        new Thread("Error dump: " + dropboxTag) {
13012            @Override
13013            public void run() {
13014                // 5 second sleep to let stacks arrive and be batched together
13015                try {
13016                    Thread.sleep(5000);  // 5 seconds
13017                } catch (InterruptedException e) {}
13018
13019                String errorReport;
13020                synchronized (mStrictModeBuffer) {
13021                    errorReport = mStrictModeBuffer.toString();
13022                    if (errorReport.length() == 0) {
13023                        return;
13024                    }
13025                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13026                    mStrictModeBuffer.trimToSize();
13027                }
13028                dbox.addText(dropboxTag, errorReport);
13029            }
13030        }.start();
13031    }
13032
13033    /**
13034     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13035     * @param app object of the crashing app, null for the system server
13036     * @param tag reported by the caller
13037     * @param system whether this wtf is coming from the system
13038     * @param crashInfo describing the context of the error
13039     * @return true if the process should exit immediately (WTF is fatal)
13040     */
13041    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13042            final ApplicationErrorReport.CrashInfo crashInfo) {
13043        final int callingUid = Binder.getCallingUid();
13044        final int callingPid = Binder.getCallingPid();
13045
13046        if (system) {
13047            // If this is coming from the system, we could very well have low-level
13048            // system locks held, so we want to do this all asynchronously.  And we
13049            // never want this to become fatal, so there is that too.
13050            mHandler.post(new Runnable() {
13051                @Override public void run() {
13052                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13053                }
13054            });
13055            return false;
13056        }
13057
13058        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13059                crashInfo);
13060
13061        if (r != null && r.pid != Process.myPid() &&
13062                Settings.Global.getInt(mContext.getContentResolver(),
13063                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13064            mAppErrors.crashApplication(r, crashInfo);
13065            return true;
13066        } else {
13067            return false;
13068        }
13069    }
13070
13071    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13072            final ApplicationErrorReport.CrashInfo crashInfo) {
13073        final ProcessRecord r = findAppProcess(app, "WTF");
13074        final String processName = app == null ? "system_server"
13075                : (r == null ? "unknown" : r.processName);
13076
13077        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13078                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13079
13080        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13081
13082        return r;
13083    }
13084
13085    /**
13086     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13087     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13088     */
13089    private ProcessRecord findAppProcess(IBinder app, String reason) {
13090        if (app == null) {
13091            return null;
13092        }
13093
13094        synchronized (this) {
13095            final int NP = mProcessNames.getMap().size();
13096            for (int ip=0; ip<NP; ip++) {
13097                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13098                final int NA = apps.size();
13099                for (int ia=0; ia<NA; ia++) {
13100                    ProcessRecord p = apps.valueAt(ia);
13101                    if (p.thread != null && p.thread.asBinder() == app) {
13102                        return p;
13103                    }
13104                }
13105            }
13106
13107            Slog.w(TAG, "Can't find mystery application for " + reason
13108                    + " from pid=" + Binder.getCallingPid()
13109                    + " uid=" + Binder.getCallingUid() + ": " + app);
13110            return null;
13111        }
13112    }
13113
13114    /**
13115     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13116     * to append various headers to the dropbox log text.
13117     */
13118    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13119            StringBuilder sb) {
13120        // Watchdog thread ends up invoking this function (with
13121        // a null ProcessRecord) to add the stack file to dropbox.
13122        // Do not acquire a lock on this (am) in such cases, as it
13123        // could cause a potential deadlock, if and when watchdog
13124        // is invoked due to unavailability of lock on am and it
13125        // would prevent watchdog from killing system_server.
13126        if (process == null) {
13127            sb.append("Process: ").append(processName).append("\n");
13128            return;
13129        }
13130        // Note: ProcessRecord 'process' is guarded by the service
13131        // instance.  (notably process.pkgList, which could otherwise change
13132        // concurrently during execution of this method)
13133        synchronized (this) {
13134            sb.append("Process: ").append(processName).append("\n");
13135            int flags = process.info.flags;
13136            IPackageManager pm = AppGlobals.getPackageManager();
13137            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13138            for (int ip=0; ip<process.pkgList.size(); ip++) {
13139                String pkg = process.pkgList.keyAt(ip);
13140                sb.append("Package: ").append(pkg);
13141                try {
13142                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13143                    if (pi != null) {
13144                        sb.append(" v").append(pi.versionCode);
13145                        if (pi.versionName != null) {
13146                            sb.append(" (").append(pi.versionName).append(")");
13147                        }
13148                    }
13149                } catch (RemoteException e) {
13150                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13151                }
13152                sb.append("\n");
13153            }
13154        }
13155    }
13156
13157    private static String processClass(ProcessRecord process) {
13158        if (process == null || process.pid == MY_PID) {
13159            return "system_server";
13160        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13161            return "system_app";
13162        } else {
13163            return "data_app";
13164        }
13165    }
13166
13167    private volatile long mWtfClusterStart;
13168    private volatile int mWtfClusterCount;
13169
13170    /**
13171     * Write a description of an error (crash, WTF, ANR) to the drop box.
13172     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13173     * @param process which caused the error, null means the system server
13174     * @param activity which triggered the error, null if unknown
13175     * @param parent activity related to the error, null if unknown
13176     * @param subject line related to the error, null if absent
13177     * @param report in long form describing the error, null if absent
13178     * @param logFile to include in the report, null if none
13179     * @param crashInfo giving an application stack trace, null if absent
13180     */
13181    public void addErrorToDropBox(String eventType,
13182            ProcessRecord process, String processName, ActivityRecord activity,
13183            ActivityRecord parent, String subject,
13184            final String report, final File logFile,
13185            final ApplicationErrorReport.CrashInfo crashInfo) {
13186        // NOTE -- this must never acquire the ActivityManagerService lock,
13187        // otherwise the watchdog may be prevented from resetting the system.
13188
13189        final String dropboxTag = processClass(process) + "_" + eventType;
13190        final DropBoxManager dbox = (DropBoxManager)
13191                mContext.getSystemService(Context.DROPBOX_SERVICE);
13192
13193        // Exit early if the dropbox isn't configured to accept this report type.
13194        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13195
13196        // Rate-limit how often we're willing to do the heavy lifting below to
13197        // collect and record logs; currently 5 logs per 10 second period.
13198        final long now = SystemClock.elapsedRealtime();
13199        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13200            mWtfClusterStart = now;
13201            mWtfClusterCount = 1;
13202        } else {
13203            if (mWtfClusterCount++ >= 5) return;
13204        }
13205
13206        final StringBuilder sb = new StringBuilder(1024);
13207        appendDropBoxProcessHeaders(process, processName, sb);
13208        if (process != null) {
13209            sb.append("Foreground: ")
13210                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13211                    .append("\n");
13212        }
13213        if (activity != null) {
13214            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13215        }
13216        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13217            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13218        }
13219        if (parent != null && parent != activity) {
13220            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13221        }
13222        if (subject != null) {
13223            sb.append("Subject: ").append(subject).append("\n");
13224        }
13225        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13226        if (Debug.isDebuggerConnected()) {
13227            sb.append("Debugger: Connected\n");
13228        }
13229        sb.append("\n");
13230
13231        // Do the rest in a worker thread to avoid blocking the caller on I/O
13232        // (After this point, we shouldn't access AMS internal data structures.)
13233        Thread worker = new Thread("Error dump: " + dropboxTag) {
13234            @Override
13235            public void run() {
13236                if (report != null) {
13237                    sb.append(report);
13238                }
13239                if (logFile != null) {
13240                    try {
13241                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13242                                    "\n\n[[TRUNCATED]]"));
13243                    } catch (IOException e) {
13244                        Slog.e(TAG, "Error reading " + logFile, e);
13245                    }
13246                }
13247                if (crashInfo != null && crashInfo.stackTrace != null) {
13248                    sb.append(crashInfo.stackTrace);
13249                }
13250
13251                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13252                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13253                if (lines > 0) {
13254                    sb.append("\n");
13255
13256                    // Merge several logcat streams, and take the last N lines
13257                    InputStreamReader input = null;
13258                    try {
13259                        java.lang.Process logcat = new ProcessBuilder(
13260                                "/system/bin/timeout", "-k", "15s", "10s",
13261                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13262                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13263                                        .redirectErrorStream(true).start();
13264
13265                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13266                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13267                        input = new InputStreamReader(logcat.getInputStream());
13268
13269                        int num;
13270                        char[] buf = new char[8192];
13271                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13272                    } catch (IOException e) {
13273                        Slog.e(TAG, "Error running logcat", e);
13274                    } finally {
13275                        if (input != null) try { input.close(); } catch (IOException e) {}
13276                    }
13277                }
13278
13279                dbox.addText(dropboxTag, sb.toString());
13280            }
13281        };
13282
13283        if (process == null) {
13284            // If process is null, we are being called from some internal code
13285            // and may be about to die -- run this synchronously.
13286            worker.run();
13287        } else {
13288            worker.start();
13289        }
13290    }
13291
13292    @Override
13293    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13294        enforceNotIsolatedCaller("getProcessesInErrorState");
13295        // assume our apps are happy - lazy create the list
13296        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13297
13298        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13299                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13300        int userId = UserHandle.getUserId(Binder.getCallingUid());
13301
13302        synchronized (this) {
13303
13304            // iterate across all processes
13305            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13306                ProcessRecord app = mLruProcesses.get(i);
13307                if (!allUsers && app.userId != userId) {
13308                    continue;
13309                }
13310                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13311                    // This one's in trouble, so we'll generate a report for it
13312                    // crashes are higher priority (in case there's a crash *and* an anr)
13313                    ActivityManager.ProcessErrorStateInfo report = null;
13314                    if (app.crashing) {
13315                        report = app.crashingReport;
13316                    } else if (app.notResponding) {
13317                        report = app.notRespondingReport;
13318                    }
13319
13320                    if (report != null) {
13321                        if (errList == null) {
13322                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13323                        }
13324                        errList.add(report);
13325                    } else {
13326                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13327                                " crashing = " + app.crashing +
13328                                " notResponding = " + app.notResponding);
13329                    }
13330                }
13331            }
13332        }
13333
13334        return errList;
13335    }
13336
13337    static int procStateToImportance(int procState, int memAdj,
13338            ActivityManager.RunningAppProcessInfo currApp) {
13339        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13340        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13341            currApp.lru = memAdj;
13342        } else {
13343            currApp.lru = 0;
13344        }
13345        return imp;
13346    }
13347
13348    private void fillInProcMemInfo(ProcessRecord app,
13349            ActivityManager.RunningAppProcessInfo outInfo) {
13350        outInfo.pid = app.pid;
13351        outInfo.uid = app.info.uid;
13352        if (mHeavyWeightProcess == app) {
13353            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13354        }
13355        if (app.persistent) {
13356            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13357        }
13358        if (app.activities.size() > 0) {
13359            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13360        }
13361        outInfo.lastTrimLevel = app.trimMemoryLevel;
13362        int adj = app.curAdj;
13363        int procState = app.curProcState;
13364        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13365        outInfo.importanceReasonCode = app.adjTypeCode;
13366        outInfo.processState = app.curProcState;
13367    }
13368
13369    @Override
13370    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13371        enforceNotIsolatedCaller("getRunningAppProcesses");
13372
13373        final int callingUid = Binder.getCallingUid();
13374
13375        // Lazy instantiation of list
13376        List<ActivityManager.RunningAppProcessInfo> runList = null;
13377        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13378                callingUid) == PackageManager.PERMISSION_GRANTED;
13379        final int userId = UserHandle.getUserId(callingUid);
13380        final boolean allUids = isGetTasksAllowed(
13381                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13382
13383        synchronized (this) {
13384            // Iterate across all processes
13385            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13386                ProcessRecord app = mLruProcesses.get(i);
13387                if ((!allUsers && app.userId != userId)
13388                        || (!allUids && app.uid != callingUid)) {
13389                    continue;
13390                }
13391                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13392                    // Generate process state info for running application
13393                    ActivityManager.RunningAppProcessInfo currApp =
13394                        new ActivityManager.RunningAppProcessInfo(app.processName,
13395                                app.pid, app.getPackageList());
13396                    fillInProcMemInfo(app, currApp);
13397                    if (app.adjSource instanceof ProcessRecord) {
13398                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13399                        currApp.importanceReasonImportance =
13400                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13401                                        app.adjSourceProcState);
13402                    } else if (app.adjSource instanceof ActivityRecord) {
13403                        ActivityRecord r = (ActivityRecord)app.adjSource;
13404                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13405                    }
13406                    if (app.adjTarget instanceof ComponentName) {
13407                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13408                    }
13409                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13410                    //        + " lru=" + currApp.lru);
13411                    if (runList == null) {
13412                        runList = new ArrayList<>();
13413                    }
13414                    runList.add(currApp);
13415                }
13416            }
13417        }
13418        return runList;
13419    }
13420
13421    @Override
13422    public List<ApplicationInfo> getRunningExternalApplications() {
13423        enforceNotIsolatedCaller("getRunningExternalApplications");
13424        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13425        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13426        if (runningApps != null && runningApps.size() > 0) {
13427            Set<String> extList = new HashSet<String>();
13428            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13429                if (app.pkgList != null) {
13430                    for (String pkg : app.pkgList) {
13431                        extList.add(pkg);
13432                    }
13433                }
13434            }
13435            IPackageManager pm = AppGlobals.getPackageManager();
13436            for (String pkg : extList) {
13437                try {
13438                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13439                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13440                        retList.add(info);
13441                    }
13442                } catch (RemoteException e) {
13443                }
13444            }
13445        }
13446        return retList;
13447    }
13448
13449    @Override
13450    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13451        enforceNotIsolatedCaller("getMyMemoryState");
13452        synchronized (this) {
13453            ProcessRecord proc;
13454            synchronized (mPidsSelfLocked) {
13455                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13456            }
13457            fillInProcMemInfo(proc, outInfo);
13458        }
13459    }
13460
13461    @Override
13462    public int getMemoryTrimLevel() {
13463        enforceNotIsolatedCaller("getMyMemoryState");
13464        synchronized (this) {
13465            return mLastMemoryLevel;
13466        }
13467    }
13468
13469    @Override
13470    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13471            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13472        (new ActivityManagerShellCommand(this, false)).exec(
13473                this, in, out, err, args, resultReceiver);
13474    }
13475
13476    @Override
13477    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13478        if (checkCallingPermission(android.Manifest.permission.DUMP)
13479                != PackageManager.PERMISSION_GRANTED) {
13480            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13481                    + Binder.getCallingPid()
13482                    + ", uid=" + Binder.getCallingUid()
13483                    + " without permission "
13484                    + android.Manifest.permission.DUMP);
13485            return;
13486        }
13487
13488        boolean dumpAll = false;
13489        boolean dumpClient = false;
13490        String dumpPackage = null;
13491
13492        int opti = 0;
13493        while (opti < args.length) {
13494            String opt = args[opti];
13495            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13496                break;
13497            }
13498            opti++;
13499            if ("-a".equals(opt)) {
13500                dumpAll = true;
13501            } else if ("-c".equals(opt)) {
13502                dumpClient = true;
13503            } else if ("-p".equals(opt)) {
13504                if (opti < args.length) {
13505                    dumpPackage = args[opti];
13506                    opti++;
13507                } else {
13508                    pw.println("Error: -p option requires package argument");
13509                    return;
13510                }
13511                dumpClient = true;
13512            } else if ("-h".equals(opt)) {
13513                ActivityManagerShellCommand.dumpHelp(pw, true);
13514                return;
13515            } else {
13516                pw.println("Unknown argument: " + opt + "; use -h for help");
13517            }
13518        }
13519
13520        long origId = Binder.clearCallingIdentity();
13521        boolean more = false;
13522        // Is the caller requesting to dump a particular piece of data?
13523        if (opti < args.length) {
13524            String cmd = args[opti];
13525            opti++;
13526            if ("activities".equals(cmd) || "a".equals(cmd)) {
13527                synchronized (this) {
13528                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13529                }
13530            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13531                synchronized (this) {
13532                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13533                }
13534            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13535                String[] newArgs;
13536                String name;
13537                if (opti >= args.length) {
13538                    name = null;
13539                    newArgs = EMPTY_STRING_ARRAY;
13540                } else {
13541                    dumpPackage = args[opti];
13542                    opti++;
13543                    newArgs = new String[args.length - opti];
13544                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13545                            args.length - opti);
13546                }
13547                synchronized (this) {
13548                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13549                }
13550            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13551                String[] newArgs;
13552                String name;
13553                if (opti >= args.length) {
13554                    name = null;
13555                    newArgs = EMPTY_STRING_ARRAY;
13556                } else {
13557                    dumpPackage = args[opti];
13558                    opti++;
13559                    newArgs = new String[args.length - opti];
13560                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13561                            args.length - opti);
13562                }
13563                synchronized (this) {
13564                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13565                }
13566            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13567                String[] newArgs;
13568                String name;
13569                if (opti >= args.length) {
13570                    name = null;
13571                    newArgs = EMPTY_STRING_ARRAY;
13572                } else {
13573                    dumpPackage = args[opti];
13574                    opti++;
13575                    newArgs = new String[args.length - opti];
13576                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13577                            args.length - opti);
13578                }
13579                synchronized (this) {
13580                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13581                }
13582            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13583                synchronized (this) {
13584                    dumpOomLocked(fd, pw, args, opti, true);
13585                }
13586            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13587                synchronized (this) {
13588                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13589                }
13590            } else if ("provider".equals(cmd)) {
13591                String[] newArgs;
13592                String name;
13593                if (opti >= args.length) {
13594                    name = null;
13595                    newArgs = EMPTY_STRING_ARRAY;
13596                } else {
13597                    name = args[opti];
13598                    opti++;
13599                    newArgs = new String[args.length - opti];
13600                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13601                }
13602                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13603                    pw.println("No providers match: " + name);
13604                    pw.println("Use -h for help.");
13605                }
13606            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13607                synchronized (this) {
13608                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13609                }
13610            } else if ("service".equals(cmd)) {
13611                String[] newArgs;
13612                String name;
13613                if (opti >= args.length) {
13614                    name = null;
13615                    newArgs = EMPTY_STRING_ARRAY;
13616                } else {
13617                    name = args[opti];
13618                    opti++;
13619                    newArgs = new String[args.length - opti];
13620                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13621                            args.length - opti);
13622                }
13623                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13624                    pw.println("No services match: " + name);
13625                    pw.println("Use -h for help.");
13626                }
13627            } else if ("package".equals(cmd)) {
13628                String[] newArgs;
13629                if (opti >= args.length) {
13630                    pw.println("package: no package name specified");
13631                    pw.println("Use -h for help.");
13632                } else {
13633                    dumpPackage = args[opti];
13634                    opti++;
13635                    newArgs = new String[args.length - opti];
13636                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13637                            args.length - opti);
13638                    args = newArgs;
13639                    opti = 0;
13640                    more = true;
13641                }
13642            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13643                synchronized (this) {
13644                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13645                }
13646            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13647                synchronized (this) {
13648                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13649                }
13650            } else if ("locks".equals(cmd)) {
13651                LockGuard.dump(fd, pw, args);
13652            } else {
13653                // Dumping a single activity?
13654                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13655                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13656                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13657                    if (res < 0) {
13658                        pw.println("Bad activity command, or no activities match: " + cmd);
13659                        pw.println("Use -h for help.");
13660                    }
13661                }
13662            }
13663            if (!more) {
13664                Binder.restoreCallingIdentity(origId);
13665                return;
13666            }
13667        }
13668
13669        // No piece of data specified, dump everything.
13670        synchronized (this) {
13671            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13672            pw.println();
13673            if (dumpAll) {
13674                pw.println("-------------------------------------------------------------------------------");
13675            }
13676            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13677            pw.println();
13678            if (dumpAll) {
13679                pw.println("-------------------------------------------------------------------------------");
13680            }
13681            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13682            pw.println();
13683            if (dumpAll) {
13684                pw.println("-------------------------------------------------------------------------------");
13685            }
13686            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13687            pw.println();
13688            if (dumpAll) {
13689                pw.println("-------------------------------------------------------------------------------");
13690            }
13691            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13692            pw.println();
13693            if (dumpAll) {
13694                pw.println("-------------------------------------------------------------------------------");
13695            }
13696            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13697            pw.println();
13698            if (dumpAll) {
13699                pw.println("-------------------------------------------------------------------------------");
13700            }
13701            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13702            if (mAssociations.size() > 0) {
13703                pw.println();
13704                if (dumpAll) {
13705                    pw.println("-------------------------------------------------------------------------------");
13706                }
13707                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13708            }
13709            pw.println();
13710            if (dumpAll) {
13711                pw.println("-------------------------------------------------------------------------------");
13712            }
13713            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13714        }
13715        Binder.restoreCallingIdentity(origId);
13716    }
13717
13718    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13719            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13720        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13721
13722        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13723                dumpPackage);
13724        boolean needSep = printedAnything;
13725
13726        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13727                dumpPackage, needSep, "  mFocusedActivity: ");
13728        if (printed) {
13729            printedAnything = true;
13730            needSep = false;
13731        }
13732
13733        if (dumpPackage == null) {
13734            if (needSep) {
13735                pw.println();
13736            }
13737            needSep = true;
13738            printedAnything = true;
13739            mStackSupervisor.dump(pw, "  ");
13740        }
13741
13742        if (!printedAnything) {
13743            pw.println("  (nothing)");
13744        }
13745    }
13746
13747    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13748            int opti, boolean dumpAll, String dumpPackage) {
13749        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13750
13751        boolean printedAnything = false;
13752
13753        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13754            boolean printedHeader = false;
13755
13756            final int N = mRecentTasks.size();
13757            for (int i=0; i<N; i++) {
13758                TaskRecord tr = mRecentTasks.get(i);
13759                if (dumpPackage != null) {
13760                    if (tr.realActivity == null ||
13761                            !dumpPackage.equals(tr.realActivity)) {
13762                        continue;
13763                    }
13764                }
13765                if (!printedHeader) {
13766                    pw.println("  Recent tasks:");
13767                    printedHeader = true;
13768                    printedAnything = true;
13769                }
13770                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13771                        pw.println(tr);
13772                if (dumpAll) {
13773                    mRecentTasks.get(i).dump(pw, "    ");
13774                }
13775            }
13776        }
13777
13778        if (!printedAnything) {
13779            pw.println("  (nothing)");
13780        }
13781    }
13782
13783    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13784            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13785        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13786
13787        int dumpUid = 0;
13788        if (dumpPackage != null) {
13789            IPackageManager pm = AppGlobals.getPackageManager();
13790            try {
13791                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13792            } catch (RemoteException e) {
13793            }
13794        }
13795
13796        boolean printedAnything = false;
13797
13798        final long now = SystemClock.uptimeMillis();
13799
13800        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13801            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13802                    = mAssociations.valueAt(i1);
13803            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13804                SparseArray<ArrayMap<String, Association>> sourceUids
13805                        = targetComponents.valueAt(i2);
13806                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13807                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13808                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13809                        Association ass = sourceProcesses.valueAt(i4);
13810                        if (dumpPackage != null) {
13811                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13812                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13813                                continue;
13814                            }
13815                        }
13816                        printedAnything = true;
13817                        pw.print("  ");
13818                        pw.print(ass.mTargetProcess);
13819                        pw.print("/");
13820                        UserHandle.formatUid(pw, ass.mTargetUid);
13821                        pw.print(" <- ");
13822                        pw.print(ass.mSourceProcess);
13823                        pw.print("/");
13824                        UserHandle.formatUid(pw, ass.mSourceUid);
13825                        pw.println();
13826                        pw.print("    via ");
13827                        pw.print(ass.mTargetComponent.flattenToShortString());
13828                        pw.println();
13829                        pw.print("    ");
13830                        long dur = ass.mTime;
13831                        if (ass.mNesting > 0) {
13832                            dur += now - ass.mStartTime;
13833                        }
13834                        TimeUtils.formatDuration(dur, pw);
13835                        pw.print(" (");
13836                        pw.print(ass.mCount);
13837                        pw.print(" times)");
13838                        pw.print("  ");
13839                        for (int i=0; i<ass.mStateTimes.length; i++) {
13840                            long amt = ass.mStateTimes[i];
13841                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13842                                amt += now - ass.mLastStateUptime;
13843                            }
13844                            if (amt != 0) {
13845                                pw.print(" ");
13846                                pw.print(ProcessList.makeProcStateString(
13847                                            i + ActivityManager.MIN_PROCESS_STATE));
13848                                pw.print("=");
13849                                TimeUtils.formatDuration(amt, pw);
13850                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13851                                    pw.print("*");
13852                                }
13853                            }
13854                        }
13855                        pw.println();
13856                        if (ass.mNesting > 0) {
13857                            pw.print("    Currently active: ");
13858                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13859                            pw.println();
13860                        }
13861                    }
13862                }
13863            }
13864
13865        }
13866
13867        if (!printedAnything) {
13868            pw.println("  (nothing)");
13869        }
13870    }
13871
13872    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13873            String header, boolean needSep) {
13874        boolean printed = false;
13875        int whichAppId = -1;
13876        if (dumpPackage != null) {
13877            try {
13878                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13879                        dumpPackage, 0);
13880                whichAppId = UserHandle.getAppId(info.uid);
13881            } catch (NameNotFoundException e) {
13882                e.printStackTrace();
13883            }
13884        }
13885        for (int i=0; i<uids.size(); i++) {
13886            UidRecord uidRec = uids.valueAt(i);
13887            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13888                continue;
13889            }
13890            if (!printed) {
13891                printed = true;
13892                if (needSep) {
13893                    pw.println();
13894                }
13895                pw.print("  ");
13896                pw.println(header);
13897                needSep = true;
13898            }
13899            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13900            pw.print(": "); pw.println(uidRec);
13901        }
13902        return printed;
13903    }
13904
13905    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13906            int opti, boolean dumpAll, String dumpPackage) {
13907        boolean needSep = false;
13908        boolean printedAnything = false;
13909        int numPers = 0;
13910
13911        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13912
13913        if (dumpAll) {
13914            final int NP = mProcessNames.getMap().size();
13915            for (int ip=0; ip<NP; ip++) {
13916                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13917                final int NA = procs.size();
13918                for (int ia=0; ia<NA; ia++) {
13919                    ProcessRecord r = procs.valueAt(ia);
13920                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13921                        continue;
13922                    }
13923                    if (!needSep) {
13924                        pw.println("  All known processes:");
13925                        needSep = true;
13926                        printedAnything = true;
13927                    }
13928                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13929                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13930                        pw.print(" "); pw.println(r);
13931                    r.dump(pw, "    ");
13932                    if (r.persistent) {
13933                        numPers++;
13934                    }
13935                }
13936            }
13937        }
13938
13939        if (mIsolatedProcesses.size() > 0) {
13940            boolean printed = false;
13941            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13942                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13943                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13944                    continue;
13945                }
13946                if (!printed) {
13947                    if (needSep) {
13948                        pw.println();
13949                    }
13950                    pw.println("  Isolated process list (sorted by uid):");
13951                    printedAnything = true;
13952                    printed = true;
13953                    needSep = true;
13954                }
13955                pw.println(String.format("%sIsolated #%2d: %s",
13956                        "    ", i, r.toString()));
13957            }
13958        }
13959
13960        if (mActiveUids.size() > 0) {
13961            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13962                printedAnything = needSep = true;
13963            }
13964        }
13965        if (mValidateUids.size() > 0) {
13966            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13967                printedAnything = needSep = true;
13968            }
13969        }
13970
13971        if (mLruProcesses.size() > 0) {
13972            if (needSep) {
13973                pw.println();
13974            }
13975            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13976                    pw.print(" total, non-act at ");
13977                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13978                    pw.print(", non-svc at ");
13979                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13980                    pw.println("):");
13981            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13982            needSep = true;
13983            printedAnything = true;
13984        }
13985
13986        if (dumpAll || dumpPackage != null) {
13987            synchronized (mPidsSelfLocked) {
13988                boolean printed = false;
13989                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13990                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13991                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13992                        continue;
13993                    }
13994                    if (!printed) {
13995                        if (needSep) pw.println();
13996                        needSep = true;
13997                        pw.println("  PID mappings:");
13998                        printed = true;
13999                        printedAnything = true;
14000                    }
14001                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14002                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14003                }
14004            }
14005        }
14006
14007        if (mForegroundProcesses.size() > 0) {
14008            synchronized (mPidsSelfLocked) {
14009                boolean printed = false;
14010                for (int i=0; i<mForegroundProcesses.size(); i++) {
14011                    ProcessRecord r = mPidsSelfLocked.get(
14012                            mForegroundProcesses.valueAt(i).pid);
14013                    if (dumpPackage != null && (r == null
14014                            || !r.pkgList.containsKey(dumpPackage))) {
14015                        continue;
14016                    }
14017                    if (!printed) {
14018                        if (needSep) pw.println();
14019                        needSep = true;
14020                        pw.println("  Foreground Processes:");
14021                        printed = true;
14022                        printedAnything = true;
14023                    }
14024                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14025                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14026                }
14027            }
14028        }
14029
14030        if (mPersistentStartingProcesses.size() > 0) {
14031            if (needSep) pw.println();
14032            needSep = true;
14033            printedAnything = true;
14034            pw.println("  Persisent processes that are starting:");
14035            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14036                    "Starting Norm", "Restarting PERS", dumpPackage);
14037        }
14038
14039        if (mRemovedProcesses.size() > 0) {
14040            if (needSep) pw.println();
14041            needSep = true;
14042            printedAnything = true;
14043            pw.println("  Processes that are being removed:");
14044            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14045                    "Removed Norm", "Removed PERS", dumpPackage);
14046        }
14047
14048        if (mProcessesOnHold.size() > 0) {
14049            if (needSep) pw.println();
14050            needSep = true;
14051            printedAnything = true;
14052            pw.println("  Processes that are on old until the system is ready:");
14053            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14054                    "OnHold Norm", "OnHold PERS", dumpPackage);
14055        }
14056
14057        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14058
14059        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14060        if (needSep) {
14061            printedAnything = true;
14062        }
14063
14064        if (dumpPackage == null) {
14065            pw.println();
14066            needSep = false;
14067            mUserController.dump(pw, dumpAll);
14068        }
14069        if (mHomeProcess != null && (dumpPackage == null
14070                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14071            if (needSep) {
14072                pw.println();
14073                needSep = false;
14074            }
14075            pw.println("  mHomeProcess: " + mHomeProcess);
14076        }
14077        if (mPreviousProcess != null && (dumpPackage == null
14078                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14079            if (needSep) {
14080                pw.println();
14081                needSep = false;
14082            }
14083            pw.println("  mPreviousProcess: " + mPreviousProcess);
14084        }
14085        if (dumpAll) {
14086            StringBuilder sb = new StringBuilder(128);
14087            sb.append("  mPreviousProcessVisibleTime: ");
14088            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14089            pw.println(sb);
14090        }
14091        if (mHeavyWeightProcess != null && (dumpPackage == null
14092                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14093            if (needSep) {
14094                pw.println();
14095                needSep = false;
14096            }
14097            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14098        }
14099        if (dumpPackage == null) {
14100            pw.println("  mConfiguration: " + mConfiguration);
14101        }
14102        if (dumpAll) {
14103            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14104            if (mCompatModePackages.getPackages().size() > 0) {
14105                boolean printed = false;
14106                for (Map.Entry<String, Integer> entry
14107                        : mCompatModePackages.getPackages().entrySet()) {
14108                    String pkg = entry.getKey();
14109                    int mode = entry.getValue();
14110                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14111                        continue;
14112                    }
14113                    if (!printed) {
14114                        pw.println("  mScreenCompatPackages:");
14115                        printed = true;
14116                    }
14117                    pw.print("    "); pw.print(pkg); pw.print(": ");
14118                            pw.print(mode); pw.println();
14119                }
14120            }
14121        }
14122        if (dumpPackage == null) {
14123            pw.println("  mWakefulness="
14124                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14125            pw.println("  mSleepTokens=" + mSleepTokens);
14126            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14127                    + lockScreenShownToString());
14128            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14129            if (mRunningVoice != null) {
14130                pw.println("  mRunningVoice=" + mRunningVoice);
14131                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14132            }
14133        }
14134        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14135                || mOrigWaitForDebugger) {
14136            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14137                    || dumpPackage.equals(mOrigDebugApp)) {
14138                if (needSep) {
14139                    pw.println();
14140                    needSep = false;
14141                }
14142                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14143                        + " mDebugTransient=" + mDebugTransient
14144                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14145            }
14146        }
14147        if (mCurAppTimeTracker != null) {
14148            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14149        }
14150        if (mMemWatchProcesses.getMap().size() > 0) {
14151            pw.println("  Mem watch processes:");
14152            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14153                    = mMemWatchProcesses.getMap();
14154            for (int i=0; i<procs.size(); i++) {
14155                final String proc = procs.keyAt(i);
14156                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14157                for (int j=0; j<uids.size(); j++) {
14158                    if (needSep) {
14159                        pw.println();
14160                        needSep = false;
14161                    }
14162                    StringBuilder sb = new StringBuilder();
14163                    sb.append("    ").append(proc).append('/');
14164                    UserHandle.formatUid(sb, uids.keyAt(j));
14165                    Pair<Long, String> val = uids.valueAt(j);
14166                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14167                    if (val.second != null) {
14168                        sb.append(", report to ").append(val.second);
14169                    }
14170                    pw.println(sb.toString());
14171                }
14172            }
14173            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14174            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14175            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14176                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14177        }
14178        if (mTrackAllocationApp != null) {
14179            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14180                if (needSep) {
14181                    pw.println();
14182                    needSep = false;
14183                }
14184                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14185            }
14186        }
14187        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14188                || mProfileFd != null) {
14189            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14190                if (needSep) {
14191                    pw.println();
14192                    needSep = false;
14193                }
14194                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14195                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14196                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14197                        + mAutoStopProfiler);
14198                pw.println("  mProfileType=" + mProfileType);
14199            }
14200        }
14201        if (mNativeDebuggingApp != null) {
14202            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14203                if (needSep) {
14204                    pw.println();
14205                    needSep = false;
14206                }
14207                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14208            }
14209        }
14210        if (dumpPackage == null) {
14211            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14212                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14213                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14214            }
14215            if (mController != null) {
14216                pw.println("  mController=" + mController
14217                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14218            }
14219            if (dumpAll) {
14220                pw.println("  Total persistent processes: " + numPers);
14221                pw.println("  mProcessesReady=" + mProcessesReady
14222                        + " mSystemReady=" + mSystemReady
14223                        + " mBooted=" + mBooted
14224                        + " mFactoryTest=" + mFactoryTest);
14225                pw.println("  mBooting=" + mBooting
14226                        + " mCallFinishBooting=" + mCallFinishBooting
14227                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14228                pw.print("  mLastPowerCheckRealtime=");
14229                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14230                        pw.println("");
14231                pw.print("  mLastPowerCheckUptime=");
14232                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14233                        pw.println("");
14234                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14235                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14236                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14237                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14238                        + " (" + mLruProcesses.size() + " total)"
14239                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14240                        + " mNumServiceProcs=" + mNumServiceProcs
14241                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14242                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14243                        + " mLastMemoryLevel" + mLastMemoryLevel
14244                        + " mLastNumProcesses" + mLastNumProcesses);
14245                long now = SystemClock.uptimeMillis();
14246                pw.print("  mLastIdleTime=");
14247                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14248                        pw.print(" mLowRamSinceLastIdle=");
14249                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14250                        pw.println();
14251            }
14252        }
14253
14254        if (!printedAnything) {
14255            pw.println("  (nothing)");
14256        }
14257    }
14258
14259    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14260            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14261        if (mProcessesToGc.size() > 0) {
14262            boolean printed = false;
14263            long now = SystemClock.uptimeMillis();
14264            for (int i=0; i<mProcessesToGc.size(); i++) {
14265                ProcessRecord proc = mProcessesToGc.get(i);
14266                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14267                    continue;
14268                }
14269                if (!printed) {
14270                    if (needSep) pw.println();
14271                    needSep = true;
14272                    pw.println("  Processes that are waiting to GC:");
14273                    printed = true;
14274                }
14275                pw.print("    Process "); pw.println(proc);
14276                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14277                        pw.print(", last gced=");
14278                        pw.print(now-proc.lastRequestedGc);
14279                        pw.print(" ms ago, last lowMem=");
14280                        pw.print(now-proc.lastLowMemory);
14281                        pw.println(" ms ago");
14282
14283            }
14284        }
14285        return needSep;
14286    }
14287
14288    void printOomLevel(PrintWriter pw, String name, int adj) {
14289        pw.print("    ");
14290        if (adj >= 0) {
14291            pw.print(' ');
14292            if (adj < 10) pw.print(' ');
14293        } else {
14294            if (adj > -10) pw.print(' ');
14295        }
14296        pw.print(adj);
14297        pw.print(": ");
14298        pw.print(name);
14299        pw.print(" (");
14300        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14301        pw.println(")");
14302    }
14303
14304    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14305            int opti, boolean dumpAll) {
14306        boolean needSep = false;
14307
14308        if (mLruProcesses.size() > 0) {
14309            if (needSep) pw.println();
14310            needSep = true;
14311            pw.println("  OOM levels:");
14312            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14313            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14314            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14315            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14316            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14317            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14318            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14319            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14320            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14321            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14322            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14323            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14324            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14325            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14326
14327            if (needSep) pw.println();
14328            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14329                    pw.print(" total, non-act at ");
14330                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14331                    pw.print(", non-svc at ");
14332                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14333                    pw.println("):");
14334            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14335            needSep = true;
14336        }
14337
14338        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14339
14340        pw.println();
14341        pw.println("  mHomeProcess: " + mHomeProcess);
14342        pw.println("  mPreviousProcess: " + mPreviousProcess);
14343        if (mHeavyWeightProcess != null) {
14344            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14345        }
14346
14347        return true;
14348    }
14349
14350    /**
14351     * There are three ways to call this:
14352     *  - no provider specified: dump all the providers
14353     *  - a flattened component name that matched an existing provider was specified as the
14354     *    first arg: dump that one provider
14355     *  - the first arg isn't the flattened component name of an existing provider:
14356     *    dump all providers whose component contains the first arg as a substring
14357     */
14358    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14359            int opti, boolean dumpAll) {
14360        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14361    }
14362
14363    static class ItemMatcher {
14364        ArrayList<ComponentName> components;
14365        ArrayList<String> strings;
14366        ArrayList<Integer> objects;
14367        boolean all;
14368
14369        ItemMatcher() {
14370            all = true;
14371        }
14372
14373        void build(String name) {
14374            ComponentName componentName = ComponentName.unflattenFromString(name);
14375            if (componentName != null) {
14376                if (components == null) {
14377                    components = new ArrayList<ComponentName>();
14378                }
14379                components.add(componentName);
14380                all = false;
14381            } else {
14382                int objectId = 0;
14383                // Not a '/' separated full component name; maybe an object ID?
14384                try {
14385                    objectId = Integer.parseInt(name, 16);
14386                    if (objects == null) {
14387                        objects = new ArrayList<Integer>();
14388                    }
14389                    objects.add(objectId);
14390                    all = false;
14391                } catch (RuntimeException e) {
14392                    // Not an integer; just do string match.
14393                    if (strings == null) {
14394                        strings = new ArrayList<String>();
14395                    }
14396                    strings.add(name);
14397                    all = false;
14398                }
14399            }
14400        }
14401
14402        int build(String[] args, int opti) {
14403            for (; opti<args.length; opti++) {
14404                String name = args[opti];
14405                if ("--".equals(name)) {
14406                    return opti+1;
14407                }
14408                build(name);
14409            }
14410            return opti;
14411        }
14412
14413        boolean match(Object object, ComponentName comp) {
14414            if (all) {
14415                return true;
14416            }
14417            if (components != null) {
14418                for (int i=0; i<components.size(); i++) {
14419                    if (components.get(i).equals(comp)) {
14420                        return true;
14421                    }
14422                }
14423            }
14424            if (objects != null) {
14425                for (int i=0; i<objects.size(); i++) {
14426                    if (System.identityHashCode(object) == objects.get(i)) {
14427                        return true;
14428                    }
14429                }
14430            }
14431            if (strings != null) {
14432                String flat = comp.flattenToString();
14433                for (int i=0; i<strings.size(); i++) {
14434                    if (flat.contains(strings.get(i))) {
14435                        return true;
14436                    }
14437                }
14438            }
14439            return false;
14440        }
14441    }
14442
14443    /**
14444     * There are three things that cmd can be:
14445     *  - a flattened component name that matches an existing activity
14446     *  - the cmd arg isn't the flattened component name of an existing activity:
14447     *    dump all activity whose component contains the cmd as a substring
14448     *  - A hex number of the ActivityRecord object instance.
14449     */
14450    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14451            int opti, boolean dumpAll) {
14452        ArrayList<ActivityRecord> activities;
14453
14454        synchronized (this) {
14455            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14456        }
14457
14458        if (activities.size() <= 0) {
14459            return false;
14460        }
14461
14462        String[] newArgs = new String[args.length - opti];
14463        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14464
14465        TaskRecord lastTask = null;
14466        boolean needSep = false;
14467        for (int i=activities.size()-1; i>=0; i--) {
14468            ActivityRecord r = activities.get(i);
14469            if (needSep) {
14470                pw.println();
14471            }
14472            needSep = true;
14473            synchronized (this) {
14474                if (lastTask != r.task) {
14475                    lastTask = r.task;
14476                    pw.print("TASK "); pw.print(lastTask.affinity);
14477                            pw.print(" id="); pw.println(lastTask.taskId);
14478                    if (dumpAll) {
14479                        lastTask.dump(pw, "  ");
14480                    }
14481                }
14482            }
14483            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14484        }
14485        return true;
14486    }
14487
14488    /**
14489     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14490     * there is a thread associated with the activity.
14491     */
14492    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14493            final ActivityRecord r, String[] args, boolean dumpAll) {
14494        String innerPrefix = prefix + "  ";
14495        synchronized (this) {
14496            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14497                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14498                    pw.print(" pid=");
14499                    if (r.app != null) pw.println(r.app.pid);
14500                    else pw.println("(not running)");
14501            if (dumpAll) {
14502                r.dump(pw, innerPrefix);
14503            }
14504        }
14505        if (r.app != null && r.app.thread != null) {
14506            // flush anything that is already in the PrintWriter since the thread is going
14507            // to write to the file descriptor directly
14508            pw.flush();
14509            try {
14510                TransferPipe tp = new TransferPipe();
14511                try {
14512                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14513                            r.appToken, innerPrefix, args);
14514                    tp.go(fd);
14515                } finally {
14516                    tp.kill();
14517                }
14518            } catch (IOException e) {
14519                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14520            } catch (RemoteException e) {
14521                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14522            }
14523        }
14524    }
14525
14526    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14527            int opti, boolean dumpAll, String dumpPackage) {
14528        boolean needSep = false;
14529        boolean onlyHistory = false;
14530        boolean printedAnything = false;
14531
14532        if ("history".equals(dumpPackage)) {
14533            if (opti < args.length && "-s".equals(args[opti])) {
14534                dumpAll = false;
14535            }
14536            onlyHistory = true;
14537            dumpPackage = null;
14538        }
14539
14540        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14541        if (!onlyHistory && dumpAll) {
14542            if (mRegisteredReceivers.size() > 0) {
14543                boolean printed = false;
14544                Iterator it = mRegisteredReceivers.values().iterator();
14545                while (it.hasNext()) {
14546                    ReceiverList r = (ReceiverList)it.next();
14547                    if (dumpPackage != null && (r.app == null ||
14548                            !dumpPackage.equals(r.app.info.packageName))) {
14549                        continue;
14550                    }
14551                    if (!printed) {
14552                        pw.println("  Registered Receivers:");
14553                        needSep = true;
14554                        printed = true;
14555                        printedAnything = true;
14556                    }
14557                    pw.print("  * "); pw.println(r);
14558                    r.dump(pw, "    ");
14559                }
14560            }
14561
14562            if (mReceiverResolver.dump(pw, needSep ?
14563                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14564                    "    ", dumpPackage, false, false)) {
14565                needSep = true;
14566                printedAnything = true;
14567            }
14568        }
14569
14570        for (BroadcastQueue q : mBroadcastQueues) {
14571            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14572            printedAnything |= needSep;
14573        }
14574
14575        needSep = true;
14576
14577        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14578            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14579                if (needSep) {
14580                    pw.println();
14581                }
14582                needSep = true;
14583                printedAnything = true;
14584                pw.print("  Sticky broadcasts for user ");
14585                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14586                StringBuilder sb = new StringBuilder(128);
14587                for (Map.Entry<String, ArrayList<Intent>> ent
14588                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14589                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14590                    if (dumpAll) {
14591                        pw.println(":");
14592                        ArrayList<Intent> intents = ent.getValue();
14593                        final int N = intents.size();
14594                        for (int i=0; i<N; i++) {
14595                            sb.setLength(0);
14596                            sb.append("    Intent: ");
14597                            intents.get(i).toShortString(sb, false, true, false, false);
14598                            pw.println(sb.toString());
14599                            Bundle bundle = intents.get(i).getExtras();
14600                            if (bundle != null) {
14601                                pw.print("      ");
14602                                pw.println(bundle.toString());
14603                            }
14604                        }
14605                    } else {
14606                        pw.println("");
14607                    }
14608                }
14609            }
14610        }
14611
14612        if (!onlyHistory && dumpAll) {
14613            pw.println();
14614            for (BroadcastQueue queue : mBroadcastQueues) {
14615                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14616                        + queue.mBroadcastsScheduled);
14617            }
14618            pw.println("  mHandler:");
14619            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14620            needSep = true;
14621            printedAnything = true;
14622        }
14623
14624        if (!printedAnything) {
14625            pw.println("  (nothing)");
14626        }
14627    }
14628
14629    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14630            int opti, boolean dumpAll, String dumpPackage) {
14631        boolean needSep;
14632        boolean printedAnything = false;
14633
14634        ItemMatcher matcher = new ItemMatcher();
14635        matcher.build(args, opti);
14636
14637        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14638
14639        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14640        printedAnything |= needSep;
14641
14642        if (mLaunchingProviders.size() > 0) {
14643            boolean printed = false;
14644            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14645                ContentProviderRecord r = mLaunchingProviders.get(i);
14646                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14647                    continue;
14648                }
14649                if (!printed) {
14650                    if (needSep) pw.println();
14651                    needSep = true;
14652                    pw.println("  Launching content providers:");
14653                    printed = true;
14654                    printedAnything = true;
14655                }
14656                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14657                        pw.println(r);
14658            }
14659        }
14660
14661        if (!printedAnything) {
14662            pw.println("  (nothing)");
14663        }
14664    }
14665
14666    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14667            int opti, boolean dumpAll, String dumpPackage) {
14668        boolean needSep = false;
14669        boolean printedAnything = false;
14670
14671        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14672
14673        if (mGrantedUriPermissions.size() > 0) {
14674            boolean printed = false;
14675            int dumpUid = -2;
14676            if (dumpPackage != null) {
14677                try {
14678                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14679                            MATCH_UNINSTALLED_PACKAGES, 0);
14680                } catch (NameNotFoundException e) {
14681                    dumpUid = -1;
14682                }
14683            }
14684            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14685                int uid = mGrantedUriPermissions.keyAt(i);
14686                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14687                    continue;
14688                }
14689                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14690                if (!printed) {
14691                    if (needSep) pw.println();
14692                    needSep = true;
14693                    pw.println("  Granted Uri Permissions:");
14694                    printed = true;
14695                    printedAnything = true;
14696                }
14697                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14698                for (UriPermission perm : perms.values()) {
14699                    pw.print("    "); pw.println(perm);
14700                    if (dumpAll) {
14701                        perm.dump(pw, "      ");
14702                    }
14703                }
14704            }
14705        }
14706
14707        if (!printedAnything) {
14708            pw.println("  (nothing)");
14709        }
14710    }
14711
14712    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14713            int opti, boolean dumpAll, String dumpPackage) {
14714        boolean printed = false;
14715
14716        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14717
14718        if (mIntentSenderRecords.size() > 0) {
14719            Iterator<WeakReference<PendingIntentRecord>> it
14720                    = mIntentSenderRecords.values().iterator();
14721            while (it.hasNext()) {
14722                WeakReference<PendingIntentRecord> ref = it.next();
14723                PendingIntentRecord rec = ref != null ? ref.get(): null;
14724                if (dumpPackage != null && (rec == null
14725                        || !dumpPackage.equals(rec.key.packageName))) {
14726                    continue;
14727                }
14728                printed = true;
14729                if (rec != null) {
14730                    pw.print("  * "); pw.println(rec);
14731                    if (dumpAll) {
14732                        rec.dump(pw, "    ");
14733                    }
14734                } else {
14735                    pw.print("  * "); pw.println(ref);
14736                }
14737            }
14738        }
14739
14740        if (!printed) {
14741            pw.println("  (nothing)");
14742        }
14743    }
14744
14745    private static final int dumpProcessList(PrintWriter pw,
14746            ActivityManagerService service, List list,
14747            String prefix, String normalLabel, String persistentLabel,
14748            String dumpPackage) {
14749        int numPers = 0;
14750        final int N = list.size()-1;
14751        for (int i=N; i>=0; i--) {
14752            ProcessRecord r = (ProcessRecord)list.get(i);
14753            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14754                continue;
14755            }
14756            pw.println(String.format("%s%s #%2d: %s",
14757                    prefix, (r.persistent ? persistentLabel : normalLabel),
14758                    i, r.toString()));
14759            if (r.persistent) {
14760                numPers++;
14761            }
14762        }
14763        return numPers;
14764    }
14765
14766    private static final boolean dumpProcessOomList(PrintWriter pw,
14767            ActivityManagerService service, List<ProcessRecord> origList,
14768            String prefix, String normalLabel, String persistentLabel,
14769            boolean inclDetails, String dumpPackage) {
14770
14771        ArrayList<Pair<ProcessRecord, Integer>> list
14772                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14773        for (int i=0; i<origList.size(); i++) {
14774            ProcessRecord r = origList.get(i);
14775            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14776                continue;
14777            }
14778            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14779        }
14780
14781        if (list.size() <= 0) {
14782            return false;
14783        }
14784
14785        Comparator<Pair<ProcessRecord, Integer>> comparator
14786                = new Comparator<Pair<ProcessRecord, Integer>>() {
14787            @Override
14788            public int compare(Pair<ProcessRecord, Integer> object1,
14789                    Pair<ProcessRecord, Integer> object2) {
14790                if (object1.first.setAdj != object2.first.setAdj) {
14791                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14792                }
14793                if (object1.first.setProcState != object2.first.setProcState) {
14794                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14795                }
14796                if (object1.second.intValue() != object2.second.intValue()) {
14797                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14798                }
14799                return 0;
14800            }
14801        };
14802
14803        Collections.sort(list, comparator);
14804
14805        final long curRealtime = SystemClock.elapsedRealtime();
14806        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14807        final long curUptime = SystemClock.uptimeMillis();
14808        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14809
14810        for (int i=list.size()-1; i>=0; i--) {
14811            ProcessRecord r = list.get(i).first;
14812            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14813            char schedGroup;
14814            switch (r.setSchedGroup) {
14815                case ProcessList.SCHED_GROUP_BACKGROUND:
14816                    schedGroup = 'B';
14817                    break;
14818                case ProcessList.SCHED_GROUP_DEFAULT:
14819                    schedGroup = 'F';
14820                    break;
14821                case ProcessList.SCHED_GROUP_TOP_APP:
14822                    schedGroup = 'T';
14823                    break;
14824                default:
14825                    schedGroup = '?';
14826                    break;
14827            }
14828            char foreground;
14829            if (r.foregroundActivities) {
14830                foreground = 'A';
14831            } else if (r.foregroundServices) {
14832                foreground = 'S';
14833            } else {
14834                foreground = ' ';
14835            }
14836            String procState = ProcessList.makeProcStateString(r.curProcState);
14837            pw.print(prefix);
14838            pw.print(r.persistent ? persistentLabel : normalLabel);
14839            pw.print(" #");
14840            int num = (origList.size()-1)-list.get(i).second;
14841            if (num < 10) pw.print(' ');
14842            pw.print(num);
14843            pw.print(": ");
14844            pw.print(oomAdj);
14845            pw.print(' ');
14846            pw.print(schedGroup);
14847            pw.print('/');
14848            pw.print(foreground);
14849            pw.print('/');
14850            pw.print(procState);
14851            pw.print(" trm:");
14852            if (r.trimMemoryLevel < 10) pw.print(' ');
14853            pw.print(r.trimMemoryLevel);
14854            pw.print(' ');
14855            pw.print(r.toShortString());
14856            pw.print(" (");
14857            pw.print(r.adjType);
14858            pw.println(')');
14859            if (r.adjSource != null || r.adjTarget != null) {
14860                pw.print(prefix);
14861                pw.print("    ");
14862                if (r.adjTarget instanceof ComponentName) {
14863                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14864                } else if (r.adjTarget != null) {
14865                    pw.print(r.adjTarget.toString());
14866                } else {
14867                    pw.print("{null}");
14868                }
14869                pw.print("<=");
14870                if (r.adjSource instanceof ProcessRecord) {
14871                    pw.print("Proc{");
14872                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14873                    pw.println("}");
14874                } else if (r.adjSource != null) {
14875                    pw.println(r.adjSource.toString());
14876                } else {
14877                    pw.println("{null}");
14878                }
14879            }
14880            if (inclDetails) {
14881                pw.print(prefix);
14882                pw.print("    ");
14883                pw.print("oom: max="); pw.print(r.maxAdj);
14884                pw.print(" curRaw="); pw.print(r.curRawAdj);
14885                pw.print(" setRaw="); pw.print(r.setRawAdj);
14886                pw.print(" cur="); pw.print(r.curAdj);
14887                pw.print(" set="); pw.println(r.setAdj);
14888                pw.print(prefix);
14889                pw.print("    ");
14890                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14891                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14892                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14893                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14894                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14895                pw.println();
14896                pw.print(prefix);
14897                pw.print("    ");
14898                pw.print("cached="); pw.print(r.cached);
14899                pw.print(" empty="); pw.print(r.empty);
14900                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14901
14902                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14903                    if (r.lastWakeTime != 0) {
14904                        long wtime;
14905                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14906                        synchronized (stats) {
14907                            wtime = stats.getProcessWakeTime(r.info.uid,
14908                                    r.pid, curRealtime);
14909                        }
14910                        long timeUsed = wtime - r.lastWakeTime;
14911                        pw.print(prefix);
14912                        pw.print("    ");
14913                        pw.print("keep awake over ");
14914                        TimeUtils.formatDuration(realtimeSince, pw);
14915                        pw.print(" used ");
14916                        TimeUtils.formatDuration(timeUsed, pw);
14917                        pw.print(" (");
14918                        pw.print((timeUsed*100)/realtimeSince);
14919                        pw.println("%)");
14920                    }
14921                    if (r.lastCpuTime != 0) {
14922                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14923                        pw.print(prefix);
14924                        pw.print("    ");
14925                        pw.print("run cpu over ");
14926                        TimeUtils.formatDuration(uptimeSince, pw);
14927                        pw.print(" used ");
14928                        TimeUtils.formatDuration(timeUsed, pw);
14929                        pw.print(" (");
14930                        pw.print((timeUsed*100)/uptimeSince);
14931                        pw.println("%)");
14932                    }
14933                }
14934            }
14935        }
14936        return true;
14937    }
14938
14939    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14940            String[] args) {
14941        ArrayList<ProcessRecord> procs;
14942        synchronized (this) {
14943            if (args != null && args.length > start
14944                    && args[start].charAt(0) != '-') {
14945                procs = new ArrayList<ProcessRecord>();
14946                int pid = -1;
14947                try {
14948                    pid = Integer.parseInt(args[start]);
14949                } catch (NumberFormatException e) {
14950                }
14951                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14952                    ProcessRecord proc = mLruProcesses.get(i);
14953                    if (proc.pid == pid) {
14954                        procs.add(proc);
14955                    } else if (allPkgs && proc.pkgList != null
14956                            && proc.pkgList.containsKey(args[start])) {
14957                        procs.add(proc);
14958                    } else if (proc.processName.equals(args[start])) {
14959                        procs.add(proc);
14960                    }
14961                }
14962                if (procs.size() <= 0) {
14963                    return null;
14964                }
14965            } else {
14966                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14967            }
14968        }
14969        return procs;
14970    }
14971
14972    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14973            PrintWriter pw, String[] args) {
14974        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14975        if (procs == null) {
14976            pw.println("No process found for: " + args[0]);
14977            return;
14978        }
14979
14980        long uptime = SystemClock.uptimeMillis();
14981        long realtime = SystemClock.elapsedRealtime();
14982        pw.println("Applications Graphics Acceleration Info:");
14983        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14984
14985        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14986            ProcessRecord r = procs.get(i);
14987            if (r.thread != null) {
14988                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14989                pw.flush();
14990                try {
14991                    TransferPipe tp = new TransferPipe();
14992                    try {
14993                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14994                        tp.go(fd);
14995                    } finally {
14996                        tp.kill();
14997                    }
14998                } catch (IOException e) {
14999                    pw.println("Failure while dumping the app: " + r);
15000                    pw.flush();
15001                } catch (RemoteException e) {
15002                    pw.println("Got a RemoteException while dumping the app " + r);
15003                    pw.flush();
15004                }
15005            }
15006        }
15007    }
15008
15009    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15010        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15011        if (procs == null) {
15012            pw.println("No process found for: " + args[0]);
15013            return;
15014        }
15015
15016        pw.println("Applications Database Info:");
15017
15018        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15019            ProcessRecord r = procs.get(i);
15020            if (r.thread != null) {
15021                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15022                pw.flush();
15023                try {
15024                    TransferPipe tp = new TransferPipe();
15025                    try {
15026                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15027                        tp.go(fd);
15028                    } finally {
15029                        tp.kill();
15030                    }
15031                } catch (IOException e) {
15032                    pw.println("Failure while dumping the app: " + r);
15033                    pw.flush();
15034                } catch (RemoteException e) {
15035                    pw.println("Got a RemoteException while dumping the app " + r);
15036                    pw.flush();
15037                }
15038            }
15039        }
15040    }
15041
15042    final static class MemItem {
15043        final boolean isProc;
15044        final String label;
15045        final String shortLabel;
15046        final long pss;
15047        final long swapPss;
15048        final int id;
15049        final boolean hasActivities;
15050        ArrayList<MemItem> subitems;
15051
15052        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15053                boolean _hasActivities) {
15054            isProc = true;
15055            label = _label;
15056            shortLabel = _shortLabel;
15057            pss = _pss;
15058            swapPss = _swapPss;
15059            id = _id;
15060            hasActivities = _hasActivities;
15061        }
15062
15063        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15064            isProc = false;
15065            label = _label;
15066            shortLabel = _shortLabel;
15067            pss = _pss;
15068            swapPss = _swapPss;
15069            id = _id;
15070            hasActivities = false;
15071        }
15072    }
15073
15074    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15075            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15076        if (sort && !isCompact) {
15077            Collections.sort(items, new Comparator<MemItem>() {
15078                @Override
15079                public int compare(MemItem lhs, MemItem rhs) {
15080                    if (lhs.pss < rhs.pss) {
15081                        return 1;
15082                    } else if (lhs.pss > rhs.pss) {
15083                        return -1;
15084                    }
15085                    return 0;
15086                }
15087            });
15088        }
15089
15090        for (int i=0; i<items.size(); i++) {
15091            MemItem mi = items.get(i);
15092            if (!isCompact) {
15093                if (dumpSwapPss) {
15094                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15095                            mi.label, stringifyKBSize(mi.swapPss));
15096                } else {
15097                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15098                }
15099            } else if (mi.isProc) {
15100                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15101                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15102                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15103                pw.println(mi.hasActivities ? ",a" : ",e");
15104            } else {
15105                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15106                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15107            }
15108            if (mi.subitems != null) {
15109                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15110                        true, isCompact, dumpSwapPss);
15111            }
15112        }
15113    }
15114
15115    // These are in KB.
15116    static final long[] DUMP_MEM_BUCKETS = new long[] {
15117        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15118        120*1024, 160*1024, 200*1024,
15119        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15120        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15121    };
15122
15123    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15124            boolean stackLike) {
15125        int start = label.lastIndexOf('.');
15126        if (start >= 0) start++;
15127        else start = 0;
15128        int end = label.length();
15129        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15130            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15131                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15132                out.append(bucket);
15133                out.append(stackLike ? "MB." : "MB ");
15134                out.append(label, start, end);
15135                return;
15136            }
15137        }
15138        out.append(memKB/1024);
15139        out.append(stackLike ? "MB." : "MB ");
15140        out.append(label, start, end);
15141    }
15142
15143    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15144            ProcessList.NATIVE_ADJ,
15145            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15146            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15147            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15148            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15149            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15150            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15151    };
15152    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15153            "Native",
15154            "System", "Persistent", "Persistent Service", "Foreground",
15155            "Visible", "Perceptible",
15156            "Heavy Weight", "Backup",
15157            "A Services", "Home",
15158            "Previous", "B Services", "Cached"
15159    };
15160    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15161            "native",
15162            "sys", "pers", "persvc", "fore",
15163            "vis", "percept",
15164            "heavy", "backup",
15165            "servicea", "home",
15166            "prev", "serviceb", "cached"
15167    };
15168
15169    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15170            long realtime, boolean isCheckinRequest, boolean isCompact) {
15171        if (isCompact) {
15172            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15173        }
15174        if (isCheckinRequest || isCompact) {
15175            // short checkin version
15176            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15177        } else {
15178            pw.println("Applications Memory Usage (in Kilobytes):");
15179            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15180        }
15181    }
15182
15183    private static final int KSM_SHARED = 0;
15184    private static final int KSM_SHARING = 1;
15185    private static final int KSM_UNSHARED = 2;
15186    private static final int KSM_VOLATILE = 3;
15187
15188    private final long[] getKsmInfo() {
15189        long[] longOut = new long[4];
15190        final int[] SINGLE_LONG_FORMAT = new int[] {
15191            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15192        };
15193        long[] longTmp = new long[1];
15194        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15195                SINGLE_LONG_FORMAT, null, longTmp, null);
15196        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15197        longTmp[0] = 0;
15198        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15199                SINGLE_LONG_FORMAT, null, longTmp, null);
15200        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15201        longTmp[0] = 0;
15202        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15203                SINGLE_LONG_FORMAT, null, longTmp, null);
15204        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15205        longTmp[0] = 0;
15206        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15207                SINGLE_LONG_FORMAT, null, longTmp, null);
15208        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15209        return longOut;
15210    }
15211
15212    private static String stringifySize(long size, int order) {
15213        Locale locale = Locale.US;
15214        switch (order) {
15215            case 1:
15216                return String.format(locale, "%,13d", size);
15217            case 1024:
15218                return String.format(locale, "%,9dK", size / 1024);
15219            case 1024 * 1024:
15220                return String.format(locale, "%,5dM", size / 1024 / 1024);
15221            case 1024 * 1024 * 1024:
15222                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15223            default:
15224                throw new IllegalArgumentException("Invalid size order");
15225        }
15226    }
15227
15228    private static String stringifyKBSize(long size) {
15229        return stringifySize(size * 1024, 1024);
15230    }
15231
15232    // Update this version number in case you change the 'compact' format
15233    private static final int MEMINFO_COMPACT_VERSION = 1;
15234
15235    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15236            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15237        boolean dumpDetails = false;
15238        boolean dumpFullDetails = false;
15239        boolean dumpDalvik = false;
15240        boolean dumpSummaryOnly = false;
15241        boolean dumpUnreachable = false;
15242        boolean oomOnly = false;
15243        boolean isCompact = false;
15244        boolean localOnly = false;
15245        boolean packages = false;
15246        boolean isCheckinRequest = false;
15247        boolean dumpSwapPss = false;
15248
15249        int opti = 0;
15250        while (opti < args.length) {
15251            String opt = args[opti];
15252            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15253                break;
15254            }
15255            opti++;
15256            if ("-a".equals(opt)) {
15257                dumpDetails = true;
15258                dumpFullDetails = true;
15259                dumpDalvik = true;
15260                dumpSwapPss = true;
15261            } else if ("-d".equals(opt)) {
15262                dumpDalvik = true;
15263            } else if ("-c".equals(opt)) {
15264                isCompact = true;
15265            } else if ("-s".equals(opt)) {
15266                dumpDetails = true;
15267                dumpSummaryOnly = true;
15268            } else if ("-S".equals(opt)) {
15269                dumpSwapPss = true;
15270            } else if ("--unreachable".equals(opt)) {
15271                dumpUnreachable = true;
15272            } else if ("--oom".equals(opt)) {
15273                oomOnly = true;
15274            } else if ("--local".equals(opt)) {
15275                localOnly = true;
15276            } else if ("--package".equals(opt)) {
15277                packages = true;
15278            } else if ("--checkin".equals(opt)) {
15279                isCheckinRequest = true;
15280
15281            } else if ("-h".equals(opt)) {
15282                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15283                pw.println("  -a: include all available information for each process.");
15284                pw.println("  -d: include dalvik details.");
15285                pw.println("  -c: dump in a compact machine-parseable representation.");
15286                pw.println("  -s: dump only summary of application memory usage.");
15287                pw.println("  -S: dump also SwapPss.");
15288                pw.println("  --oom: only show processes organized by oom adj.");
15289                pw.println("  --local: only collect details locally, don't call process.");
15290                pw.println("  --package: interpret process arg as package, dumping all");
15291                pw.println("             processes that have loaded that package.");
15292                pw.println("  --checkin: dump data for a checkin");
15293                pw.println("If [process] is specified it can be the name or ");
15294                pw.println("pid of a specific process to dump.");
15295                return;
15296            } else {
15297                pw.println("Unknown argument: " + opt + "; use -h for help");
15298            }
15299        }
15300
15301        long uptime = SystemClock.uptimeMillis();
15302        long realtime = SystemClock.elapsedRealtime();
15303        final long[] tmpLong = new long[1];
15304
15305        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15306        if (procs == null) {
15307            // No Java processes.  Maybe they want to print a native process.
15308            if (args != null && args.length > opti
15309                    && args[opti].charAt(0) != '-') {
15310                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15311                        = new ArrayList<ProcessCpuTracker.Stats>();
15312                updateCpuStatsNow();
15313                int findPid = -1;
15314                try {
15315                    findPid = Integer.parseInt(args[opti]);
15316                } catch (NumberFormatException e) {
15317                }
15318                synchronized (mProcessCpuTracker) {
15319                    final int N = mProcessCpuTracker.countStats();
15320                    for (int i=0; i<N; i++) {
15321                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15322                        if (st.pid == findPid || (st.baseName != null
15323                                && st.baseName.equals(args[opti]))) {
15324                            nativeProcs.add(st);
15325                        }
15326                    }
15327                }
15328                if (nativeProcs.size() > 0) {
15329                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15330                            isCompact);
15331                    Debug.MemoryInfo mi = null;
15332                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15333                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15334                        final int pid = r.pid;
15335                        if (!isCheckinRequest && dumpDetails) {
15336                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15337                        }
15338                        if (mi == null) {
15339                            mi = new Debug.MemoryInfo();
15340                        }
15341                        if (dumpDetails || (!brief && !oomOnly)) {
15342                            Debug.getMemoryInfo(pid, mi);
15343                        } else {
15344                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15345                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15346                        }
15347                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15348                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15349                        if (isCheckinRequest) {
15350                            pw.println();
15351                        }
15352                    }
15353                    return;
15354                }
15355            }
15356            pw.println("No process found for: " + args[opti]);
15357            return;
15358        }
15359
15360        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15361            dumpDetails = true;
15362        }
15363
15364        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15365
15366        String[] innerArgs = new String[args.length-opti];
15367        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15368
15369        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15370        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15371        long nativePss = 0;
15372        long nativeSwapPss = 0;
15373        long dalvikPss = 0;
15374        long dalvikSwapPss = 0;
15375        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15376                EmptyArray.LONG;
15377        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15378                EmptyArray.LONG;
15379        long otherPss = 0;
15380        long otherSwapPss = 0;
15381        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15382        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15383
15384        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15385        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15386        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15387                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15388
15389        long totalPss = 0;
15390        long totalSwapPss = 0;
15391        long cachedPss = 0;
15392        long cachedSwapPss = 0;
15393        boolean hasSwapPss = false;
15394
15395        Debug.MemoryInfo mi = null;
15396        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15397            final ProcessRecord r = procs.get(i);
15398            final IApplicationThread thread;
15399            final int pid;
15400            final int oomAdj;
15401            final boolean hasActivities;
15402            synchronized (this) {
15403                thread = r.thread;
15404                pid = r.pid;
15405                oomAdj = r.getSetAdjWithServices();
15406                hasActivities = r.activities.size() > 0;
15407            }
15408            if (thread != null) {
15409                if (!isCheckinRequest && dumpDetails) {
15410                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15411                }
15412                if (mi == null) {
15413                    mi = new Debug.MemoryInfo();
15414                }
15415                if (dumpDetails || (!brief && !oomOnly)) {
15416                    Debug.getMemoryInfo(pid, mi);
15417                    hasSwapPss = mi.hasSwappedOutPss;
15418                } else {
15419                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15420                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15421                }
15422                if (dumpDetails) {
15423                    if (localOnly) {
15424                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15425                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15426                        if (isCheckinRequest) {
15427                            pw.println();
15428                        }
15429                    } else {
15430                        try {
15431                            pw.flush();
15432                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15433                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15434                        } catch (RemoteException e) {
15435                            if (!isCheckinRequest) {
15436                                pw.println("Got RemoteException!");
15437                                pw.flush();
15438                            }
15439                        }
15440                    }
15441                }
15442
15443                final long myTotalPss = mi.getTotalPss();
15444                final long myTotalUss = mi.getTotalUss();
15445                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15446
15447                synchronized (this) {
15448                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15449                        // Record this for posterity if the process has been stable.
15450                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15451                    }
15452                }
15453
15454                if (!isCheckinRequest && mi != null) {
15455                    totalPss += myTotalPss;
15456                    totalSwapPss += myTotalSwapPss;
15457                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15458                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15459                            myTotalSwapPss, pid, hasActivities);
15460                    procMems.add(pssItem);
15461                    procMemsMap.put(pid, pssItem);
15462
15463                    nativePss += mi.nativePss;
15464                    nativeSwapPss += mi.nativeSwappedOutPss;
15465                    dalvikPss += mi.dalvikPss;
15466                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15467                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15468                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15469                        dalvikSubitemSwapPss[j] +=
15470                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15471                    }
15472                    otherPss += mi.otherPss;
15473                    otherSwapPss += mi.otherSwappedOutPss;
15474                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15475                        long mem = mi.getOtherPss(j);
15476                        miscPss[j] += mem;
15477                        otherPss -= mem;
15478                        mem = mi.getOtherSwappedOutPss(j);
15479                        miscSwapPss[j] += mem;
15480                        otherSwapPss -= mem;
15481                    }
15482
15483                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15484                        cachedPss += myTotalPss;
15485                        cachedSwapPss += myTotalSwapPss;
15486                    }
15487
15488                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15489                        if (oomIndex == (oomPss.length - 1)
15490                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15491                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15492                            oomPss[oomIndex] += myTotalPss;
15493                            oomSwapPss[oomIndex] += myTotalSwapPss;
15494                            if (oomProcs[oomIndex] == null) {
15495                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15496                            }
15497                            oomProcs[oomIndex].add(pssItem);
15498                            break;
15499                        }
15500                    }
15501                }
15502            }
15503        }
15504
15505        long nativeProcTotalPss = 0;
15506
15507        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15508            // If we are showing aggregations, also look for native processes to
15509            // include so that our aggregations are more accurate.
15510            updateCpuStatsNow();
15511            mi = null;
15512            synchronized (mProcessCpuTracker) {
15513                final int N = mProcessCpuTracker.countStats();
15514                for (int i=0; i<N; i++) {
15515                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15516                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15517                        if (mi == null) {
15518                            mi = new Debug.MemoryInfo();
15519                        }
15520                        if (!brief && !oomOnly) {
15521                            Debug.getMemoryInfo(st.pid, mi);
15522                        } else {
15523                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15524                            mi.nativePrivateDirty = (int)tmpLong[0];
15525                        }
15526
15527                        final long myTotalPss = mi.getTotalPss();
15528                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15529                        totalPss += myTotalPss;
15530                        nativeProcTotalPss += myTotalPss;
15531
15532                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15533                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15534                        procMems.add(pssItem);
15535
15536                        nativePss += mi.nativePss;
15537                        nativeSwapPss += mi.nativeSwappedOutPss;
15538                        dalvikPss += mi.dalvikPss;
15539                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15540                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15541                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15542                            dalvikSubitemSwapPss[j] +=
15543                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15544                        }
15545                        otherPss += mi.otherPss;
15546                        otherSwapPss += mi.otherSwappedOutPss;
15547                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15548                            long mem = mi.getOtherPss(j);
15549                            miscPss[j] += mem;
15550                            otherPss -= mem;
15551                            mem = mi.getOtherSwappedOutPss(j);
15552                            miscSwapPss[j] += mem;
15553                            otherSwapPss -= mem;
15554                        }
15555                        oomPss[0] += myTotalPss;
15556                        oomSwapPss[0] += myTotalSwapPss;
15557                        if (oomProcs[0] == null) {
15558                            oomProcs[0] = new ArrayList<MemItem>();
15559                        }
15560                        oomProcs[0].add(pssItem);
15561                    }
15562                }
15563            }
15564
15565            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15566
15567            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15568            final MemItem dalvikItem =
15569                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15570            if (dalvikSubitemPss.length > 0) {
15571                dalvikItem.subitems = new ArrayList<MemItem>();
15572                for (int j=0; j<dalvikSubitemPss.length; j++) {
15573                    final String name = Debug.MemoryInfo.getOtherLabel(
15574                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15575                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15576                                    dalvikSubitemSwapPss[j], j));
15577                }
15578            }
15579            catMems.add(dalvikItem);
15580            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15581            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15582                String label = Debug.MemoryInfo.getOtherLabel(j);
15583                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15584            }
15585
15586            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15587            for (int j=0; j<oomPss.length; j++) {
15588                if (oomPss[j] != 0) {
15589                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15590                            : DUMP_MEM_OOM_LABEL[j];
15591                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15592                            DUMP_MEM_OOM_ADJ[j]);
15593                    item.subitems = oomProcs[j];
15594                    oomMems.add(item);
15595                }
15596            }
15597
15598            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15599            if (!brief && !oomOnly && !isCompact) {
15600                pw.println();
15601                pw.println("Total PSS by process:");
15602                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15603                pw.println();
15604            }
15605            if (!isCompact) {
15606                pw.println("Total PSS by OOM adjustment:");
15607            }
15608            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15609            if (!brief && !oomOnly) {
15610                PrintWriter out = categoryPw != null ? categoryPw : pw;
15611                if (!isCompact) {
15612                    out.println();
15613                    out.println("Total PSS by category:");
15614                }
15615                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15616            }
15617            if (!isCompact) {
15618                pw.println();
15619            }
15620            MemInfoReader memInfo = new MemInfoReader();
15621            memInfo.readMemInfo();
15622            if (nativeProcTotalPss > 0) {
15623                synchronized (this) {
15624                    final long cachedKb = memInfo.getCachedSizeKb();
15625                    final long freeKb = memInfo.getFreeSizeKb();
15626                    final long zramKb = memInfo.getZramTotalSizeKb();
15627                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15628                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15629                            kernelKb*1024, nativeProcTotalPss*1024);
15630                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15631                            nativeProcTotalPss);
15632                }
15633            }
15634            if (!brief) {
15635                if (!isCompact) {
15636                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15637                    pw.print(" (status ");
15638                    switch (mLastMemoryLevel) {
15639                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15640                            pw.println("normal)");
15641                            break;
15642                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15643                            pw.println("moderate)");
15644                            break;
15645                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15646                            pw.println("low)");
15647                            break;
15648                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15649                            pw.println("critical)");
15650                            break;
15651                        default:
15652                            pw.print(mLastMemoryLevel);
15653                            pw.println(")");
15654                            break;
15655                    }
15656                    pw.print(" Free RAM: ");
15657                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15658                            + memInfo.getFreeSizeKb()));
15659                    pw.print(" (");
15660                    pw.print(stringifyKBSize(cachedPss));
15661                    pw.print(" cached pss + ");
15662                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15663                    pw.print(" cached kernel + ");
15664                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15665                    pw.println(" free)");
15666                } else {
15667                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15668                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15669                            + memInfo.getFreeSizeKb()); pw.print(",");
15670                    pw.println(totalPss - cachedPss);
15671                }
15672            }
15673            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15674                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15675                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15676            if (!isCompact) {
15677                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15678                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15679                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15680                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15681                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15682            } else {
15683                pw.print("lostram,"); pw.println(lostRAM);
15684            }
15685            if (!brief) {
15686                if (memInfo.getZramTotalSizeKb() != 0) {
15687                    if (!isCompact) {
15688                        pw.print("     ZRAM: ");
15689                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15690                                pw.print(" physical used for ");
15691                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15692                                        - memInfo.getSwapFreeSizeKb()));
15693                                pw.print(" in swap (");
15694                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15695                                pw.println(" total swap)");
15696                    } else {
15697                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15698                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15699                                pw.println(memInfo.getSwapFreeSizeKb());
15700                    }
15701                }
15702                final long[] ksm = getKsmInfo();
15703                if (!isCompact) {
15704                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15705                            || ksm[KSM_VOLATILE] != 0) {
15706                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15707                                pw.print(" saved from shared ");
15708                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15709                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15710                                pw.print(" unshared; ");
15711                                pw.print(stringifyKBSize(
15712                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15713                    }
15714                    pw.print("   Tuning: ");
15715                    pw.print(ActivityManager.staticGetMemoryClass());
15716                    pw.print(" (large ");
15717                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15718                    pw.print("), oom ");
15719                    pw.print(stringifySize(
15720                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15721                    pw.print(", restore limit ");
15722                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15723                    if (ActivityManager.isLowRamDeviceStatic()) {
15724                        pw.print(" (low-ram)");
15725                    }
15726                    if (ActivityManager.isHighEndGfx()) {
15727                        pw.print(" (high-end-gfx)");
15728                    }
15729                    pw.println();
15730                } else {
15731                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15732                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15733                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15734                    pw.print("tuning,");
15735                    pw.print(ActivityManager.staticGetMemoryClass());
15736                    pw.print(',');
15737                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15738                    pw.print(',');
15739                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15740                    if (ActivityManager.isLowRamDeviceStatic()) {
15741                        pw.print(",low-ram");
15742                    }
15743                    if (ActivityManager.isHighEndGfx()) {
15744                        pw.print(",high-end-gfx");
15745                    }
15746                    pw.println();
15747                }
15748            }
15749        }
15750    }
15751
15752    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15753            long memtrack, String name) {
15754        sb.append("  ");
15755        sb.append(ProcessList.makeOomAdjString(oomAdj));
15756        sb.append(' ');
15757        sb.append(ProcessList.makeProcStateString(procState));
15758        sb.append(' ');
15759        ProcessList.appendRamKb(sb, pss);
15760        sb.append(": ");
15761        sb.append(name);
15762        if (memtrack > 0) {
15763            sb.append(" (");
15764            sb.append(stringifyKBSize(memtrack));
15765            sb.append(" memtrack)");
15766        }
15767    }
15768
15769    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15770        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15771        sb.append(" (pid ");
15772        sb.append(mi.pid);
15773        sb.append(") ");
15774        sb.append(mi.adjType);
15775        sb.append('\n');
15776        if (mi.adjReason != null) {
15777            sb.append("                      ");
15778            sb.append(mi.adjReason);
15779            sb.append('\n');
15780        }
15781    }
15782
15783    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15784        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15785        for (int i=0, N=memInfos.size(); i<N; i++) {
15786            ProcessMemInfo mi = memInfos.get(i);
15787            infoMap.put(mi.pid, mi);
15788        }
15789        updateCpuStatsNow();
15790        long[] memtrackTmp = new long[1];
15791        synchronized (mProcessCpuTracker) {
15792            final int N = mProcessCpuTracker.countStats();
15793            for (int i=0; i<N; i++) {
15794                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15795                if (st.vsize > 0) {
15796                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15797                    if (pss > 0) {
15798                        if (infoMap.indexOfKey(st.pid) < 0) {
15799                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15800                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15801                            mi.pss = pss;
15802                            mi.memtrack = memtrackTmp[0];
15803                            memInfos.add(mi);
15804                        }
15805                    }
15806                }
15807            }
15808        }
15809
15810        long totalPss = 0;
15811        long totalMemtrack = 0;
15812        for (int i=0, N=memInfos.size(); i<N; i++) {
15813            ProcessMemInfo mi = memInfos.get(i);
15814            if (mi.pss == 0) {
15815                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15816                mi.memtrack = memtrackTmp[0];
15817            }
15818            totalPss += mi.pss;
15819            totalMemtrack += mi.memtrack;
15820        }
15821        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15822            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15823                if (lhs.oomAdj != rhs.oomAdj) {
15824                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15825                }
15826                if (lhs.pss != rhs.pss) {
15827                    return lhs.pss < rhs.pss ? 1 : -1;
15828                }
15829                return 0;
15830            }
15831        });
15832
15833        StringBuilder tag = new StringBuilder(128);
15834        StringBuilder stack = new StringBuilder(128);
15835        tag.append("Low on memory -- ");
15836        appendMemBucket(tag, totalPss, "total", false);
15837        appendMemBucket(stack, totalPss, "total", true);
15838
15839        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15840        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15841        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15842
15843        boolean firstLine = true;
15844        int lastOomAdj = Integer.MIN_VALUE;
15845        long extraNativeRam = 0;
15846        long extraNativeMemtrack = 0;
15847        long cachedPss = 0;
15848        for (int i=0, N=memInfos.size(); i<N; i++) {
15849            ProcessMemInfo mi = memInfos.get(i);
15850
15851            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15852                cachedPss += mi.pss;
15853            }
15854
15855            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15856                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15857                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15858                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15859                if (lastOomAdj != mi.oomAdj) {
15860                    lastOomAdj = mi.oomAdj;
15861                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15862                        tag.append(" / ");
15863                    }
15864                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15865                        if (firstLine) {
15866                            stack.append(":");
15867                            firstLine = false;
15868                        }
15869                        stack.append("\n\t at ");
15870                    } else {
15871                        stack.append("$");
15872                    }
15873                } else {
15874                    tag.append(" ");
15875                    stack.append("$");
15876                }
15877                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15878                    appendMemBucket(tag, mi.pss, mi.name, false);
15879                }
15880                appendMemBucket(stack, mi.pss, mi.name, true);
15881                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15882                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15883                    stack.append("(");
15884                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15885                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15886                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15887                            stack.append(":");
15888                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15889                        }
15890                    }
15891                    stack.append(")");
15892                }
15893            }
15894
15895            appendMemInfo(fullNativeBuilder, mi);
15896            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15897                // The short form only has native processes that are >= 512K.
15898                if (mi.pss >= 512) {
15899                    appendMemInfo(shortNativeBuilder, mi);
15900                } else {
15901                    extraNativeRam += mi.pss;
15902                    extraNativeMemtrack += mi.memtrack;
15903                }
15904            } else {
15905                // Short form has all other details, but if we have collected RAM
15906                // from smaller native processes let's dump a summary of that.
15907                if (extraNativeRam > 0) {
15908                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15909                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15910                    shortNativeBuilder.append('\n');
15911                    extraNativeRam = 0;
15912                }
15913                appendMemInfo(fullJavaBuilder, mi);
15914            }
15915        }
15916
15917        fullJavaBuilder.append("           ");
15918        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15919        fullJavaBuilder.append(": TOTAL");
15920        if (totalMemtrack > 0) {
15921            fullJavaBuilder.append(" (");
15922            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15923            fullJavaBuilder.append(" memtrack)");
15924        } else {
15925        }
15926        fullJavaBuilder.append("\n");
15927
15928        MemInfoReader memInfo = new MemInfoReader();
15929        memInfo.readMemInfo();
15930        final long[] infos = memInfo.getRawInfo();
15931
15932        StringBuilder memInfoBuilder = new StringBuilder(1024);
15933        Debug.getMemInfo(infos);
15934        memInfoBuilder.append("  MemInfo: ");
15935        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15936        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15937        memInfoBuilder.append(stringifyKBSize(
15938                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15939        memInfoBuilder.append(stringifyKBSize(
15940                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15941        memInfoBuilder.append(stringifyKBSize(
15942                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15943        memInfoBuilder.append("           ");
15944        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15945        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15946        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15947        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15948        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15949            memInfoBuilder.append("  ZRAM: ");
15950            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15951            memInfoBuilder.append(" RAM, ");
15952            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15953            memInfoBuilder.append(" swap total, ");
15954            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15955            memInfoBuilder.append(" swap free\n");
15956        }
15957        final long[] ksm = getKsmInfo();
15958        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15959                || ksm[KSM_VOLATILE] != 0) {
15960            memInfoBuilder.append("  KSM: ");
15961            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15962            memInfoBuilder.append(" saved from shared ");
15963            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15964            memInfoBuilder.append("\n       ");
15965            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15966            memInfoBuilder.append(" unshared; ");
15967            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15968            memInfoBuilder.append(" volatile\n");
15969        }
15970        memInfoBuilder.append("  Free RAM: ");
15971        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15972                + memInfo.getFreeSizeKb()));
15973        memInfoBuilder.append("\n");
15974        memInfoBuilder.append("  Used RAM: ");
15975        memInfoBuilder.append(stringifyKBSize(
15976                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15977        memInfoBuilder.append("\n");
15978        memInfoBuilder.append("  Lost RAM: ");
15979        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15980                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15981                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
15982        memInfoBuilder.append("\n");
15983        Slog.i(TAG, "Low on memory:");
15984        Slog.i(TAG, shortNativeBuilder.toString());
15985        Slog.i(TAG, fullJavaBuilder.toString());
15986        Slog.i(TAG, memInfoBuilder.toString());
15987
15988        StringBuilder dropBuilder = new StringBuilder(1024);
15989        /*
15990        StringWriter oomSw = new StringWriter();
15991        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15992        StringWriter catSw = new StringWriter();
15993        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15994        String[] emptyArgs = new String[] { };
15995        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15996        oomPw.flush();
15997        String oomString = oomSw.toString();
15998        */
15999        dropBuilder.append("Low on memory:");
16000        dropBuilder.append(stack);
16001        dropBuilder.append('\n');
16002        dropBuilder.append(fullNativeBuilder);
16003        dropBuilder.append(fullJavaBuilder);
16004        dropBuilder.append('\n');
16005        dropBuilder.append(memInfoBuilder);
16006        dropBuilder.append('\n');
16007        /*
16008        dropBuilder.append(oomString);
16009        dropBuilder.append('\n');
16010        */
16011        StringWriter catSw = new StringWriter();
16012        synchronized (ActivityManagerService.this) {
16013            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16014            String[] emptyArgs = new String[] { };
16015            catPw.println();
16016            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16017            catPw.println();
16018            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16019                    false, false, null);
16020            catPw.println();
16021            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16022            catPw.flush();
16023        }
16024        dropBuilder.append(catSw.toString());
16025        addErrorToDropBox("lowmem", null, "system_server", null,
16026                null, tag.toString(), dropBuilder.toString(), null, null);
16027        //Slog.i(TAG, "Sent to dropbox:");
16028        //Slog.i(TAG, dropBuilder.toString());
16029        synchronized (ActivityManagerService.this) {
16030            long now = SystemClock.uptimeMillis();
16031            if (mLastMemUsageReportTime < now) {
16032                mLastMemUsageReportTime = now;
16033            }
16034        }
16035    }
16036
16037    /**
16038     * Searches array of arguments for the specified string
16039     * @param args array of argument strings
16040     * @param value value to search for
16041     * @return true if the value is contained in the array
16042     */
16043    private static boolean scanArgs(String[] args, String value) {
16044        if (args != null) {
16045            for (String arg : args) {
16046                if (value.equals(arg)) {
16047                    return true;
16048                }
16049            }
16050        }
16051        return false;
16052    }
16053
16054    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16055            ContentProviderRecord cpr, boolean always) {
16056        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16057
16058        if (!inLaunching || always) {
16059            synchronized (cpr) {
16060                cpr.launchingApp = null;
16061                cpr.notifyAll();
16062            }
16063            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16064            String names[] = cpr.info.authority.split(";");
16065            for (int j = 0; j < names.length; j++) {
16066                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16067            }
16068        }
16069
16070        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16071            ContentProviderConnection conn = cpr.connections.get(i);
16072            if (conn.waiting) {
16073                // If this connection is waiting for the provider, then we don't
16074                // need to mess with its process unless we are always removing
16075                // or for some reason the provider is not currently launching.
16076                if (inLaunching && !always) {
16077                    continue;
16078                }
16079            }
16080            ProcessRecord capp = conn.client;
16081            conn.dead = true;
16082            if (conn.stableCount > 0) {
16083                if (!capp.persistent && capp.thread != null
16084                        && capp.pid != 0
16085                        && capp.pid != MY_PID) {
16086                    capp.kill("depends on provider "
16087                            + cpr.name.flattenToShortString()
16088                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16089                }
16090            } else if (capp.thread != null && conn.provider.provider != null) {
16091                try {
16092                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16093                } catch (RemoteException e) {
16094                }
16095                // In the protocol here, we don't expect the client to correctly
16096                // clean up this connection, we'll just remove it.
16097                cpr.connections.remove(i);
16098                if (conn.client.conProviders.remove(conn)) {
16099                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16100                }
16101            }
16102        }
16103
16104        if (inLaunching && always) {
16105            mLaunchingProviders.remove(cpr);
16106        }
16107        return inLaunching;
16108    }
16109
16110    /**
16111     * Main code for cleaning up a process when it has gone away.  This is
16112     * called both as a result of the process dying, or directly when stopping
16113     * a process when running in single process mode.
16114     *
16115     * @return Returns true if the given process has been restarted, so the
16116     * app that was passed in must remain on the process lists.
16117     */
16118    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16119            boolean restarting, boolean allowRestart, int index) {
16120        if (index >= 0) {
16121            removeLruProcessLocked(app);
16122            ProcessList.remove(app.pid);
16123        }
16124
16125        mProcessesToGc.remove(app);
16126        mPendingPssProcesses.remove(app);
16127
16128        // Dismiss any open dialogs.
16129        if (app.crashDialog != null && !app.forceCrashReport) {
16130            app.crashDialog.dismiss();
16131            app.crashDialog = null;
16132        }
16133        if (app.anrDialog != null) {
16134            app.anrDialog.dismiss();
16135            app.anrDialog = null;
16136        }
16137        if (app.waitDialog != null) {
16138            app.waitDialog.dismiss();
16139            app.waitDialog = null;
16140        }
16141
16142        app.crashing = false;
16143        app.notResponding = false;
16144
16145        app.resetPackageList(mProcessStats);
16146        app.unlinkDeathRecipient();
16147        app.makeInactive(mProcessStats);
16148        app.waitingToKill = null;
16149        app.forcingToForeground = null;
16150        updateProcessForegroundLocked(app, false, false);
16151        app.foregroundActivities = false;
16152        app.hasShownUi = false;
16153        app.treatLikeActivity = false;
16154        app.hasAboveClient = false;
16155        app.hasClientActivities = false;
16156
16157        mServices.killServicesLocked(app, allowRestart);
16158
16159        boolean restart = false;
16160
16161        // Remove published content providers.
16162        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16163            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16164            final boolean always = app.bad || !allowRestart;
16165            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16166            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16167                // We left the provider in the launching list, need to
16168                // restart it.
16169                restart = true;
16170            }
16171
16172            cpr.provider = null;
16173            cpr.proc = null;
16174        }
16175        app.pubProviders.clear();
16176
16177        // Take care of any launching providers waiting for this process.
16178        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16179            restart = true;
16180        }
16181
16182        // Unregister from connected content providers.
16183        if (!app.conProviders.isEmpty()) {
16184            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16185                ContentProviderConnection conn = app.conProviders.get(i);
16186                conn.provider.connections.remove(conn);
16187                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16188                        conn.provider.name);
16189            }
16190            app.conProviders.clear();
16191        }
16192
16193        // At this point there may be remaining entries in mLaunchingProviders
16194        // where we were the only one waiting, so they are no longer of use.
16195        // Look for these and clean up if found.
16196        // XXX Commented out for now.  Trying to figure out a way to reproduce
16197        // the actual situation to identify what is actually going on.
16198        if (false) {
16199            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16200                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16201                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16202                    synchronized (cpr) {
16203                        cpr.launchingApp = null;
16204                        cpr.notifyAll();
16205                    }
16206                }
16207            }
16208        }
16209
16210        skipCurrentReceiverLocked(app);
16211
16212        // Unregister any receivers.
16213        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16214            removeReceiverLocked(app.receivers.valueAt(i));
16215        }
16216        app.receivers.clear();
16217
16218        // If the app is undergoing backup, tell the backup manager about it
16219        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16220            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16221                    + mBackupTarget.appInfo + " died during backup");
16222            try {
16223                IBackupManager bm = IBackupManager.Stub.asInterface(
16224                        ServiceManager.getService(Context.BACKUP_SERVICE));
16225                bm.agentDisconnected(app.info.packageName);
16226            } catch (RemoteException e) {
16227                // can't happen; backup manager is local
16228            }
16229        }
16230
16231        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16232            ProcessChangeItem item = mPendingProcessChanges.get(i);
16233            if (item.pid == app.pid) {
16234                mPendingProcessChanges.remove(i);
16235                mAvailProcessChanges.add(item);
16236            }
16237        }
16238        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16239                null).sendToTarget();
16240
16241        // If the caller is restarting this app, then leave it in its
16242        // current lists and let the caller take care of it.
16243        if (restarting) {
16244            return false;
16245        }
16246
16247        if (!app.persistent || app.isolated) {
16248            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16249                    "Removing non-persistent process during cleanup: " + app);
16250            removeProcessNameLocked(app.processName, app.uid);
16251            if (mHeavyWeightProcess == app) {
16252                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16253                        mHeavyWeightProcess.userId, 0));
16254                mHeavyWeightProcess = null;
16255            }
16256        } else if (!app.removed) {
16257            // This app is persistent, so we need to keep its record around.
16258            // If it is not already on the pending app list, add it there
16259            // and start a new process for it.
16260            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16261                mPersistentStartingProcesses.add(app);
16262                restart = true;
16263            }
16264        }
16265        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16266                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16267        mProcessesOnHold.remove(app);
16268
16269        if (app == mHomeProcess) {
16270            mHomeProcess = null;
16271        }
16272        if (app == mPreviousProcess) {
16273            mPreviousProcess = null;
16274        }
16275
16276        if (restart && !app.isolated) {
16277            // We have components that still need to be running in the
16278            // process, so re-launch it.
16279            if (index < 0) {
16280                ProcessList.remove(app.pid);
16281            }
16282            addProcessNameLocked(app);
16283            startProcessLocked(app, "restart", app.processName);
16284            return true;
16285        } else if (app.pid > 0 && app.pid != MY_PID) {
16286            // Goodbye!
16287            boolean removed;
16288            synchronized (mPidsSelfLocked) {
16289                mPidsSelfLocked.remove(app.pid);
16290                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16291            }
16292            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16293            if (app.isolated) {
16294                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16295            }
16296            app.setPid(0);
16297        }
16298        return false;
16299    }
16300
16301    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16302        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16303            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16304            if (cpr.launchingApp == app) {
16305                return true;
16306            }
16307        }
16308        return false;
16309    }
16310
16311    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16312        // Look through the content providers we are waiting to have launched,
16313        // and if any run in this process then either schedule a restart of
16314        // the process or kill the client waiting for it if this process has
16315        // gone bad.
16316        boolean restart = false;
16317        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16318            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16319            if (cpr.launchingApp == app) {
16320                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16321                    restart = true;
16322                } else {
16323                    removeDyingProviderLocked(app, cpr, true);
16324                }
16325            }
16326        }
16327        return restart;
16328    }
16329
16330    // =========================================================
16331    // SERVICES
16332    // =========================================================
16333
16334    @Override
16335    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16336            int flags) {
16337        enforceNotIsolatedCaller("getServices");
16338        synchronized (this) {
16339            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16340        }
16341    }
16342
16343    @Override
16344    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16345        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16346        synchronized (this) {
16347            return mServices.getRunningServiceControlPanelLocked(name);
16348        }
16349    }
16350
16351    @Override
16352    public ComponentName startService(IApplicationThread caller, Intent service,
16353            String resolvedType, String callingPackage, int userId)
16354            throws TransactionTooLargeException {
16355        enforceNotIsolatedCaller("startService");
16356        // Refuse possible leaked file descriptors
16357        if (service != null && service.hasFileDescriptors() == true) {
16358            throw new IllegalArgumentException("File descriptors passed in Intent");
16359        }
16360
16361        if (callingPackage == null) {
16362            throw new IllegalArgumentException("callingPackage cannot be null");
16363        }
16364
16365        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16366                "startService: " + service + " type=" + resolvedType);
16367        synchronized(this) {
16368            final int callingPid = Binder.getCallingPid();
16369            final int callingUid = Binder.getCallingUid();
16370            final long origId = Binder.clearCallingIdentity();
16371            ComponentName res = mServices.startServiceLocked(caller, service,
16372                    resolvedType, callingPid, callingUid, callingPackage, userId);
16373            Binder.restoreCallingIdentity(origId);
16374            return res;
16375        }
16376    }
16377
16378    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16379            String callingPackage, int userId)
16380            throws TransactionTooLargeException {
16381        synchronized(this) {
16382            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16383                    "startServiceInPackage: " + service + " type=" + resolvedType);
16384            final long origId = Binder.clearCallingIdentity();
16385            ComponentName res = mServices.startServiceLocked(null, service,
16386                    resolvedType, -1, uid, callingPackage, userId);
16387            Binder.restoreCallingIdentity(origId);
16388            return res;
16389        }
16390    }
16391
16392    @Override
16393    public int stopService(IApplicationThread caller, Intent service,
16394            String resolvedType, int userId) {
16395        enforceNotIsolatedCaller("stopService");
16396        // Refuse possible leaked file descriptors
16397        if (service != null && service.hasFileDescriptors() == true) {
16398            throw new IllegalArgumentException("File descriptors passed in Intent");
16399        }
16400
16401        synchronized(this) {
16402            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16403        }
16404    }
16405
16406    @Override
16407    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16408        enforceNotIsolatedCaller("peekService");
16409        // Refuse possible leaked file descriptors
16410        if (service != null && service.hasFileDescriptors() == true) {
16411            throw new IllegalArgumentException("File descriptors passed in Intent");
16412        }
16413
16414        if (callingPackage == null) {
16415            throw new IllegalArgumentException("callingPackage cannot be null");
16416        }
16417
16418        synchronized(this) {
16419            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16420        }
16421    }
16422
16423    @Override
16424    public boolean stopServiceToken(ComponentName className, IBinder token,
16425            int startId) {
16426        synchronized(this) {
16427            return mServices.stopServiceTokenLocked(className, token, startId);
16428        }
16429    }
16430
16431    @Override
16432    public void setServiceForeground(ComponentName className, IBinder token,
16433            int id, Notification notification, boolean removeNotification) {
16434        synchronized(this) {
16435            mServices.setServiceForegroundLocked(className, token, id, notification,
16436                    removeNotification);
16437        }
16438    }
16439
16440    @Override
16441    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16442            boolean requireFull, String name, String callerPackage) {
16443        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16444                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16445    }
16446
16447    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16448            String className, int flags) {
16449        boolean result = false;
16450        // For apps that don't have pre-defined UIDs, check for permission
16451        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16452            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16453                if (ActivityManager.checkUidPermission(
16454                        INTERACT_ACROSS_USERS,
16455                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16456                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16457                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16458                            + " requests FLAG_SINGLE_USER, but app does not hold "
16459                            + INTERACT_ACROSS_USERS;
16460                    Slog.w(TAG, msg);
16461                    throw new SecurityException(msg);
16462                }
16463                // Permission passed
16464                result = true;
16465            }
16466        } else if ("system".equals(componentProcessName)) {
16467            result = true;
16468        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16469            // Phone app and persistent apps are allowed to export singleuser providers.
16470            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16471                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16472        }
16473        if (DEBUG_MU) Slog.v(TAG_MU,
16474                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16475                + Integer.toHexString(flags) + ") = " + result);
16476        return result;
16477    }
16478
16479    /**
16480     * Checks to see if the caller is in the same app as the singleton
16481     * component, or the component is in a special app. It allows special apps
16482     * to export singleton components but prevents exporting singleton
16483     * components for regular apps.
16484     */
16485    boolean isValidSingletonCall(int callingUid, int componentUid) {
16486        int componentAppId = UserHandle.getAppId(componentUid);
16487        return UserHandle.isSameApp(callingUid, componentUid)
16488                || componentAppId == Process.SYSTEM_UID
16489                || componentAppId == Process.PHONE_UID
16490                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16491                        == PackageManager.PERMISSION_GRANTED;
16492    }
16493
16494    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16495            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16496            int userId) throws TransactionTooLargeException {
16497        enforceNotIsolatedCaller("bindService");
16498
16499        // Refuse possible leaked file descriptors
16500        if (service != null && service.hasFileDescriptors() == true) {
16501            throw new IllegalArgumentException("File descriptors passed in Intent");
16502        }
16503
16504        if (callingPackage == null) {
16505            throw new IllegalArgumentException("callingPackage cannot be null");
16506        }
16507
16508        synchronized(this) {
16509            return mServices.bindServiceLocked(caller, token, service,
16510                    resolvedType, connection, flags, callingPackage, userId);
16511        }
16512    }
16513
16514    public boolean unbindService(IServiceConnection connection) {
16515        synchronized (this) {
16516            return mServices.unbindServiceLocked(connection);
16517        }
16518    }
16519
16520    public void publishService(IBinder token, Intent intent, IBinder service) {
16521        // Refuse possible leaked file descriptors
16522        if (intent != null && intent.hasFileDescriptors() == true) {
16523            throw new IllegalArgumentException("File descriptors passed in Intent");
16524        }
16525
16526        synchronized(this) {
16527            if (!(token instanceof ServiceRecord)) {
16528                throw new IllegalArgumentException("Invalid service token");
16529            }
16530            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16531        }
16532    }
16533
16534    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16535        // Refuse possible leaked file descriptors
16536        if (intent != null && intent.hasFileDescriptors() == true) {
16537            throw new IllegalArgumentException("File descriptors passed in Intent");
16538        }
16539
16540        synchronized(this) {
16541            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16542        }
16543    }
16544
16545    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16546        synchronized(this) {
16547            if (!(token instanceof ServiceRecord)) {
16548                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16549                throw new IllegalArgumentException("Invalid service token");
16550            }
16551            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16552        }
16553    }
16554
16555    // =========================================================
16556    // BACKUP AND RESTORE
16557    // =========================================================
16558
16559    // Cause the target app to be launched if necessary and its backup agent
16560    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16561    // activity manager to announce its creation.
16562    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16563        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16564                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16565        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16566
16567        synchronized(this) {
16568            // !!! TODO: currently no check here that we're already bound
16569            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16570            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16571            synchronized (stats) {
16572                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16573            }
16574
16575            // Backup agent is now in use, its package can't be stopped.
16576            try {
16577                AppGlobals.getPackageManager().setPackageStoppedState(
16578                        app.packageName, false, UserHandle.getUserId(app.uid));
16579            } catch (RemoteException e) {
16580            } catch (IllegalArgumentException e) {
16581                Slog.w(TAG, "Failed trying to unstop package "
16582                        + app.packageName + ": " + e);
16583            }
16584
16585            BackupRecord r = new BackupRecord(ss, app, backupMode);
16586            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16587                    ? new ComponentName(app.packageName, app.backupAgentName)
16588                    : new ComponentName("android", "FullBackupAgent");
16589            // startProcessLocked() returns existing proc's record if it's already running
16590            ProcessRecord proc = startProcessLocked(app.processName, app,
16591                    false, 0, "backup", hostingName, false, false, false);
16592            if (proc == null) {
16593                Slog.e(TAG, "Unable to start backup agent process " + r);
16594                return false;
16595            }
16596
16597            r.app = proc;
16598            mBackupTarget = r;
16599            mBackupAppName = app.packageName;
16600
16601            // Try not to kill the process during backup
16602            updateOomAdjLocked(proc);
16603
16604            // If the process is already attached, schedule the creation of the backup agent now.
16605            // If it is not yet live, this will be done when it attaches to the framework.
16606            if (proc.thread != null) {
16607                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16608                try {
16609                    proc.thread.scheduleCreateBackupAgent(app,
16610                            compatibilityInfoForPackageLocked(app), backupMode);
16611                } catch (RemoteException e) {
16612                    // Will time out on the backup manager side
16613                }
16614            } else {
16615                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16616            }
16617            // Invariants: at this point, the target app process exists and the application
16618            // is either already running or in the process of coming up.  mBackupTarget and
16619            // mBackupAppName describe the app, so that when it binds back to the AM we
16620            // know that it's scheduled for a backup-agent operation.
16621        }
16622
16623        return true;
16624    }
16625
16626    @Override
16627    public void clearPendingBackup() {
16628        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16629        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16630
16631        synchronized (this) {
16632            mBackupTarget = null;
16633            mBackupAppName = null;
16634        }
16635    }
16636
16637    // A backup agent has just come up
16638    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16639        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16640                + " = " + agent);
16641
16642        synchronized(this) {
16643            if (!agentPackageName.equals(mBackupAppName)) {
16644                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16645                return;
16646            }
16647        }
16648
16649        long oldIdent = Binder.clearCallingIdentity();
16650        try {
16651            IBackupManager bm = IBackupManager.Stub.asInterface(
16652                    ServiceManager.getService(Context.BACKUP_SERVICE));
16653            bm.agentConnected(agentPackageName, agent);
16654        } catch (RemoteException e) {
16655            // can't happen; the backup manager service is local
16656        } catch (Exception e) {
16657            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16658            e.printStackTrace();
16659        } finally {
16660            Binder.restoreCallingIdentity(oldIdent);
16661        }
16662    }
16663
16664    // done with this agent
16665    public void unbindBackupAgent(ApplicationInfo appInfo) {
16666        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16667        if (appInfo == null) {
16668            Slog.w(TAG, "unbind backup agent for null app");
16669            return;
16670        }
16671
16672        synchronized(this) {
16673            try {
16674                if (mBackupAppName == null) {
16675                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16676                    return;
16677                }
16678
16679                if (!mBackupAppName.equals(appInfo.packageName)) {
16680                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16681                    return;
16682                }
16683
16684                // Not backing this app up any more; reset its OOM adjustment
16685                final ProcessRecord proc = mBackupTarget.app;
16686                updateOomAdjLocked(proc);
16687
16688                // If the app crashed during backup, 'thread' will be null here
16689                if (proc.thread != null) {
16690                    try {
16691                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16692                                compatibilityInfoForPackageLocked(appInfo));
16693                    } catch (Exception e) {
16694                        Slog.e(TAG, "Exception when unbinding backup agent:");
16695                        e.printStackTrace();
16696                    }
16697                }
16698            } finally {
16699                mBackupTarget = null;
16700                mBackupAppName = null;
16701            }
16702        }
16703    }
16704    // =========================================================
16705    // BROADCASTS
16706    // =========================================================
16707
16708    boolean isPendingBroadcastProcessLocked(int pid) {
16709        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16710                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16711    }
16712
16713    void skipPendingBroadcastLocked(int pid) {
16714            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16715            for (BroadcastQueue queue : mBroadcastQueues) {
16716                queue.skipPendingBroadcastLocked(pid);
16717            }
16718    }
16719
16720    // The app just attached; send any pending broadcasts that it should receive
16721    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16722        boolean didSomething = false;
16723        for (BroadcastQueue queue : mBroadcastQueues) {
16724            didSomething |= queue.sendPendingBroadcastsLocked(app);
16725        }
16726        return didSomething;
16727    }
16728
16729    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16730            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16731        enforceNotIsolatedCaller("registerReceiver");
16732        ArrayList<Intent> stickyIntents = null;
16733        ProcessRecord callerApp = null;
16734        int callingUid;
16735        int callingPid;
16736        synchronized(this) {
16737            if (caller != null) {
16738                callerApp = getRecordForAppLocked(caller);
16739                if (callerApp == null) {
16740                    throw new SecurityException(
16741                            "Unable to find app for caller " + caller
16742                            + " (pid=" + Binder.getCallingPid()
16743                            + ") when registering receiver " + receiver);
16744                }
16745                if (callerApp.info.uid != Process.SYSTEM_UID &&
16746                        !callerApp.pkgList.containsKey(callerPackage) &&
16747                        !"android".equals(callerPackage)) {
16748                    throw new SecurityException("Given caller package " + callerPackage
16749                            + " is not running in process " + callerApp);
16750                }
16751                callingUid = callerApp.info.uid;
16752                callingPid = callerApp.pid;
16753            } else {
16754                callerPackage = null;
16755                callingUid = Binder.getCallingUid();
16756                callingPid = Binder.getCallingPid();
16757            }
16758
16759            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16760                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16761
16762            Iterator<String> actions = filter.actionsIterator();
16763            if (actions == null) {
16764                ArrayList<String> noAction = new ArrayList<String>(1);
16765                noAction.add(null);
16766                actions = noAction.iterator();
16767            }
16768
16769            // Collect stickies of users
16770            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16771            while (actions.hasNext()) {
16772                String action = actions.next();
16773                for (int id : userIds) {
16774                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16775                    if (stickies != null) {
16776                        ArrayList<Intent> intents = stickies.get(action);
16777                        if (intents != null) {
16778                            if (stickyIntents == null) {
16779                                stickyIntents = new ArrayList<Intent>();
16780                            }
16781                            stickyIntents.addAll(intents);
16782                        }
16783                    }
16784                }
16785            }
16786        }
16787
16788        ArrayList<Intent> allSticky = null;
16789        if (stickyIntents != null) {
16790            final ContentResolver resolver = mContext.getContentResolver();
16791            // Look for any matching sticky broadcasts...
16792            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16793                Intent intent = stickyIntents.get(i);
16794                // If intent has scheme "content", it will need to acccess
16795                // provider that needs to lock mProviderMap in ActivityThread
16796                // and also it may need to wait application response, so we
16797                // cannot lock ActivityManagerService here.
16798                if (filter.match(resolver, intent, true, TAG) >= 0) {
16799                    if (allSticky == null) {
16800                        allSticky = new ArrayList<Intent>();
16801                    }
16802                    allSticky.add(intent);
16803                }
16804            }
16805        }
16806
16807        // The first sticky in the list is returned directly back to the client.
16808        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16809        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16810        if (receiver == null) {
16811            return sticky;
16812        }
16813
16814        synchronized (this) {
16815            if (callerApp != null && (callerApp.thread == null
16816                    || callerApp.thread.asBinder() != caller.asBinder())) {
16817                // Original caller already died
16818                return null;
16819            }
16820            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16821            if (rl == null) {
16822                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16823                        userId, receiver);
16824                if (rl.app != null) {
16825                    rl.app.receivers.add(rl);
16826                } else {
16827                    try {
16828                        receiver.asBinder().linkToDeath(rl, 0);
16829                    } catch (RemoteException e) {
16830                        return sticky;
16831                    }
16832                    rl.linkedToDeath = true;
16833                }
16834                mRegisteredReceivers.put(receiver.asBinder(), rl);
16835            } else if (rl.uid != callingUid) {
16836                throw new IllegalArgumentException(
16837                        "Receiver requested to register for uid " + callingUid
16838                        + " was previously registered for uid " + rl.uid);
16839            } else if (rl.pid != callingPid) {
16840                throw new IllegalArgumentException(
16841                        "Receiver requested to register for pid " + callingPid
16842                        + " was previously registered for pid " + rl.pid);
16843            } else if (rl.userId != userId) {
16844                throw new IllegalArgumentException(
16845                        "Receiver requested to register for user " + userId
16846                        + " was previously registered for user " + rl.userId);
16847            }
16848            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16849                    permission, callingUid, userId);
16850            rl.add(bf);
16851            if (!bf.debugCheck()) {
16852                Slog.w(TAG, "==> For Dynamic broadcast");
16853            }
16854            mReceiverResolver.addFilter(bf);
16855
16856            // Enqueue broadcasts for all existing stickies that match
16857            // this filter.
16858            if (allSticky != null) {
16859                ArrayList receivers = new ArrayList();
16860                receivers.add(bf);
16861
16862                final int stickyCount = allSticky.size();
16863                for (int i = 0; i < stickyCount; i++) {
16864                    Intent intent = allSticky.get(i);
16865                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16866                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16867                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16868                            null, 0, null, null, false, true, true, -1);
16869                    queue.enqueueParallelBroadcastLocked(r);
16870                    queue.scheduleBroadcastsLocked();
16871                }
16872            }
16873
16874            return sticky;
16875        }
16876    }
16877
16878    public void unregisterReceiver(IIntentReceiver receiver) {
16879        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16880
16881        final long origId = Binder.clearCallingIdentity();
16882        try {
16883            boolean doTrim = false;
16884
16885            synchronized(this) {
16886                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16887                if (rl != null) {
16888                    final BroadcastRecord r = rl.curBroadcast;
16889                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16890                        final boolean doNext = r.queue.finishReceiverLocked(
16891                                r, r.resultCode, r.resultData, r.resultExtras,
16892                                r.resultAbort, false);
16893                        if (doNext) {
16894                            doTrim = true;
16895                            r.queue.processNextBroadcast(false);
16896                        }
16897                    }
16898
16899                    if (rl.app != null) {
16900                        rl.app.receivers.remove(rl);
16901                    }
16902                    removeReceiverLocked(rl);
16903                    if (rl.linkedToDeath) {
16904                        rl.linkedToDeath = false;
16905                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16906                    }
16907                }
16908            }
16909
16910            // If we actually concluded any broadcasts, we might now be able
16911            // to trim the recipients' apps from our working set
16912            if (doTrim) {
16913                trimApplications();
16914                return;
16915            }
16916
16917        } finally {
16918            Binder.restoreCallingIdentity(origId);
16919        }
16920    }
16921
16922    void removeReceiverLocked(ReceiverList rl) {
16923        mRegisteredReceivers.remove(rl.receiver.asBinder());
16924        for (int i = rl.size() - 1; i >= 0; i--) {
16925            mReceiverResolver.removeFilter(rl.get(i));
16926        }
16927    }
16928
16929    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16930        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16931            ProcessRecord r = mLruProcesses.get(i);
16932            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16933                try {
16934                    r.thread.dispatchPackageBroadcast(cmd, packages);
16935                } catch (RemoteException ex) {
16936                }
16937            }
16938        }
16939    }
16940
16941    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16942            int callingUid, int[] users) {
16943        // TODO: come back and remove this assumption to triage all broadcasts
16944        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16945
16946        List<ResolveInfo> receivers = null;
16947        try {
16948            HashSet<ComponentName> singleUserReceivers = null;
16949            boolean scannedFirstReceivers = false;
16950            for (int user : users) {
16951                // Skip users that have Shell restrictions, with exception of always permitted
16952                // Shell broadcasts
16953                if (callingUid == Process.SHELL_UID
16954                        && mUserController.hasUserRestriction(
16955                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
16956                        && !isPermittedShellBroadcast(intent)) {
16957                    continue;
16958                }
16959                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16960                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
16961                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16962                    // If this is not the system user, we need to check for
16963                    // any receivers that should be filtered out.
16964                    for (int i=0; i<newReceivers.size(); i++) {
16965                        ResolveInfo ri = newReceivers.get(i);
16966                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16967                            newReceivers.remove(i);
16968                            i--;
16969                        }
16970                    }
16971                }
16972                if (newReceivers != null && newReceivers.size() == 0) {
16973                    newReceivers = null;
16974                }
16975                if (receivers == null) {
16976                    receivers = newReceivers;
16977                } else if (newReceivers != null) {
16978                    // We need to concatenate the additional receivers
16979                    // found with what we have do far.  This would be easy,
16980                    // but we also need to de-dup any receivers that are
16981                    // singleUser.
16982                    if (!scannedFirstReceivers) {
16983                        // Collect any single user receivers we had already retrieved.
16984                        scannedFirstReceivers = true;
16985                        for (int i=0; i<receivers.size(); i++) {
16986                            ResolveInfo ri = receivers.get(i);
16987                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16988                                ComponentName cn = new ComponentName(
16989                                        ri.activityInfo.packageName, ri.activityInfo.name);
16990                                if (singleUserReceivers == null) {
16991                                    singleUserReceivers = new HashSet<ComponentName>();
16992                                }
16993                                singleUserReceivers.add(cn);
16994                            }
16995                        }
16996                    }
16997                    // Add the new results to the existing results, tracking
16998                    // and de-dupping single user receivers.
16999                    for (int i=0; i<newReceivers.size(); i++) {
17000                        ResolveInfo ri = newReceivers.get(i);
17001                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17002                            ComponentName cn = new ComponentName(
17003                                    ri.activityInfo.packageName, ri.activityInfo.name);
17004                            if (singleUserReceivers == null) {
17005                                singleUserReceivers = new HashSet<ComponentName>();
17006                            }
17007                            if (!singleUserReceivers.contains(cn)) {
17008                                singleUserReceivers.add(cn);
17009                                receivers.add(ri);
17010                            }
17011                        } else {
17012                            receivers.add(ri);
17013                        }
17014                    }
17015                }
17016            }
17017        } catch (RemoteException ex) {
17018            // pm is in same process, this will never happen.
17019        }
17020        return receivers;
17021    }
17022
17023    private boolean isPermittedShellBroadcast(Intent intent) {
17024        // remote bugreport should always be allowed to be taken
17025        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17026    }
17027
17028    final int broadcastIntentLocked(ProcessRecord callerApp,
17029            String callerPackage, Intent intent, String resolvedType,
17030            IIntentReceiver resultTo, int resultCode, String resultData,
17031            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17032            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17033        intent = new Intent(intent);
17034
17035        // By default broadcasts do not go to stopped apps.
17036        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17037
17038        // If we have not finished booting, don't allow this to launch new processes.
17039        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17040            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17041        }
17042
17043        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17044                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17045                + " ordered=" + ordered + " userid=" + userId);
17046        if ((resultTo != null) && !ordered) {
17047            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17048        }
17049
17050        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17051                ALLOW_NON_FULL, "broadcast", callerPackage);
17052
17053        // Make sure that the user who is receiving this broadcast is running.
17054        // If not, we will just skip it. Make an exception for shutdown broadcasts
17055        // and upgrade steps.
17056
17057        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17058            if ((callingUid != Process.SYSTEM_UID
17059                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17060                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17061                Slog.w(TAG, "Skipping broadcast of " + intent
17062                        + ": user " + userId + " is stopped");
17063                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17064            }
17065        }
17066
17067        BroadcastOptions brOptions = null;
17068        if (bOptions != null) {
17069            brOptions = new BroadcastOptions(bOptions);
17070            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17071                // See if the caller is allowed to do this.  Note we are checking against
17072                // the actual real caller (not whoever provided the operation as say a
17073                // PendingIntent), because that who is actually supplied the arguments.
17074                if (checkComponentPermission(
17075                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17076                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17077                        != PackageManager.PERMISSION_GRANTED) {
17078                    String msg = "Permission Denial: " + intent.getAction()
17079                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17080                            + ", uid=" + callingUid + ")"
17081                            + " requires "
17082                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17083                    Slog.w(TAG, msg);
17084                    throw new SecurityException(msg);
17085                }
17086            }
17087        }
17088
17089        // Verify that protected broadcasts are only being sent by system code,
17090        // and that system code is only sending protected broadcasts.
17091        final String action = intent.getAction();
17092        final boolean isProtectedBroadcast;
17093        try {
17094            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17095        } catch (RemoteException e) {
17096            Slog.w(TAG, "Remote exception", e);
17097            return ActivityManager.BROADCAST_SUCCESS;
17098        }
17099
17100        final boolean isCallerSystem;
17101        switch (UserHandle.getAppId(callingUid)) {
17102            case Process.ROOT_UID:
17103            case Process.SYSTEM_UID:
17104            case Process.PHONE_UID:
17105            case Process.BLUETOOTH_UID:
17106            case Process.NFC_UID:
17107                isCallerSystem = true;
17108                break;
17109            default:
17110                isCallerSystem = (callerApp != null) && callerApp.persistent;
17111                break;
17112        }
17113
17114        if (isCallerSystem) {
17115            if (isProtectedBroadcast
17116                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17117                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17118                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17119                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17120                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17121                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17122                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17123                // Broadcast is either protected, or it's a public action that
17124                // we've relaxed, so it's fine for system internals to send.
17125            } else {
17126                // The vast majority of broadcasts sent from system internals
17127                // should be protected to avoid security holes, so yell loudly
17128                // to ensure we examine these cases.
17129                Log.wtf(TAG, "Sending non-protected broadcast " + action
17130                        + " from system", new Throwable());
17131            }
17132
17133        } else {
17134            if (isProtectedBroadcast) {
17135                String msg = "Permission Denial: not allowed to send broadcast "
17136                        + action + " from pid="
17137                        + callingPid + ", uid=" + callingUid;
17138                Slog.w(TAG, msg);
17139                throw new SecurityException(msg);
17140
17141            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17142                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17143                // Special case for compatibility: we don't want apps to send this,
17144                // but historically it has not been protected and apps may be using it
17145                // to poke their own app widget.  So, instead of making it protected,
17146                // just limit it to the caller.
17147                if (callerPackage == null) {
17148                    String msg = "Permission Denial: not allowed to send broadcast "
17149                            + action + " from unknown caller.";
17150                    Slog.w(TAG, msg);
17151                    throw new SecurityException(msg);
17152                } else if (intent.getComponent() != null) {
17153                    // They are good enough to send to an explicit component...  verify
17154                    // it is being sent to the calling app.
17155                    if (!intent.getComponent().getPackageName().equals(
17156                            callerPackage)) {
17157                        String msg = "Permission Denial: not allowed to send broadcast "
17158                                + action + " to "
17159                                + intent.getComponent().getPackageName() + " from "
17160                                + callerPackage;
17161                        Slog.w(TAG, msg);
17162                        throw new SecurityException(msg);
17163                    }
17164                } else {
17165                    // Limit broadcast to their own package.
17166                    intent.setPackage(callerPackage);
17167                }
17168            }
17169        }
17170
17171        if (action != null) {
17172            switch (action) {
17173                case Intent.ACTION_UID_REMOVED:
17174                case Intent.ACTION_PACKAGE_REMOVED:
17175                case Intent.ACTION_PACKAGE_CHANGED:
17176                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17177                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17178                case Intent.ACTION_PACKAGES_SUSPENDED:
17179                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17180                    // Handle special intents: if this broadcast is from the package
17181                    // manager about a package being removed, we need to remove all of
17182                    // its activities from the history stack.
17183                    if (checkComponentPermission(
17184                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17185                            callingPid, callingUid, -1, true)
17186                            != PackageManager.PERMISSION_GRANTED) {
17187                        String msg = "Permission Denial: " + intent.getAction()
17188                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17189                                + ", uid=" + callingUid + ")"
17190                                + " requires "
17191                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17192                        Slog.w(TAG, msg);
17193                        throw new SecurityException(msg);
17194                    }
17195                    switch (action) {
17196                        case Intent.ACTION_UID_REMOVED:
17197                            final Bundle intentExtras = intent.getExtras();
17198                            final int uid = intentExtras != null
17199                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17200                            if (uid >= 0) {
17201                                mBatteryStatsService.removeUid(uid);
17202                                mAppOpsService.uidRemoved(uid);
17203                            }
17204                            break;
17205                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17206                            // If resources are unavailable just force stop all those packages
17207                            // and flush the attribute cache as well.
17208                            String list[] =
17209                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17210                            if (list != null && list.length > 0) {
17211                                for (int i = 0; i < list.length; i++) {
17212                                    forceStopPackageLocked(list[i], -1, false, true, true,
17213                                            false, false, userId, "storage unmount");
17214                                }
17215                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17216                                sendPackageBroadcastLocked(
17217                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17218                                        userId);
17219                            }
17220                            break;
17221                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17222                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17223                            break;
17224                        case Intent.ACTION_PACKAGE_REMOVED:
17225                        case Intent.ACTION_PACKAGE_CHANGED:
17226                            Uri data = intent.getData();
17227                            String ssp;
17228                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17229                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17230                                final boolean replacing =
17231                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17232                                final boolean killProcess =
17233                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17234                                final boolean fullUninstall = removed && !replacing;
17235                                if (killProcess) {
17236                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17237                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17238                                            false, true, true, false, fullUninstall, userId,
17239                                            removed ? "pkg removed" : "pkg changed");
17240                                }
17241                                if (removed) {
17242                                    final int cmd = killProcess
17243                                            ? IApplicationThread.PACKAGE_REMOVED
17244                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17245                                    sendPackageBroadcastLocked(cmd,
17246                                            new String[] {ssp}, userId);
17247                                    if (fullUninstall) {
17248                                        mAppOpsService.packageRemoved(
17249                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17250
17251                                        // Remove all permissions granted from/to this package
17252                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17253
17254                                        removeTasksByPackageNameLocked(ssp, userId);
17255                                        mBatteryStatsService.notePackageUninstalled(ssp);
17256                                    }
17257                                } else {
17258                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17259                                            intent.getStringArrayExtra(
17260                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17261                                }
17262                            }
17263                            break;
17264                        case Intent.ACTION_PACKAGES_SUSPENDED:
17265                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17266                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17267                                    intent.getAction());
17268                            final String[] packageNames = intent.getStringArrayExtra(
17269                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17270                            final int userHandle = intent.getIntExtra(
17271                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17272
17273                            synchronized(ActivityManagerService.this) {
17274                                mRecentTasks.onPackagesSuspendedChanged(
17275                                        packageNames, suspended, userHandle);
17276                            }
17277                            break;
17278                    }
17279                    break;
17280                case Intent.ACTION_PACKAGE_REPLACED:
17281                {
17282                    final Uri data = intent.getData();
17283                    final String ssp;
17284                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17285                        final ApplicationInfo aInfo =
17286                                getPackageManagerInternalLocked().getApplicationInfo(
17287                                        ssp,
17288                                        userId);
17289                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17290                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17291                                new String[] {ssp}, userId);
17292                    }
17293                    break;
17294                }
17295                case Intent.ACTION_PACKAGE_ADDED:
17296                {
17297                    // Special case for adding a package: by default turn on compatibility mode.
17298                    Uri data = intent.getData();
17299                    String ssp;
17300                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17301                        final boolean replacing =
17302                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17303                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17304
17305                        try {
17306                            ApplicationInfo ai = AppGlobals.getPackageManager().
17307                                    getApplicationInfo(ssp, 0, 0);
17308                            mBatteryStatsService.notePackageInstalled(ssp,
17309                                    ai != null ? ai.versionCode : 0);
17310                        } catch (RemoteException e) {
17311                        }
17312                    }
17313                    break;
17314                }
17315                case Intent.ACTION_TIMEZONE_CHANGED:
17316                    // If this is the time zone changed action, queue up a message that will reset
17317                    // the timezone of all currently running processes. This message will get
17318                    // queued up before the broadcast happens.
17319                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17320                    break;
17321                case Intent.ACTION_TIME_CHANGED:
17322                    // If the user set the time, let all running processes know.
17323                    final int is24Hour =
17324                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17325                                    : 0;
17326                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17327                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17328                    synchronized (stats) {
17329                        stats.noteCurrentTimeChangedLocked();
17330                    }
17331                    break;
17332                case Intent.ACTION_CLEAR_DNS_CACHE:
17333                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17334                    break;
17335                case Proxy.PROXY_CHANGE_ACTION:
17336                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17337                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17338                    break;
17339                case android.hardware.Camera.ACTION_NEW_PICTURE:
17340                case android.hardware.Camera.ACTION_NEW_VIDEO:
17341                    // These broadcasts are no longer allowed by the system, since they can
17342                    // cause significant thrashing at a crictical point (using the camera).
17343                    // Apps should use JobScehduler to monitor for media provider changes.
17344                    Slog.w(TAG, action + " no longer allowed; dropping from "
17345                            + UserHandle.formatUid(callingUid));
17346                    // Lie; we don't want to crash the app.
17347                    return ActivityManager.BROADCAST_SUCCESS;
17348            }
17349        }
17350
17351        // Add to the sticky list if requested.
17352        if (sticky) {
17353            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17354                    callingPid, callingUid)
17355                    != PackageManager.PERMISSION_GRANTED) {
17356                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17357                        + callingPid + ", uid=" + callingUid
17358                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17359                Slog.w(TAG, msg);
17360                throw new SecurityException(msg);
17361            }
17362            if (requiredPermissions != null && requiredPermissions.length > 0) {
17363                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17364                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17365                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17366            }
17367            if (intent.getComponent() != null) {
17368                throw new SecurityException(
17369                        "Sticky broadcasts can't target a specific component");
17370            }
17371            // We use userId directly here, since the "all" target is maintained
17372            // as a separate set of sticky broadcasts.
17373            if (userId != UserHandle.USER_ALL) {
17374                // But first, if this is not a broadcast to all users, then
17375                // make sure it doesn't conflict with an existing broadcast to
17376                // all users.
17377                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17378                        UserHandle.USER_ALL);
17379                if (stickies != null) {
17380                    ArrayList<Intent> list = stickies.get(intent.getAction());
17381                    if (list != null) {
17382                        int N = list.size();
17383                        int i;
17384                        for (i=0; i<N; i++) {
17385                            if (intent.filterEquals(list.get(i))) {
17386                                throw new IllegalArgumentException(
17387                                        "Sticky broadcast " + intent + " for user "
17388                                        + userId + " conflicts with existing global broadcast");
17389                            }
17390                        }
17391                    }
17392                }
17393            }
17394            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17395            if (stickies == null) {
17396                stickies = new ArrayMap<>();
17397                mStickyBroadcasts.put(userId, stickies);
17398            }
17399            ArrayList<Intent> list = stickies.get(intent.getAction());
17400            if (list == null) {
17401                list = new ArrayList<>();
17402                stickies.put(intent.getAction(), list);
17403            }
17404            final int stickiesCount = list.size();
17405            int i;
17406            for (i = 0; i < stickiesCount; i++) {
17407                if (intent.filterEquals(list.get(i))) {
17408                    // This sticky already exists, replace it.
17409                    list.set(i, new Intent(intent));
17410                    break;
17411                }
17412            }
17413            if (i >= stickiesCount) {
17414                list.add(new Intent(intent));
17415            }
17416        }
17417
17418        int[] users;
17419        if (userId == UserHandle.USER_ALL) {
17420            // Caller wants broadcast to go to all started users.
17421            users = mUserController.getStartedUserArrayLocked();
17422        } else {
17423            // Caller wants broadcast to go to one specific user.
17424            users = new int[] {userId};
17425        }
17426
17427        // Figure out who all will receive this broadcast.
17428        List receivers = null;
17429        List<BroadcastFilter> registeredReceivers = null;
17430        // Need to resolve the intent to interested receivers...
17431        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17432                 == 0) {
17433            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17434        }
17435        if (intent.getComponent() == null) {
17436            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17437                // Query one target user at a time, excluding shell-restricted users
17438                for (int i = 0; i < users.length; i++) {
17439                    if (mUserController.hasUserRestriction(
17440                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17441                        continue;
17442                    }
17443                    List<BroadcastFilter> registeredReceiversForUser =
17444                            mReceiverResolver.queryIntent(intent,
17445                                    resolvedType, false, users[i]);
17446                    if (registeredReceivers == null) {
17447                        registeredReceivers = registeredReceiversForUser;
17448                    } else if (registeredReceiversForUser != null) {
17449                        registeredReceivers.addAll(registeredReceiversForUser);
17450                    }
17451                }
17452            } else {
17453                registeredReceivers = mReceiverResolver.queryIntent(intent,
17454                        resolvedType, false, userId);
17455            }
17456        }
17457
17458        final boolean replacePending =
17459                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17460
17461        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17462                + " replacePending=" + replacePending);
17463
17464        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17465        if (!ordered && NR > 0) {
17466            // If we are not serializing this broadcast, then send the
17467            // registered receivers separately so they don't wait for the
17468            // components to be launched.
17469            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17470            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17471                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17472                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17473                    resultExtras, ordered, sticky, false, userId);
17474            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17475            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17476            if (!replaced) {
17477                queue.enqueueParallelBroadcastLocked(r);
17478                queue.scheduleBroadcastsLocked();
17479            }
17480            registeredReceivers = null;
17481            NR = 0;
17482        }
17483
17484        // Merge into one list.
17485        int ir = 0;
17486        if (receivers != null) {
17487            // A special case for PACKAGE_ADDED: do not allow the package
17488            // being added to see this broadcast.  This prevents them from
17489            // using this as a back door to get run as soon as they are
17490            // installed.  Maybe in the future we want to have a special install
17491            // broadcast or such for apps, but we'd like to deliberately make
17492            // this decision.
17493            String skipPackages[] = null;
17494            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17495                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17496                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17497                Uri data = intent.getData();
17498                if (data != null) {
17499                    String pkgName = data.getSchemeSpecificPart();
17500                    if (pkgName != null) {
17501                        skipPackages = new String[] { pkgName };
17502                    }
17503                }
17504            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17505                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17506            }
17507            if (skipPackages != null && (skipPackages.length > 0)) {
17508                for (String skipPackage : skipPackages) {
17509                    if (skipPackage != null) {
17510                        int NT = receivers.size();
17511                        for (int it=0; it<NT; it++) {
17512                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17513                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17514                                receivers.remove(it);
17515                                it--;
17516                                NT--;
17517                            }
17518                        }
17519                    }
17520                }
17521            }
17522
17523            int NT = receivers != null ? receivers.size() : 0;
17524            int it = 0;
17525            ResolveInfo curt = null;
17526            BroadcastFilter curr = null;
17527            while (it < NT && ir < NR) {
17528                if (curt == null) {
17529                    curt = (ResolveInfo)receivers.get(it);
17530                }
17531                if (curr == null) {
17532                    curr = registeredReceivers.get(ir);
17533                }
17534                if (curr.getPriority() >= curt.priority) {
17535                    // Insert this broadcast record into the final list.
17536                    receivers.add(it, curr);
17537                    ir++;
17538                    curr = null;
17539                    it++;
17540                    NT++;
17541                } else {
17542                    // Skip to the next ResolveInfo in the final list.
17543                    it++;
17544                    curt = null;
17545                }
17546            }
17547        }
17548        while (ir < NR) {
17549            if (receivers == null) {
17550                receivers = new ArrayList();
17551            }
17552            receivers.add(registeredReceivers.get(ir));
17553            ir++;
17554        }
17555
17556        if ((receivers != null && receivers.size() > 0)
17557                || resultTo != null) {
17558            BroadcastQueue queue = broadcastQueueForIntent(intent);
17559            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17560                    callerPackage, callingPid, callingUid, resolvedType,
17561                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17562                    resultData, resultExtras, ordered, sticky, false, userId);
17563
17564            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17565                    + ": prev had " + queue.mOrderedBroadcasts.size());
17566            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17567                    "Enqueueing broadcast " + r.intent.getAction());
17568
17569            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17570            if (!replaced) {
17571                queue.enqueueOrderedBroadcastLocked(r);
17572                queue.scheduleBroadcastsLocked();
17573            }
17574        }
17575
17576        return ActivityManager.BROADCAST_SUCCESS;
17577    }
17578
17579    final Intent verifyBroadcastLocked(Intent intent) {
17580        // Refuse possible leaked file descriptors
17581        if (intent != null && intent.hasFileDescriptors() == true) {
17582            throw new IllegalArgumentException("File descriptors passed in Intent");
17583        }
17584
17585        int flags = intent.getFlags();
17586
17587        if (!mProcessesReady) {
17588            // if the caller really truly claims to know what they're doing, go
17589            // ahead and allow the broadcast without launching any receivers
17590            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17591                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17592            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17593                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17594                        + " before boot completion");
17595                throw new IllegalStateException("Cannot broadcast before boot completed");
17596            }
17597        }
17598
17599        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17600            throw new IllegalArgumentException(
17601                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17602        }
17603
17604        return intent;
17605    }
17606
17607    public final int broadcastIntent(IApplicationThread caller,
17608            Intent intent, String resolvedType, IIntentReceiver resultTo,
17609            int resultCode, String resultData, Bundle resultExtras,
17610            String[] requiredPermissions, int appOp, Bundle bOptions,
17611            boolean serialized, boolean sticky, int userId) {
17612        enforceNotIsolatedCaller("broadcastIntent");
17613        synchronized(this) {
17614            intent = verifyBroadcastLocked(intent);
17615
17616            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17617            final int callingPid = Binder.getCallingPid();
17618            final int callingUid = Binder.getCallingUid();
17619            final long origId = Binder.clearCallingIdentity();
17620            int res = broadcastIntentLocked(callerApp,
17621                    callerApp != null ? callerApp.info.packageName : null,
17622                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17623                    requiredPermissions, appOp, null, serialized, sticky,
17624                    callingPid, callingUid, userId);
17625            Binder.restoreCallingIdentity(origId);
17626            return res;
17627        }
17628    }
17629
17630
17631    int broadcastIntentInPackage(String packageName, int uid,
17632            Intent intent, String resolvedType, IIntentReceiver resultTo,
17633            int resultCode, String resultData, Bundle resultExtras,
17634            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17635            int userId) {
17636        synchronized(this) {
17637            intent = verifyBroadcastLocked(intent);
17638
17639            final long origId = Binder.clearCallingIdentity();
17640            String[] requiredPermissions = requiredPermission == null ? null
17641                    : new String[] {requiredPermission};
17642            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17643                    resultTo, resultCode, resultData, resultExtras,
17644                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17645                    sticky, -1, uid, userId);
17646            Binder.restoreCallingIdentity(origId);
17647            return res;
17648        }
17649    }
17650
17651    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17652        // Refuse possible leaked file descriptors
17653        if (intent != null && intent.hasFileDescriptors() == true) {
17654            throw new IllegalArgumentException("File descriptors passed in Intent");
17655        }
17656
17657        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17658                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17659
17660        synchronized(this) {
17661            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17662                    != PackageManager.PERMISSION_GRANTED) {
17663                String msg = "Permission Denial: unbroadcastIntent() from pid="
17664                        + Binder.getCallingPid()
17665                        + ", uid=" + Binder.getCallingUid()
17666                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17667                Slog.w(TAG, msg);
17668                throw new SecurityException(msg);
17669            }
17670            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17671            if (stickies != null) {
17672                ArrayList<Intent> list = stickies.get(intent.getAction());
17673                if (list != null) {
17674                    int N = list.size();
17675                    int i;
17676                    for (i=0; i<N; i++) {
17677                        if (intent.filterEquals(list.get(i))) {
17678                            list.remove(i);
17679                            break;
17680                        }
17681                    }
17682                    if (list.size() <= 0) {
17683                        stickies.remove(intent.getAction());
17684                    }
17685                }
17686                if (stickies.size() <= 0) {
17687                    mStickyBroadcasts.remove(userId);
17688                }
17689            }
17690        }
17691    }
17692
17693    void backgroundServicesFinishedLocked(int userId) {
17694        for (BroadcastQueue queue : mBroadcastQueues) {
17695            queue.backgroundServicesFinishedLocked(userId);
17696        }
17697    }
17698
17699    public void finishReceiver(IBinder who, int resultCode, String resultData,
17700            Bundle resultExtras, boolean resultAbort, int flags) {
17701        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17702
17703        // Refuse possible leaked file descriptors
17704        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17705            throw new IllegalArgumentException("File descriptors passed in Bundle");
17706        }
17707
17708        final long origId = Binder.clearCallingIdentity();
17709        try {
17710            boolean doNext = false;
17711            BroadcastRecord r;
17712
17713            synchronized(this) {
17714                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17715                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17716                r = queue.getMatchingOrderedReceiver(who);
17717                if (r != null) {
17718                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17719                        resultData, resultExtras, resultAbort, true);
17720                }
17721            }
17722
17723            if (doNext) {
17724                r.queue.processNextBroadcast(false);
17725            }
17726            trimApplications();
17727        } finally {
17728            Binder.restoreCallingIdentity(origId);
17729        }
17730    }
17731
17732    // =========================================================
17733    // INSTRUMENTATION
17734    // =========================================================
17735
17736    public boolean startInstrumentation(ComponentName className,
17737            String profileFile, int flags, Bundle arguments,
17738            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17739            int userId, String abiOverride) {
17740        enforceNotIsolatedCaller("startInstrumentation");
17741        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17742                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17743        // Refuse possible leaked file descriptors
17744        if (arguments != null && arguments.hasFileDescriptors()) {
17745            throw new IllegalArgumentException("File descriptors passed in Bundle");
17746        }
17747
17748        synchronized(this) {
17749            InstrumentationInfo ii = null;
17750            ApplicationInfo ai = null;
17751            try {
17752                ii = mContext.getPackageManager().getInstrumentationInfo(
17753                    className, STOCK_PM_FLAGS);
17754                ai = AppGlobals.getPackageManager().getApplicationInfo(
17755                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17756            } catch (PackageManager.NameNotFoundException e) {
17757            } catch (RemoteException e) {
17758            }
17759            if (ii == null) {
17760                reportStartInstrumentationFailureLocked(watcher, className,
17761                        "Unable to find instrumentation info for: " + className);
17762                return false;
17763            }
17764            if (ai == null) {
17765                reportStartInstrumentationFailureLocked(watcher, className,
17766                        "Unable to find instrumentation target package: " + ii.targetPackage);
17767                return false;
17768            }
17769            if (!ai.hasCode()) {
17770                reportStartInstrumentationFailureLocked(watcher, className,
17771                        "Instrumentation target has no code: " + ii.targetPackage);
17772                return false;
17773            }
17774
17775            int match = mContext.getPackageManager().checkSignatures(
17776                    ii.targetPackage, ii.packageName);
17777            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17778                String msg = "Permission Denial: starting instrumentation "
17779                        + className + " from pid="
17780                        + Binder.getCallingPid()
17781                        + ", uid=" + Binder.getCallingPid()
17782                        + " not allowed because package " + ii.packageName
17783                        + " does not have a signature matching the target "
17784                        + ii.targetPackage;
17785                reportStartInstrumentationFailureLocked(watcher, className, msg);
17786                throw new SecurityException(msg);
17787            }
17788
17789            final long origId = Binder.clearCallingIdentity();
17790            // Instrumentation can kill and relaunch even persistent processes
17791            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17792                    "start instr");
17793            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17794            app.instrumentationClass = className;
17795            app.instrumentationInfo = ai;
17796            app.instrumentationProfileFile = profileFile;
17797            app.instrumentationArguments = arguments;
17798            app.instrumentationWatcher = watcher;
17799            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17800            app.instrumentationResultClass = className;
17801            Binder.restoreCallingIdentity(origId);
17802        }
17803
17804        return true;
17805    }
17806
17807    /**
17808     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17809     * error to the logs, but if somebody is watching, send the report there too.  This enables
17810     * the "am" command to report errors with more information.
17811     *
17812     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17813     * @param cn The component name of the instrumentation.
17814     * @param report The error report.
17815     */
17816    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17817            ComponentName cn, String report) {
17818        Slog.w(TAG, report);
17819        if (watcher != null) {
17820            Bundle results = new Bundle();
17821            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17822            results.putString("Error", report);
17823            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17824        }
17825    }
17826
17827    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17828        if (app.instrumentationWatcher != null) {
17829            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17830                    app.instrumentationClass, resultCode, results);
17831        }
17832
17833        // Can't call out of the system process with a lock held, so post a message.
17834        if (app.instrumentationUiAutomationConnection != null) {
17835            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17836                    app.instrumentationUiAutomationConnection).sendToTarget();
17837        }
17838
17839        app.instrumentationWatcher = null;
17840        app.instrumentationUiAutomationConnection = null;
17841        app.instrumentationClass = null;
17842        app.instrumentationInfo = null;
17843        app.instrumentationProfileFile = null;
17844        app.instrumentationArguments = null;
17845
17846        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17847                "finished inst");
17848    }
17849
17850    public void finishInstrumentation(IApplicationThread target,
17851            int resultCode, Bundle results) {
17852        int userId = UserHandle.getCallingUserId();
17853        // Refuse possible leaked file descriptors
17854        if (results != null && results.hasFileDescriptors()) {
17855            throw new IllegalArgumentException("File descriptors passed in Intent");
17856        }
17857
17858        synchronized(this) {
17859            ProcessRecord app = getRecordForAppLocked(target);
17860            if (app == null) {
17861                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17862                return;
17863            }
17864            final long origId = Binder.clearCallingIdentity();
17865            finishInstrumentationLocked(app, resultCode, results);
17866            Binder.restoreCallingIdentity(origId);
17867        }
17868    }
17869
17870    // =========================================================
17871    // CONFIGURATION
17872    // =========================================================
17873
17874    public ConfigurationInfo getDeviceConfigurationInfo() {
17875        ConfigurationInfo config = new ConfigurationInfo();
17876        synchronized (this) {
17877            config.reqTouchScreen = mConfiguration.touchscreen;
17878            config.reqKeyboardType = mConfiguration.keyboard;
17879            config.reqNavigation = mConfiguration.navigation;
17880            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17881                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17882                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17883            }
17884            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17885                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17886                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17887            }
17888            config.reqGlEsVersion = GL_ES_VERSION;
17889        }
17890        return config;
17891    }
17892
17893    ActivityStack getFocusedStack() {
17894        return mStackSupervisor.getFocusedStack();
17895    }
17896
17897    @Override
17898    public int getFocusedStackId() throws RemoteException {
17899        ActivityStack focusedStack = getFocusedStack();
17900        if (focusedStack != null) {
17901            return focusedStack.getStackId();
17902        }
17903        return -1;
17904    }
17905
17906    public Configuration getConfiguration() {
17907        Configuration ci;
17908        synchronized(this) {
17909            ci = new Configuration(mConfiguration);
17910            ci.userSetLocale = false;
17911        }
17912        return ci;
17913    }
17914
17915    @Override
17916    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17917        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17918        synchronized (this) {
17919            mSuppressResizeConfigChanges = suppress;
17920        }
17921    }
17922
17923    @Override
17924    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17925        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17926        if (fromStackId == HOME_STACK_ID) {
17927            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17928        }
17929        synchronized (this) {
17930            final long origId = Binder.clearCallingIdentity();
17931            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
17932            if (stack != null) {
17933                mWindowManager.deferSurfaceLayout();
17934                try {
17935                    if (fromStackId == DOCKED_STACK_ID) {
17936
17937                        // We are moving all tasks from the docked stack to the fullscreen stack,
17938                        // which is dismissing the docked stack, so resize all other stacks to
17939                        // fullscreen here already so we don't end up with resize trashing.
17940                        for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
17941                            if (StackId.isResizeableByDockedStack(i)) {
17942                                ActivityStack otherStack = mStackSupervisor.getStack(i);
17943                                if (otherStack != null) {
17944                                    mStackSupervisor.resizeStackLocked(i,
17945                                            null, null, null, PRESERVE_WINDOWS,
17946                                            true /* allowResizeInDockedMode */);
17947                                }
17948                            }
17949                        }
17950                    }
17951                    final ArrayList<TaskRecord> tasks = stack.getAllTasks();
17952                    final int size = tasks.size();
17953                    if (onTop) {
17954                        for (int i = 0; i < size; i++) {
17955                            mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
17956                                    FULLSCREEN_WORKSPACE_STACK_ID, onTop, !FORCE_FOCUS,
17957                                    "moveTasksToFullscreenStack", ANIMATE);
17958                        }
17959                    } else {
17960                        for (int i = size - 1; i >= 0; i--) {
17961                            mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
17962                                    FULLSCREEN_WORKSPACE_STACK_ID, 0);
17963                        }
17964                    }
17965                } finally {
17966                    mWindowManager.continueSurfaceLayout();
17967                }
17968
17969            }
17970            Binder.restoreCallingIdentity(origId);
17971        }
17972    }
17973
17974    @Override
17975    public void updatePersistentConfiguration(Configuration values) {
17976        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17977                "updateConfiguration()");
17978        enforceWriteSettingsPermission("updateConfiguration()");
17979        if (values == null) {
17980            throw new NullPointerException("Configuration must not be null");
17981        }
17982
17983        int userId = UserHandle.getCallingUserId();
17984
17985        synchronized(this) {
17986            final long origId = Binder.clearCallingIdentity();
17987            updateConfigurationLocked(values, null, false, true, userId);
17988            Binder.restoreCallingIdentity(origId);
17989        }
17990    }
17991
17992    private void updateFontScaleIfNeeded() {
17993        final int currentUserId;
17994        synchronized(this) {
17995            currentUserId = mUserController.getCurrentUserIdLocked();
17996        }
17997        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
17998                FONT_SCALE, 1.0f, currentUserId);
17999        if (mConfiguration.fontScale != scaleFactor) {
18000            final Configuration configuration = mWindowManager.computeNewConfiguration();
18001            configuration.fontScale = scaleFactor;
18002            updatePersistentConfiguration(configuration);
18003        }
18004    }
18005
18006    private void enforceWriteSettingsPermission(String func) {
18007        int uid = Binder.getCallingUid();
18008        if (uid == Process.ROOT_UID) {
18009            return;
18010        }
18011
18012        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18013                Settings.getPackageNameForUid(mContext, uid), false)) {
18014            return;
18015        }
18016
18017        String msg = "Permission Denial: " + func + " from pid="
18018                + Binder.getCallingPid()
18019                + ", uid=" + uid
18020                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18021        Slog.w(TAG, msg);
18022        throw new SecurityException(msg);
18023    }
18024
18025    public void updateConfiguration(Configuration values) {
18026        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18027                "updateConfiguration()");
18028
18029        synchronized(this) {
18030            if (values == null && mWindowManager != null) {
18031                // sentinel: fetch the current configuration from the window manager
18032                values = mWindowManager.computeNewConfiguration();
18033            }
18034
18035            if (mWindowManager != null) {
18036                mProcessList.applyDisplaySize(mWindowManager);
18037            }
18038
18039            final long origId = Binder.clearCallingIdentity();
18040            if (values != null) {
18041                Settings.System.clearConfiguration(values);
18042            }
18043            updateConfigurationLocked(values, null, false);
18044            Binder.restoreCallingIdentity(origId);
18045        }
18046    }
18047
18048    void updateUserConfigurationLocked() {
18049        Configuration configuration = new Configuration(mConfiguration);
18050        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18051                mUserController.getCurrentUserIdLocked());
18052        updateConfigurationLocked(configuration, null, false);
18053    }
18054
18055    boolean updateConfigurationLocked(Configuration values,
18056            ActivityRecord starting, boolean initLocale) {
18057        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18058        return updateConfigurationLocked(values, starting, initLocale, false,
18059                UserHandle.USER_NULL);
18060    }
18061
18062    // To cache the list of supported system locales
18063    private String[] mSupportedSystemLocales = null;
18064
18065    /**
18066     * Do either or both things: (1) change the current configuration, and (2)
18067     * make sure the given activity is running with the (now) current
18068     * configuration.  Returns true if the activity has been left running, or
18069     * false if <var>starting</var> is being destroyed to match the new
18070     * configuration.
18071     *
18072     * @param userId is only used when persistent parameter is set to true to persist configuration
18073     *               for that particular user
18074     */
18075    private boolean updateConfigurationLocked(Configuration values,
18076            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18077        int changes = 0;
18078
18079        if (mWindowManager != null) {
18080            mWindowManager.deferSurfaceLayout();
18081        }
18082        if (values != null) {
18083            Configuration newConfig = new Configuration(mConfiguration);
18084            changes = newConfig.updateFrom(values);
18085            if (changes != 0) {
18086                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18087                        "Updating configuration to: " + values);
18088
18089                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18090
18091                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18092                    final Locale locale;
18093                    if (values.getLocales().size() == 1) {
18094                        // This is an optimization to avoid the JNI call when the result of
18095                        // getFirstMatch() does not depend on the supported locales.
18096                        locale = values.getLocales().get(0);
18097                    } else {
18098                        if (mSupportedSystemLocales == null) {
18099                            mSupportedSystemLocales =
18100                                    Resources.getSystem().getAssets().getLocales();
18101                        }
18102                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18103                    }
18104                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18105                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18106                            locale));
18107                }
18108
18109                mConfigurationSeq++;
18110                if (mConfigurationSeq <= 0) {
18111                    mConfigurationSeq = 1;
18112                }
18113                newConfig.seq = mConfigurationSeq;
18114                mConfiguration = newConfig;
18115                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18116                mUsageStatsService.reportConfigurationChange(newConfig,
18117                        mUserController.getCurrentUserIdLocked());
18118                //mUsageStatsService.noteStartConfig(newConfig);
18119
18120                final Configuration configCopy = new Configuration(mConfiguration);
18121
18122                // TODO: If our config changes, should we auto dismiss any currently
18123                // showing dialogs?
18124                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18125
18126                AttributeCache ac = AttributeCache.instance();
18127                if (ac != null) {
18128                    ac.updateConfiguration(configCopy);
18129                }
18130
18131                // Make sure all resources in our process are updated
18132                // right now, so that anyone who is going to retrieve
18133                // resource values after we return will be sure to get
18134                // the new ones.  This is especially important during
18135                // boot, where the first config change needs to guarantee
18136                // all resources have that config before following boot
18137                // code is executed.
18138                mSystemThread.applyConfigurationToResources(configCopy);
18139
18140                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18141                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18142                    msg.obj = new Configuration(configCopy);
18143                    msg.arg1 = userId;
18144                    mHandler.sendMessage(msg);
18145                }
18146
18147                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18148                if (isDensityChange) {
18149                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18150                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18151                }
18152
18153                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18154                    ProcessRecord app = mLruProcesses.get(i);
18155                    try {
18156                        if (app.thread != null) {
18157                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18158                                    + app.processName + " new config " + mConfiguration);
18159                            app.thread.scheduleConfigurationChanged(configCopy);
18160                        }
18161                    } catch (Exception e) {
18162                    }
18163                }
18164                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18165                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18166                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18167                        | Intent.FLAG_RECEIVER_FOREGROUND);
18168                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18169                        null, AppOpsManager.OP_NONE, null, false, false,
18170                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18171                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18172                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18173                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18174                    if (!mProcessesReady) {
18175                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18176                    }
18177                    broadcastIntentLocked(null, null, intent,
18178                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18179                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18180                }
18181            }
18182            // Update the configuration with WM first and check if any of the stacks need to be
18183            // resized due to the configuration change. If so, resize the stacks now and do any
18184            // relaunches if necessary. This way we don't need to relaunch again below in
18185            // ensureActivityConfigurationLocked().
18186            if (mWindowManager != null) {
18187                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18188                if (resizedStacks != null) {
18189                    for (int stackId : resizedStacks) {
18190                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18191                        mStackSupervisor.resizeStackLocked(
18192                                stackId, newBounds, null, null, false, false);
18193                    }
18194                }
18195            }
18196        }
18197
18198        boolean kept = true;
18199        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18200        // mainStack is null during startup.
18201        if (mainStack != null) {
18202            if (changes != 0 && starting == null) {
18203                // If the configuration changed, and the caller is not already
18204                // in the process of starting an activity, then find the top
18205                // activity to check if its configuration needs to change.
18206                starting = mainStack.topRunningActivityLocked();
18207            }
18208
18209            if (starting != null) {
18210                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18211                // And we need to make sure at this point that all other activities
18212                // are made visible with the correct configuration.
18213                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18214                        !PRESERVE_WINDOWS);
18215            }
18216        }
18217        if (mWindowManager != null) {
18218            mWindowManager.continueSurfaceLayout();
18219        }
18220        return kept;
18221    }
18222
18223    /**
18224     * Decide based on the configuration whether we should shouw the ANR,
18225     * crash, etc dialogs.  The idea is that if there is no affordnace to
18226     * press the on-screen buttons, we shouldn't show the dialog.
18227     *
18228     * A thought: SystemUI might also want to get told about this, the Power
18229     * dialog / global actions also might want different behaviors.
18230     */
18231    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18232        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18233                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18234                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18235        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18236                                    == Configuration.UI_MODE_TYPE_CAR);
18237        return inputMethodExists && uiIsNotCarType && !inVrMode;
18238    }
18239
18240    @Override
18241    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18242        synchronized (this) {
18243            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18244            if (srec != null) {
18245                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18246            }
18247        }
18248        return false;
18249    }
18250
18251    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18252            Intent resultData) {
18253
18254        synchronized (this) {
18255            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18256            if (r != null) {
18257                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18258            }
18259            return false;
18260        }
18261    }
18262
18263    public int getLaunchedFromUid(IBinder activityToken) {
18264        ActivityRecord srec;
18265        synchronized (this) {
18266            srec = ActivityRecord.forTokenLocked(activityToken);
18267        }
18268        if (srec == null) {
18269            return -1;
18270        }
18271        return srec.launchedFromUid;
18272    }
18273
18274    public String getLaunchedFromPackage(IBinder activityToken) {
18275        ActivityRecord srec;
18276        synchronized (this) {
18277            srec = ActivityRecord.forTokenLocked(activityToken);
18278        }
18279        if (srec == null) {
18280            return null;
18281        }
18282        return srec.launchedFromPackage;
18283    }
18284
18285    // =========================================================
18286    // LIFETIME MANAGEMENT
18287    // =========================================================
18288
18289    // Returns which broadcast queue the app is the current [or imminent] receiver
18290    // on, or 'null' if the app is not an active broadcast recipient.
18291    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18292        BroadcastRecord r = app.curReceiver;
18293        if (r != null) {
18294            return r.queue;
18295        }
18296
18297        // It's not the current receiver, but it might be starting up to become one
18298        synchronized (this) {
18299            for (BroadcastQueue queue : mBroadcastQueues) {
18300                r = queue.mPendingBroadcast;
18301                if (r != null && r.curApp == app) {
18302                    // found it; report which queue it's in
18303                    return queue;
18304                }
18305            }
18306        }
18307
18308        return null;
18309    }
18310
18311    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18312            int targetUid, ComponentName targetComponent, String targetProcess) {
18313        if (!mTrackingAssociations) {
18314            return null;
18315        }
18316        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18317                = mAssociations.get(targetUid);
18318        if (components == null) {
18319            components = new ArrayMap<>();
18320            mAssociations.put(targetUid, components);
18321        }
18322        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18323        if (sourceUids == null) {
18324            sourceUids = new SparseArray<>();
18325            components.put(targetComponent, sourceUids);
18326        }
18327        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18328        if (sourceProcesses == null) {
18329            sourceProcesses = new ArrayMap<>();
18330            sourceUids.put(sourceUid, sourceProcesses);
18331        }
18332        Association ass = sourceProcesses.get(sourceProcess);
18333        if (ass == null) {
18334            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18335                    targetProcess);
18336            sourceProcesses.put(sourceProcess, ass);
18337        }
18338        ass.mCount++;
18339        ass.mNesting++;
18340        if (ass.mNesting == 1) {
18341            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18342            ass.mLastState = sourceState;
18343        }
18344        return ass;
18345    }
18346
18347    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18348            ComponentName targetComponent) {
18349        if (!mTrackingAssociations) {
18350            return;
18351        }
18352        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18353                = mAssociations.get(targetUid);
18354        if (components == null) {
18355            return;
18356        }
18357        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18358        if (sourceUids == null) {
18359            return;
18360        }
18361        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18362        if (sourceProcesses == null) {
18363            return;
18364        }
18365        Association ass = sourceProcesses.get(sourceProcess);
18366        if (ass == null || ass.mNesting <= 0) {
18367            return;
18368        }
18369        ass.mNesting--;
18370        if (ass.mNesting == 0) {
18371            long uptime = SystemClock.uptimeMillis();
18372            ass.mTime += uptime - ass.mStartTime;
18373            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18374                    += uptime - ass.mLastStateUptime;
18375            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18376        }
18377    }
18378
18379    private void noteUidProcessState(final int uid, final int state) {
18380        mBatteryStatsService.noteUidProcessState(uid, state);
18381        if (mTrackingAssociations) {
18382            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18383                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18384                        = mAssociations.valueAt(i1);
18385                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18386                    SparseArray<ArrayMap<String, Association>> sourceUids
18387                            = targetComponents.valueAt(i2);
18388                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18389                    if (sourceProcesses != null) {
18390                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18391                            Association ass = sourceProcesses.valueAt(i4);
18392                            if (ass.mNesting >= 1) {
18393                                // currently associated
18394                                long uptime = SystemClock.uptimeMillis();
18395                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18396                                        += uptime - ass.mLastStateUptime;
18397                                ass.mLastState = state;
18398                                ass.mLastStateUptime = uptime;
18399                            }
18400                        }
18401                    }
18402                }
18403            }
18404        }
18405    }
18406
18407    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18408            boolean doingAll, long now) {
18409        if (mAdjSeq == app.adjSeq) {
18410            // This adjustment has already been computed.
18411            return app.curRawAdj;
18412        }
18413
18414        if (app.thread == null) {
18415            app.adjSeq = mAdjSeq;
18416            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18417            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18418            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18419        }
18420
18421        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18422        app.adjSource = null;
18423        app.adjTarget = null;
18424        app.empty = false;
18425        app.cached = false;
18426
18427        final int activitiesSize = app.activities.size();
18428
18429        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18430            // The max adjustment doesn't allow this app to be anything
18431            // below foreground, so it is not worth doing work for it.
18432            app.adjType = "fixed";
18433            app.adjSeq = mAdjSeq;
18434            app.curRawAdj = app.maxAdj;
18435            app.foregroundActivities = false;
18436            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18437            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18438            // System processes can do UI, and when they do we want to have
18439            // them trim their memory after the user leaves the UI.  To
18440            // facilitate this, here we need to determine whether or not it
18441            // is currently showing UI.
18442            app.systemNoUi = true;
18443            if (app == TOP_APP) {
18444                app.systemNoUi = false;
18445            } else if (activitiesSize > 0) {
18446                for (int j = 0; j < activitiesSize; j++) {
18447                    final ActivityRecord r = app.activities.get(j);
18448                    if (r.visible) {
18449                        app.systemNoUi = false;
18450                    }
18451                }
18452            }
18453            if (!app.systemNoUi) {
18454                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18455            }
18456            return (app.curAdj=app.maxAdj);
18457        }
18458
18459        app.systemNoUi = false;
18460
18461        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18462
18463        // Determine the importance of the process, starting with most
18464        // important to least, and assign an appropriate OOM adjustment.
18465        int adj;
18466        int schedGroup;
18467        int procState;
18468        boolean foregroundActivities = false;
18469        BroadcastQueue queue;
18470        if (app == TOP_APP) {
18471            // The last app on the list is the foreground app.
18472            adj = ProcessList.FOREGROUND_APP_ADJ;
18473            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18474            app.adjType = "top-activity";
18475            foregroundActivities = true;
18476            procState = PROCESS_STATE_CUR_TOP;
18477        } else if (app.instrumentationClass != null) {
18478            // Don't want to kill running instrumentation.
18479            adj = ProcessList.FOREGROUND_APP_ADJ;
18480            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18481            app.adjType = "instrumentation";
18482            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18483        } else if ((queue = isReceivingBroadcast(app)) != null) {
18484            // An app that is currently receiving a broadcast also
18485            // counts as being in the foreground for OOM killer purposes.
18486            // It's placed in a sched group based on the nature of the
18487            // broadcast as reflected by which queue it's active in.
18488            adj = ProcessList.FOREGROUND_APP_ADJ;
18489            schedGroup = (queue == mFgBroadcastQueue)
18490                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18491            app.adjType = "broadcast";
18492            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18493        } else if (app.executingServices.size() > 0) {
18494            // An app that is currently executing a service callback also
18495            // counts as being in the foreground.
18496            adj = ProcessList.FOREGROUND_APP_ADJ;
18497            schedGroup = app.execServicesFg ?
18498                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18499            app.adjType = "exec-service";
18500            procState = ActivityManager.PROCESS_STATE_SERVICE;
18501            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18502        } else {
18503            // As far as we know the process is empty.  We may change our mind later.
18504            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18505            // At this point we don't actually know the adjustment.  Use the cached adj
18506            // value that the caller wants us to.
18507            adj = cachedAdj;
18508            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18509            app.cached = true;
18510            app.empty = true;
18511            app.adjType = "cch-empty";
18512        }
18513
18514        // Examine all activities if not already foreground.
18515        if (!foregroundActivities && activitiesSize > 0) {
18516            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18517            for (int j = 0; j < activitiesSize; j++) {
18518                final ActivityRecord r = app.activities.get(j);
18519                if (r.app != app) {
18520                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18521                            + " instead of expected " + app);
18522                    if (r.app == null || (r.app.uid == app.uid)) {
18523                        // Only fix things up when they look sane
18524                        r.app = app;
18525                    } else {
18526                        continue;
18527                    }
18528                }
18529                if (r.visible) {
18530                    // App has a visible activity; only upgrade adjustment.
18531                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18532                        adj = ProcessList.VISIBLE_APP_ADJ;
18533                        app.adjType = "visible";
18534                    }
18535                    if (procState > PROCESS_STATE_CUR_TOP) {
18536                        procState = PROCESS_STATE_CUR_TOP;
18537                    }
18538                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18539                    app.cached = false;
18540                    app.empty = false;
18541                    foregroundActivities = true;
18542                    if (r.task != null && minLayer > 0) {
18543                        final int layer = r.task.mLayerRank;
18544                        if (layer >= 0 && minLayer > layer) {
18545                            minLayer = layer;
18546                        }
18547                    }
18548                    break;
18549                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18550                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18551                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18552                        app.adjType = "pausing";
18553                    }
18554                    if (procState > PROCESS_STATE_CUR_TOP) {
18555                        procState = PROCESS_STATE_CUR_TOP;
18556                    }
18557                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18558                    app.cached = false;
18559                    app.empty = false;
18560                    foregroundActivities = true;
18561                } else if (r.state == ActivityState.STOPPING) {
18562                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18563                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18564                        app.adjType = "stopping";
18565                    }
18566                    // For the process state, we will at this point consider the
18567                    // process to be cached.  It will be cached either as an activity
18568                    // or empty depending on whether the activity is finishing.  We do
18569                    // this so that we can treat the process as cached for purposes of
18570                    // memory trimming (determing current memory level, trim command to
18571                    // send to process) since there can be an arbitrary number of stopping
18572                    // processes and they should soon all go into the cached state.
18573                    if (!r.finishing) {
18574                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18575                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18576                        }
18577                    }
18578                    app.cached = false;
18579                    app.empty = false;
18580                    foregroundActivities = true;
18581                } else {
18582                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18583                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18584                        app.adjType = "cch-act";
18585                    }
18586                }
18587            }
18588            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18589                adj += minLayer;
18590            }
18591        }
18592
18593        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18594                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18595            if (app.foregroundServices) {
18596                // The user is aware of this app, so make it visible.
18597                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18598                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18599                app.cached = false;
18600                app.adjType = "fg-service";
18601                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18602            } else if (app.forcingToForeground != null) {
18603                // The user is aware of this app, so make it visible.
18604                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18605                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18606                app.cached = false;
18607                app.adjType = "force-fg";
18608                app.adjSource = app.forcingToForeground;
18609                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18610            }
18611        }
18612
18613        if (app == mHeavyWeightProcess) {
18614            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18615                // We don't want to kill the current heavy-weight process.
18616                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18617                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18618                app.cached = false;
18619                app.adjType = "heavy";
18620            }
18621            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18622                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18623            }
18624        }
18625
18626        if (app == mHomeProcess) {
18627            if (adj > ProcessList.HOME_APP_ADJ) {
18628                // This process is hosting what we currently consider to be the
18629                // home app, so we don't want to let it go into the background.
18630                adj = ProcessList.HOME_APP_ADJ;
18631                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18632                app.cached = false;
18633                app.adjType = "home";
18634            }
18635            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18636                procState = ActivityManager.PROCESS_STATE_HOME;
18637            }
18638        }
18639
18640        if (app == mPreviousProcess && app.activities.size() > 0) {
18641            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18642                // This was the previous process that showed UI to the user.
18643                // We want to try to keep it around more aggressively, to give
18644                // a good experience around switching between two apps.
18645                adj = ProcessList.PREVIOUS_APP_ADJ;
18646                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18647                app.cached = false;
18648                app.adjType = "previous";
18649            }
18650            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18651                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18652            }
18653        }
18654
18655        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18656                + " reason=" + app.adjType);
18657
18658        // By default, we use the computed adjustment.  It may be changed if
18659        // there are applications dependent on our services or providers, but
18660        // this gives us a baseline and makes sure we don't get into an
18661        // infinite recursion.
18662        app.adjSeq = mAdjSeq;
18663        app.curRawAdj = adj;
18664        app.hasStartedServices = false;
18665
18666        if (mBackupTarget != null && app == mBackupTarget.app) {
18667            // If possible we want to avoid killing apps while they're being backed up
18668            if (adj > ProcessList.BACKUP_APP_ADJ) {
18669                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18670                adj = ProcessList.BACKUP_APP_ADJ;
18671                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18672                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18673                }
18674                app.adjType = "backup";
18675                app.cached = false;
18676            }
18677            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18678                procState = ActivityManager.PROCESS_STATE_BACKUP;
18679            }
18680        }
18681
18682        boolean mayBeTop = false;
18683
18684        for (int is = app.services.size()-1;
18685                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18686                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18687                        || procState > ActivityManager.PROCESS_STATE_TOP);
18688                is--) {
18689            ServiceRecord s = app.services.valueAt(is);
18690            if (s.startRequested) {
18691                app.hasStartedServices = true;
18692                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18693                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18694                }
18695                if (app.hasShownUi && app != mHomeProcess) {
18696                    // If this process has shown some UI, let it immediately
18697                    // go to the LRU list because it may be pretty heavy with
18698                    // UI stuff.  We'll tag it with a label just to help
18699                    // debug and understand what is going on.
18700                    if (adj > ProcessList.SERVICE_ADJ) {
18701                        app.adjType = "cch-started-ui-services";
18702                    }
18703                } else {
18704                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18705                        // This service has seen some activity within
18706                        // recent memory, so we will keep its process ahead
18707                        // of the background processes.
18708                        if (adj > ProcessList.SERVICE_ADJ) {
18709                            adj = ProcessList.SERVICE_ADJ;
18710                            app.adjType = "started-services";
18711                            app.cached = false;
18712                        }
18713                    }
18714                    // If we have let the service slide into the background
18715                    // state, still have some text describing what it is doing
18716                    // even though the service no longer has an impact.
18717                    if (adj > ProcessList.SERVICE_ADJ) {
18718                        app.adjType = "cch-started-services";
18719                    }
18720                }
18721            }
18722            for (int conni = s.connections.size()-1;
18723                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18724                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18725                            || procState > ActivityManager.PROCESS_STATE_TOP);
18726                    conni--) {
18727                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18728                for (int i = 0;
18729                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18730                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18731                                || procState > ActivityManager.PROCESS_STATE_TOP);
18732                        i++) {
18733                    // XXX should compute this based on the max of
18734                    // all connected clients.
18735                    ConnectionRecord cr = clist.get(i);
18736                    if (cr.binding.client == app) {
18737                        // Binding to ourself is not interesting.
18738                        continue;
18739                    }
18740                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18741                        ProcessRecord client = cr.binding.client;
18742                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18743                                TOP_APP, doingAll, now);
18744                        int clientProcState = client.curProcState;
18745                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18746                            // If the other app is cached for any reason, for purposes here
18747                            // we are going to consider it empty.  The specific cached state
18748                            // doesn't propagate except under certain conditions.
18749                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18750                        }
18751                        String adjType = null;
18752                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18753                            // Not doing bind OOM management, so treat
18754                            // this guy more like a started service.
18755                            if (app.hasShownUi && app != mHomeProcess) {
18756                                // If this process has shown some UI, let it immediately
18757                                // go to the LRU list because it may be pretty heavy with
18758                                // UI stuff.  We'll tag it with a label just to help
18759                                // debug and understand what is going on.
18760                                if (adj > clientAdj) {
18761                                    adjType = "cch-bound-ui-services";
18762                                }
18763                                app.cached = false;
18764                                clientAdj = adj;
18765                                clientProcState = procState;
18766                            } else {
18767                                if (now >= (s.lastActivity
18768                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18769                                    // This service has not seen activity within
18770                                    // recent memory, so allow it to drop to the
18771                                    // LRU list if there is no other reason to keep
18772                                    // it around.  We'll also tag it with a label just
18773                                    // to help debug and undertand what is going on.
18774                                    if (adj > clientAdj) {
18775                                        adjType = "cch-bound-services";
18776                                    }
18777                                    clientAdj = adj;
18778                                }
18779                            }
18780                        }
18781                        if (adj > clientAdj) {
18782                            // If this process has recently shown UI, and
18783                            // the process that is binding to it is less
18784                            // important than being visible, then we don't
18785                            // care about the binding as much as we care
18786                            // about letting this process get into the LRU
18787                            // list to be killed and restarted if needed for
18788                            // memory.
18789                            if (app.hasShownUi && app != mHomeProcess
18790                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18791                                adjType = "cch-bound-ui-services";
18792                            } else {
18793                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18794                                        |Context.BIND_IMPORTANT)) != 0) {
18795                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18796                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18797                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18798                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18799                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18800                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18801                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18802                                    adj = clientAdj;
18803                                } else {
18804                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18805                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18806                                    }
18807                                }
18808                                if (!client.cached) {
18809                                    app.cached = false;
18810                                }
18811                                adjType = "service";
18812                            }
18813                        }
18814                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18815                            // This will treat important bound services identically to
18816                            // the top app, which may behave differently than generic
18817                            // foreground work.
18818                            if (client.curSchedGroup > schedGroup) {
18819                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18820                                    schedGroup = client.curSchedGroup;
18821                                } else {
18822                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18823                                }
18824                            }
18825                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18826                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18827                                    // Special handling of clients who are in the top state.
18828                                    // We *may* want to consider this process to be in the
18829                                    // top state as well, but only if there is not another
18830                                    // reason for it to be running.  Being on the top is a
18831                                    // special state, meaning you are specifically running
18832                                    // for the current top app.  If the process is already
18833                                    // running in the background for some other reason, it
18834                                    // is more important to continue considering it to be
18835                                    // in the background state.
18836                                    mayBeTop = true;
18837                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18838                                } else {
18839                                    // Special handling for above-top states (persistent
18840                                    // processes).  These should not bring the current process
18841                                    // into the top state, since they are not on top.  Instead
18842                                    // give them the best state after that.
18843                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18844                                        clientProcState =
18845                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18846                                    } else if (mWakefulness
18847                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18848                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18849                                                    != 0) {
18850                                        clientProcState =
18851                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18852                                    } else {
18853                                        clientProcState =
18854                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18855                                    }
18856                                }
18857                            }
18858                        } else {
18859                            if (clientProcState <
18860                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18861                                clientProcState =
18862                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18863                            }
18864                        }
18865                        if (procState > clientProcState) {
18866                            procState = clientProcState;
18867                        }
18868                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18869                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18870                            app.pendingUiClean = true;
18871                        }
18872                        if (adjType != null) {
18873                            app.adjType = adjType;
18874                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18875                                    .REASON_SERVICE_IN_USE;
18876                            app.adjSource = cr.binding.client;
18877                            app.adjSourceProcState = clientProcState;
18878                            app.adjTarget = s.name;
18879                        }
18880                    }
18881                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18882                        app.treatLikeActivity = true;
18883                    }
18884                    final ActivityRecord a = cr.activity;
18885                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18886                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18887                            (a.visible || a.state == ActivityState.RESUMED ||
18888                             a.state == ActivityState.PAUSING)) {
18889                            adj = ProcessList.FOREGROUND_APP_ADJ;
18890                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18891                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18892                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18893                                } else {
18894                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18895                                }
18896                            }
18897                            app.cached = false;
18898                            app.adjType = "service";
18899                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18900                                    .REASON_SERVICE_IN_USE;
18901                            app.adjSource = a;
18902                            app.adjSourceProcState = procState;
18903                            app.adjTarget = s.name;
18904                        }
18905                    }
18906                }
18907            }
18908        }
18909
18910        for (int provi = app.pubProviders.size()-1;
18911                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18912                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18913                        || procState > ActivityManager.PROCESS_STATE_TOP);
18914                provi--) {
18915            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18916            for (int i = cpr.connections.size()-1;
18917                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18918                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18919                            || procState > ActivityManager.PROCESS_STATE_TOP);
18920                    i--) {
18921                ContentProviderConnection conn = cpr.connections.get(i);
18922                ProcessRecord client = conn.client;
18923                if (client == app) {
18924                    // Being our own client is not interesting.
18925                    continue;
18926                }
18927                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18928                int clientProcState = client.curProcState;
18929                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18930                    // If the other app is cached for any reason, for purposes here
18931                    // we are going to consider it empty.
18932                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18933                }
18934                if (adj > clientAdj) {
18935                    if (app.hasShownUi && app != mHomeProcess
18936                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18937                        app.adjType = "cch-ui-provider";
18938                    } else {
18939                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18940                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18941                        app.adjType = "provider";
18942                    }
18943                    app.cached &= client.cached;
18944                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18945                            .REASON_PROVIDER_IN_USE;
18946                    app.adjSource = client;
18947                    app.adjSourceProcState = clientProcState;
18948                    app.adjTarget = cpr.name;
18949                }
18950                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18951                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18952                        // Special handling of clients who are in the top state.
18953                        // We *may* want to consider this process to be in the
18954                        // top state as well, but only if there is not another
18955                        // reason for it to be running.  Being on the top is a
18956                        // special state, meaning you are specifically running
18957                        // for the current top app.  If the process is already
18958                        // running in the background for some other reason, it
18959                        // is more important to continue considering it to be
18960                        // in the background state.
18961                        mayBeTop = true;
18962                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18963                    } else {
18964                        // Special handling for above-top states (persistent
18965                        // processes).  These should not bring the current process
18966                        // into the top state, since they are not on top.  Instead
18967                        // give them the best state after that.
18968                        clientProcState =
18969                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18970                    }
18971                }
18972                if (procState > clientProcState) {
18973                    procState = clientProcState;
18974                }
18975                if (client.curSchedGroup > schedGroup) {
18976                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18977                }
18978            }
18979            // If the provider has external (non-framework) process
18980            // dependencies, ensure that its adjustment is at least
18981            // FOREGROUND_APP_ADJ.
18982            if (cpr.hasExternalProcessHandles()) {
18983                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18984                    adj = ProcessList.FOREGROUND_APP_ADJ;
18985                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18986                    app.cached = false;
18987                    app.adjType = "provider";
18988                    app.adjTarget = cpr.name;
18989                }
18990                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18991                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18992                }
18993            }
18994        }
18995
18996        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18997            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18998                adj = ProcessList.PREVIOUS_APP_ADJ;
18999                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19000                app.cached = false;
19001                app.adjType = "provider";
19002            }
19003            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19004                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19005            }
19006        }
19007
19008        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19009            // A client of one of our services or providers is in the top state.  We
19010            // *may* want to be in the top state, but not if we are already running in
19011            // the background for some other reason.  For the decision here, we are going
19012            // to pick out a few specific states that we want to remain in when a client
19013            // is top (states that tend to be longer-term) and otherwise allow it to go
19014            // to the top state.
19015            switch (procState) {
19016                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19017                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19018                case ActivityManager.PROCESS_STATE_SERVICE:
19019                    // These all are longer-term states, so pull them up to the top
19020                    // of the background states, but not all the way to the top state.
19021                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19022                    break;
19023                default:
19024                    // Otherwise, top is a better choice, so take it.
19025                    procState = ActivityManager.PROCESS_STATE_TOP;
19026                    break;
19027            }
19028        }
19029
19030        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19031            if (app.hasClientActivities) {
19032                // This is a cached process, but with client activities.  Mark it so.
19033                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19034                app.adjType = "cch-client-act";
19035            } else if (app.treatLikeActivity) {
19036                // This is a cached process, but somebody wants us to treat it like it has
19037                // an activity, okay!
19038                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19039                app.adjType = "cch-as-act";
19040            }
19041        }
19042
19043        if (adj == ProcessList.SERVICE_ADJ) {
19044            if (doingAll) {
19045                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19046                mNewNumServiceProcs++;
19047                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19048                if (!app.serviceb) {
19049                    // This service isn't far enough down on the LRU list to
19050                    // normally be a B service, but if we are low on RAM and it
19051                    // is large we want to force it down since we would prefer to
19052                    // keep launcher over it.
19053                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19054                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19055                        app.serviceHighRam = true;
19056                        app.serviceb = true;
19057                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19058                    } else {
19059                        mNewNumAServiceProcs++;
19060                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19061                    }
19062                } else {
19063                    app.serviceHighRam = false;
19064                }
19065            }
19066            if (app.serviceb) {
19067                adj = ProcessList.SERVICE_B_ADJ;
19068            }
19069        }
19070
19071        app.curRawAdj = adj;
19072
19073        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19074        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19075        if (adj > app.maxAdj) {
19076            adj = app.maxAdj;
19077            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19078                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19079            }
19080        }
19081
19082        // Do final modification to adj.  Everything we do between here and applying
19083        // the final setAdj must be done in this function, because we will also use
19084        // it when computing the final cached adj later.  Note that we don't need to
19085        // worry about this for max adj above, since max adj will always be used to
19086        // keep it out of the cached vaues.
19087        app.curAdj = app.modifyRawOomAdj(adj);
19088        app.curSchedGroup = schedGroup;
19089        app.curProcState = procState;
19090        app.foregroundActivities = foregroundActivities;
19091
19092        return app.curRawAdj;
19093    }
19094
19095    /**
19096     * Record new PSS sample for a process.
19097     */
19098    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19099            long now) {
19100        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19101                swapPss * 1024);
19102        proc.lastPssTime = now;
19103        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19104        if (DEBUG_PSS) Slog.d(TAG_PSS,
19105                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19106                + " state=" + ProcessList.makeProcStateString(procState));
19107        if (proc.initialIdlePss == 0) {
19108            proc.initialIdlePss = pss;
19109        }
19110        proc.lastPss = pss;
19111        proc.lastSwapPss = swapPss;
19112        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19113            proc.lastCachedPss = pss;
19114            proc.lastCachedSwapPss = swapPss;
19115        }
19116
19117        final SparseArray<Pair<Long, String>> watchUids
19118                = mMemWatchProcesses.getMap().get(proc.processName);
19119        Long check = null;
19120        if (watchUids != null) {
19121            Pair<Long, String> val = watchUids.get(proc.uid);
19122            if (val == null) {
19123                val = watchUids.get(0);
19124            }
19125            if (val != null) {
19126                check = val.first;
19127            }
19128        }
19129        if (check != null) {
19130            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19131                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19132                if (!isDebuggable) {
19133                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19134                        isDebuggable = true;
19135                    }
19136                }
19137                if (isDebuggable) {
19138                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19139                    final ProcessRecord myProc = proc;
19140                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19141                    mMemWatchDumpProcName = proc.processName;
19142                    mMemWatchDumpFile = heapdumpFile.toString();
19143                    mMemWatchDumpPid = proc.pid;
19144                    mMemWatchDumpUid = proc.uid;
19145                    BackgroundThread.getHandler().post(new Runnable() {
19146                        @Override
19147                        public void run() {
19148                            revokeUriPermission(ActivityThread.currentActivityThread()
19149                                            .getApplicationThread(),
19150                                    DumpHeapActivity.JAVA_URI,
19151                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19152                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19153                                    UserHandle.myUserId());
19154                            ParcelFileDescriptor fd = null;
19155                            try {
19156                                heapdumpFile.delete();
19157                                fd = ParcelFileDescriptor.open(heapdumpFile,
19158                                        ParcelFileDescriptor.MODE_CREATE |
19159                                                ParcelFileDescriptor.MODE_TRUNCATE |
19160                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19161                                                ParcelFileDescriptor.MODE_APPEND);
19162                                IApplicationThread thread = myProc.thread;
19163                                if (thread != null) {
19164                                    try {
19165                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19166                                                "Requesting dump heap from "
19167                                                + myProc + " to " + heapdumpFile);
19168                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19169                                    } catch (RemoteException e) {
19170                                    }
19171                                }
19172                            } catch (FileNotFoundException e) {
19173                                e.printStackTrace();
19174                            } finally {
19175                                if (fd != null) {
19176                                    try {
19177                                        fd.close();
19178                                    } catch (IOException e) {
19179                                    }
19180                                }
19181                            }
19182                        }
19183                    });
19184                } else {
19185                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19186                            + ", but debugging not enabled");
19187                }
19188            }
19189        }
19190    }
19191
19192    /**
19193     * Schedule PSS collection of a process.
19194     */
19195    void requestPssLocked(ProcessRecord proc, int procState) {
19196        if (mPendingPssProcesses.contains(proc)) {
19197            return;
19198        }
19199        if (mPendingPssProcesses.size() == 0) {
19200            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19201        }
19202        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19203        proc.pssProcState = procState;
19204        mPendingPssProcesses.add(proc);
19205    }
19206
19207    /**
19208     * Schedule PSS collection of all processes.
19209     */
19210    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19211        if (!always) {
19212            if (now < (mLastFullPssTime +
19213                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19214                return;
19215            }
19216        }
19217        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19218        mLastFullPssTime = now;
19219        mFullPssPending = true;
19220        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19221        mPendingPssProcesses.clear();
19222        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19223            ProcessRecord app = mLruProcesses.get(i);
19224            if (app.thread == null
19225                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19226                continue;
19227            }
19228            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19229                app.pssProcState = app.setProcState;
19230                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19231                        mTestPssMode, isSleeping(), now);
19232                mPendingPssProcesses.add(app);
19233            }
19234        }
19235        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19236    }
19237
19238    public void setTestPssMode(boolean enabled) {
19239        synchronized (this) {
19240            mTestPssMode = enabled;
19241            if (enabled) {
19242                // Whenever we enable the mode, we want to take a snapshot all of current
19243                // process mem use.
19244                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19245            }
19246        }
19247    }
19248
19249    /**
19250     * Ask a given process to GC right now.
19251     */
19252    final void performAppGcLocked(ProcessRecord app) {
19253        try {
19254            app.lastRequestedGc = SystemClock.uptimeMillis();
19255            if (app.thread != null) {
19256                if (app.reportLowMemory) {
19257                    app.reportLowMemory = false;
19258                    app.thread.scheduleLowMemory();
19259                } else {
19260                    app.thread.processInBackground();
19261                }
19262            }
19263        } catch (Exception e) {
19264            // whatever.
19265        }
19266    }
19267
19268    /**
19269     * Returns true if things are idle enough to perform GCs.
19270     */
19271    private final boolean canGcNowLocked() {
19272        boolean processingBroadcasts = false;
19273        for (BroadcastQueue q : mBroadcastQueues) {
19274            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19275                processingBroadcasts = true;
19276            }
19277        }
19278        return !processingBroadcasts
19279                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19280    }
19281
19282    /**
19283     * Perform GCs on all processes that are waiting for it, but only
19284     * if things are idle.
19285     */
19286    final void performAppGcsLocked() {
19287        final int N = mProcessesToGc.size();
19288        if (N <= 0) {
19289            return;
19290        }
19291        if (canGcNowLocked()) {
19292            while (mProcessesToGc.size() > 0) {
19293                ProcessRecord proc = mProcessesToGc.remove(0);
19294                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19295                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19296                            <= SystemClock.uptimeMillis()) {
19297                        // To avoid spamming the system, we will GC processes one
19298                        // at a time, waiting a few seconds between each.
19299                        performAppGcLocked(proc);
19300                        scheduleAppGcsLocked();
19301                        return;
19302                    } else {
19303                        // It hasn't been long enough since we last GCed this
19304                        // process...  put it in the list to wait for its time.
19305                        addProcessToGcListLocked(proc);
19306                        break;
19307                    }
19308                }
19309            }
19310
19311            scheduleAppGcsLocked();
19312        }
19313    }
19314
19315    /**
19316     * If all looks good, perform GCs on all processes waiting for them.
19317     */
19318    final void performAppGcsIfAppropriateLocked() {
19319        if (canGcNowLocked()) {
19320            performAppGcsLocked();
19321            return;
19322        }
19323        // Still not idle, wait some more.
19324        scheduleAppGcsLocked();
19325    }
19326
19327    /**
19328     * Schedule the execution of all pending app GCs.
19329     */
19330    final void scheduleAppGcsLocked() {
19331        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19332
19333        if (mProcessesToGc.size() > 0) {
19334            // Schedule a GC for the time to the next process.
19335            ProcessRecord proc = mProcessesToGc.get(0);
19336            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19337
19338            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19339            long now = SystemClock.uptimeMillis();
19340            if (when < (now+GC_TIMEOUT)) {
19341                when = now + GC_TIMEOUT;
19342            }
19343            mHandler.sendMessageAtTime(msg, when);
19344        }
19345    }
19346
19347    /**
19348     * Add a process to the array of processes waiting to be GCed.  Keeps the
19349     * list in sorted order by the last GC time.  The process can't already be
19350     * on the list.
19351     */
19352    final void addProcessToGcListLocked(ProcessRecord proc) {
19353        boolean added = false;
19354        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19355            if (mProcessesToGc.get(i).lastRequestedGc <
19356                    proc.lastRequestedGc) {
19357                added = true;
19358                mProcessesToGc.add(i+1, proc);
19359                break;
19360            }
19361        }
19362        if (!added) {
19363            mProcessesToGc.add(0, proc);
19364        }
19365    }
19366
19367    /**
19368     * Set up to ask a process to GC itself.  This will either do it
19369     * immediately, or put it on the list of processes to gc the next
19370     * time things are idle.
19371     */
19372    final void scheduleAppGcLocked(ProcessRecord app) {
19373        long now = SystemClock.uptimeMillis();
19374        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19375            return;
19376        }
19377        if (!mProcessesToGc.contains(app)) {
19378            addProcessToGcListLocked(app);
19379            scheduleAppGcsLocked();
19380        }
19381    }
19382
19383    final void checkExcessivePowerUsageLocked(boolean doKills) {
19384        updateCpuStatsNow();
19385
19386        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19387        boolean doWakeKills = doKills;
19388        boolean doCpuKills = doKills;
19389        if (mLastPowerCheckRealtime == 0) {
19390            doWakeKills = false;
19391        }
19392        if (mLastPowerCheckUptime == 0) {
19393            doCpuKills = false;
19394        }
19395        if (stats.isScreenOn()) {
19396            doWakeKills = false;
19397        }
19398        final long curRealtime = SystemClock.elapsedRealtime();
19399        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19400        final long curUptime = SystemClock.uptimeMillis();
19401        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19402        mLastPowerCheckRealtime = curRealtime;
19403        mLastPowerCheckUptime = curUptime;
19404        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19405            doWakeKills = false;
19406        }
19407        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19408            doCpuKills = false;
19409        }
19410        int i = mLruProcesses.size();
19411        while (i > 0) {
19412            i--;
19413            ProcessRecord app = mLruProcesses.get(i);
19414            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19415                long wtime;
19416                synchronized (stats) {
19417                    wtime = stats.getProcessWakeTime(app.info.uid,
19418                            app.pid, curRealtime);
19419                }
19420                long wtimeUsed = wtime - app.lastWakeTime;
19421                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19422                if (DEBUG_POWER) {
19423                    StringBuilder sb = new StringBuilder(128);
19424                    sb.append("Wake for ");
19425                    app.toShortString(sb);
19426                    sb.append(": over ");
19427                    TimeUtils.formatDuration(realtimeSince, sb);
19428                    sb.append(" used ");
19429                    TimeUtils.formatDuration(wtimeUsed, sb);
19430                    sb.append(" (");
19431                    sb.append((wtimeUsed*100)/realtimeSince);
19432                    sb.append("%)");
19433                    Slog.i(TAG_POWER, sb.toString());
19434                    sb.setLength(0);
19435                    sb.append("CPU for ");
19436                    app.toShortString(sb);
19437                    sb.append(": over ");
19438                    TimeUtils.formatDuration(uptimeSince, sb);
19439                    sb.append(" used ");
19440                    TimeUtils.formatDuration(cputimeUsed, sb);
19441                    sb.append(" (");
19442                    sb.append((cputimeUsed*100)/uptimeSince);
19443                    sb.append("%)");
19444                    Slog.i(TAG_POWER, sb.toString());
19445                }
19446                // If a process has held a wake lock for more
19447                // than 50% of the time during this period,
19448                // that sounds bad.  Kill!
19449                if (doWakeKills && realtimeSince > 0
19450                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19451                    synchronized (stats) {
19452                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19453                                realtimeSince, wtimeUsed);
19454                    }
19455                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19456                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19457                } else if (doCpuKills && uptimeSince > 0
19458                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19459                    synchronized (stats) {
19460                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19461                                uptimeSince, cputimeUsed);
19462                    }
19463                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19464                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19465                } else {
19466                    app.lastWakeTime = wtime;
19467                    app.lastCpuTime = app.curCpuTime;
19468                }
19469            }
19470        }
19471    }
19472
19473    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19474            long nowElapsed) {
19475        boolean success = true;
19476
19477        if (app.curRawAdj != app.setRawAdj) {
19478            app.setRawAdj = app.curRawAdj;
19479        }
19480
19481        int changes = 0;
19482
19483        if (app.curAdj != app.setAdj) {
19484            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19485            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19486                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19487                    + app.adjType);
19488            app.setAdj = app.curAdj;
19489        }
19490
19491        if (app.setSchedGroup != app.curSchedGroup) {
19492            app.setSchedGroup = app.curSchedGroup;
19493            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19494                    "Setting sched group of " + app.processName
19495                    + " to " + app.curSchedGroup);
19496            if (app.waitingToKill != null && app.curReceiver == null
19497                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19498                app.kill(app.waitingToKill, true);
19499                success = false;
19500            } else {
19501                int processGroup;
19502                switch (app.curSchedGroup) {
19503                    case ProcessList.SCHED_GROUP_BACKGROUND:
19504                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19505                        break;
19506                    case ProcessList.SCHED_GROUP_TOP_APP:
19507                        processGroup = Process.THREAD_GROUP_TOP_APP;
19508                        break;
19509                    default:
19510                        processGroup = Process.THREAD_GROUP_DEFAULT;
19511                        break;
19512                }
19513                if (true) {
19514                    long oldId = Binder.clearCallingIdentity();
19515                    try {
19516                        Process.setProcessGroup(app.pid, processGroup);
19517                    } catch (Exception e) {
19518                        Slog.w(TAG, "Failed setting process group of " + app.pid
19519                                + " to " + app.curSchedGroup);
19520                        e.printStackTrace();
19521                    } finally {
19522                        Binder.restoreCallingIdentity(oldId);
19523                    }
19524                } else {
19525                    if (app.thread != null) {
19526                        try {
19527                            app.thread.setSchedulingGroup(processGroup);
19528                        } catch (RemoteException e) {
19529                        }
19530                    }
19531                }
19532            }
19533        }
19534        if (app.repForegroundActivities != app.foregroundActivities) {
19535            app.repForegroundActivities = app.foregroundActivities;
19536            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19537        }
19538        if (app.repProcState != app.curProcState) {
19539            app.repProcState = app.curProcState;
19540            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19541            if (app.thread != null) {
19542                try {
19543                    if (false) {
19544                        //RuntimeException h = new RuntimeException("here");
19545                        Slog.i(TAG, "Sending new process state " + app.repProcState
19546                                + " to " + app /*, h*/);
19547                    }
19548                    app.thread.setProcessState(app.repProcState);
19549                } catch (RemoteException e) {
19550                }
19551            }
19552        }
19553        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19554                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19555            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19556                // Experimental code to more aggressively collect pss while
19557                // running test...  the problem is that this tends to collect
19558                // the data right when a process is transitioning between process
19559                // states, which well tend to give noisy data.
19560                long start = SystemClock.uptimeMillis();
19561                long pss = Debug.getPss(app.pid, mTmpLong, null);
19562                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19563                mPendingPssProcesses.remove(app);
19564                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19565                        + " to " + app.curProcState + ": "
19566                        + (SystemClock.uptimeMillis()-start) + "ms");
19567            }
19568            app.lastStateTime = now;
19569            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19570                    mTestPssMode, isSleeping(), now);
19571            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19572                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19573                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19574                    + (app.nextPssTime-now) + ": " + app);
19575        } else {
19576            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19577                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19578                    mTestPssMode)))) {
19579                requestPssLocked(app, app.setProcState);
19580                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19581                        mTestPssMode, isSleeping(), now);
19582            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19583                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19584        }
19585        if (app.setProcState != app.curProcState) {
19586            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19587                    "Proc state change of " + app.processName
19588                            + " to " + app.curProcState);
19589            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19590            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19591            if (setImportant && !curImportant) {
19592                // This app is no longer something we consider important enough to allow to
19593                // use arbitrary amounts of battery power.  Note
19594                // its current wake lock time to later know to kill it if
19595                // it is not behaving well.
19596                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19597                synchronized (stats) {
19598                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19599                            app.pid, nowElapsed);
19600                }
19601                app.lastCpuTime = app.curCpuTime;
19602
19603            }
19604            // Inform UsageStats of important process state change
19605            // Must be called before updating setProcState
19606            maybeUpdateUsageStatsLocked(app, nowElapsed);
19607
19608            app.setProcState = app.curProcState;
19609            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19610                app.notCachedSinceIdle = false;
19611            }
19612            if (!doingAll) {
19613                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19614            } else {
19615                app.procStateChanged = true;
19616            }
19617        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19618                > USAGE_STATS_INTERACTION_INTERVAL) {
19619            // For apps that sit around for a long time in the interactive state, we need
19620            // to report this at least once a day so they don't go idle.
19621            maybeUpdateUsageStatsLocked(app, nowElapsed);
19622        }
19623
19624        if (changes != 0) {
19625            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19626                    "Changes in " + app + ": " + changes);
19627            int i = mPendingProcessChanges.size()-1;
19628            ProcessChangeItem item = null;
19629            while (i >= 0) {
19630                item = mPendingProcessChanges.get(i);
19631                if (item.pid == app.pid) {
19632                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19633                            "Re-using existing item: " + item);
19634                    break;
19635                }
19636                i--;
19637            }
19638            if (i < 0) {
19639                // No existing item in pending changes; need a new one.
19640                final int NA = mAvailProcessChanges.size();
19641                if (NA > 0) {
19642                    item = mAvailProcessChanges.remove(NA-1);
19643                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19644                            "Retrieving available item: " + item);
19645                } else {
19646                    item = new ProcessChangeItem();
19647                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19648                            "Allocating new item: " + item);
19649                }
19650                item.changes = 0;
19651                item.pid = app.pid;
19652                item.uid = app.info.uid;
19653                if (mPendingProcessChanges.size() == 0) {
19654                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19655                            "*** Enqueueing dispatch processes changed!");
19656                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19657                }
19658                mPendingProcessChanges.add(item);
19659            }
19660            item.changes |= changes;
19661            item.processState = app.repProcState;
19662            item.foregroundActivities = app.repForegroundActivities;
19663            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19664                    "Item " + Integer.toHexString(System.identityHashCode(item))
19665                    + " " + app.toShortString() + ": changes=" + item.changes
19666                    + " procState=" + item.processState
19667                    + " foreground=" + item.foregroundActivities
19668                    + " type=" + app.adjType + " source=" + app.adjSource
19669                    + " target=" + app.adjTarget);
19670        }
19671
19672        return success;
19673    }
19674
19675    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19676        final UidRecord.ChangeItem pendingChange;
19677        if (uidRec == null || uidRec.pendingChange == null) {
19678            if (mPendingUidChanges.size() == 0) {
19679                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19680                        "*** Enqueueing dispatch uid changed!");
19681                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19682            }
19683            final int NA = mAvailUidChanges.size();
19684            if (NA > 0) {
19685                pendingChange = mAvailUidChanges.remove(NA-1);
19686                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19687                        "Retrieving available item: " + pendingChange);
19688            } else {
19689                pendingChange = new UidRecord.ChangeItem();
19690                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19691                        "Allocating new item: " + pendingChange);
19692            }
19693            if (uidRec != null) {
19694                uidRec.pendingChange = pendingChange;
19695                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19696                    // If this uid is going away, and we haven't yet reported it is gone,
19697                    // then do so now.
19698                    change = UidRecord.CHANGE_GONE_IDLE;
19699                }
19700            } else if (uid < 0) {
19701                throw new IllegalArgumentException("No UidRecord or uid");
19702            }
19703            pendingChange.uidRecord = uidRec;
19704            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19705            mPendingUidChanges.add(pendingChange);
19706        } else {
19707            pendingChange = uidRec.pendingChange;
19708            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19709                change = UidRecord.CHANGE_GONE_IDLE;
19710            }
19711        }
19712        pendingChange.change = change;
19713        pendingChange.processState = uidRec != null
19714                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19715    }
19716
19717    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19718            String authority) {
19719        if (app == null) return;
19720        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19721            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19722            if (userState == null) return;
19723            final long now = SystemClock.elapsedRealtime();
19724            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19725            if (lastReported == null || lastReported < now - 60 * 1000L) {
19726                mUsageStatsService.reportContentProviderUsage(
19727                        authority, providerPkgName, app.userId);
19728                userState.mProviderLastReportedFg.put(authority, now);
19729            }
19730        }
19731    }
19732
19733    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19734        if (DEBUG_USAGE_STATS) {
19735            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19736                    + "] state changes: old = " + app.setProcState + ", new = "
19737                    + app.curProcState);
19738        }
19739        if (mUsageStatsService == null) {
19740            return;
19741        }
19742        boolean isInteraction;
19743        // To avoid some abuse patterns, we are going to be careful about what we consider
19744        // to be an app interaction.  Being the top activity doesn't count while the display
19745        // is sleeping, nor do short foreground services.
19746        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19747            isInteraction = true;
19748            app.fgInteractionTime = 0;
19749        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19750            if (app.fgInteractionTime == 0) {
19751                app.fgInteractionTime = nowElapsed;
19752                isInteraction = false;
19753            } else {
19754                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19755            }
19756        } else {
19757            isInteraction = app.curProcState
19758                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19759            app.fgInteractionTime = 0;
19760        }
19761        if (isInteraction && (!app.reportedInteraction
19762                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19763            app.interactionEventTime = nowElapsed;
19764            String[] packages = app.getPackageList();
19765            if (packages != null) {
19766                for (int i = 0; i < packages.length; i++) {
19767                    mUsageStatsService.reportEvent(packages[i], app.userId,
19768                            UsageEvents.Event.SYSTEM_INTERACTION);
19769                }
19770            }
19771        }
19772        app.reportedInteraction = isInteraction;
19773        if (!isInteraction) {
19774            app.interactionEventTime = 0;
19775        }
19776    }
19777
19778    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19779        if (proc.thread != null) {
19780            if (proc.baseProcessTracker != null) {
19781                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19782            }
19783        }
19784    }
19785
19786    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19787            ProcessRecord TOP_APP, boolean doingAll, long now) {
19788        if (app.thread == null) {
19789            return false;
19790        }
19791
19792        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19793
19794        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19795    }
19796
19797    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19798            boolean oomAdj) {
19799        if (isForeground != proc.foregroundServices) {
19800            proc.foregroundServices = isForeground;
19801            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19802                    proc.info.uid);
19803            if (isForeground) {
19804                if (curProcs == null) {
19805                    curProcs = new ArrayList<ProcessRecord>();
19806                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19807                }
19808                if (!curProcs.contains(proc)) {
19809                    curProcs.add(proc);
19810                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19811                            proc.info.packageName, proc.info.uid);
19812                }
19813            } else {
19814                if (curProcs != null) {
19815                    if (curProcs.remove(proc)) {
19816                        mBatteryStatsService.noteEvent(
19817                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19818                                proc.info.packageName, proc.info.uid);
19819                        if (curProcs.size() <= 0) {
19820                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19821                        }
19822                    }
19823                }
19824            }
19825            if (oomAdj) {
19826                updateOomAdjLocked();
19827            }
19828        }
19829    }
19830
19831    private final ActivityRecord resumedAppLocked() {
19832        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19833        String pkg;
19834        int uid;
19835        if (act != null) {
19836            pkg = act.packageName;
19837            uid = act.info.applicationInfo.uid;
19838        } else {
19839            pkg = null;
19840            uid = -1;
19841        }
19842        // Has the UID or resumed package name changed?
19843        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19844                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19845            if (mCurResumedPackage != null) {
19846                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19847                        mCurResumedPackage, mCurResumedUid);
19848            }
19849            mCurResumedPackage = pkg;
19850            mCurResumedUid = uid;
19851            if (mCurResumedPackage != null) {
19852                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19853                        mCurResumedPackage, mCurResumedUid);
19854            }
19855        }
19856        return act;
19857    }
19858
19859    final boolean updateOomAdjLocked(ProcessRecord app) {
19860        final ActivityRecord TOP_ACT = resumedAppLocked();
19861        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19862        final boolean wasCached = app.cached;
19863
19864        mAdjSeq++;
19865
19866        // This is the desired cached adjusment we want to tell it to use.
19867        // If our app is currently cached, we know it, and that is it.  Otherwise,
19868        // we don't know it yet, and it needs to now be cached we will then
19869        // need to do a complete oom adj.
19870        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19871                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19872        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19873                SystemClock.uptimeMillis());
19874        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19875            // Changed to/from cached state, so apps after it in the LRU
19876            // list may also be changed.
19877            updateOomAdjLocked();
19878        }
19879        return success;
19880    }
19881
19882    final void updateOomAdjLocked() {
19883        final ActivityRecord TOP_ACT = resumedAppLocked();
19884        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19885        final long now = SystemClock.uptimeMillis();
19886        final long nowElapsed = SystemClock.elapsedRealtime();
19887        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19888        final int N = mLruProcesses.size();
19889
19890        if (false) {
19891            RuntimeException e = new RuntimeException();
19892            e.fillInStackTrace();
19893            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19894        }
19895
19896        // Reset state in all uid records.
19897        for (int i=mActiveUids.size()-1; i>=0; i--) {
19898            final UidRecord uidRec = mActiveUids.valueAt(i);
19899            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19900                    "Starting update of " + uidRec);
19901            uidRec.reset();
19902        }
19903
19904        mStackSupervisor.rankTaskLayersIfNeeded();
19905
19906        mAdjSeq++;
19907        mNewNumServiceProcs = 0;
19908        mNewNumAServiceProcs = 0;
19909
19910        final int emptyProcessLimit;
19911        final int cachedProcessLimit;
19912        if (mProcessLimit <= 0) {
19913            emptyProcessLimit = cachedProcessLimit = 0;
19914        } else if (mProcessLimit == 1) {
19915            emptyProcessLimit = 1;
19916            cachedProcessLimit = 0;
19917        } else {
19918            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19919            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19920        }
19921
19922        // Let's determine how many processes we have running vs.
19923        // how many slots we have for background processes; we may want
19924        // to put multiple processes in a slot of there are enough of
19925        // them.
19926        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19927                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19928        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19929        if (numEmptyProcs > cachedProcessLimit) {
19930            // If there are more empty processes than our limit on cached
19931            // processes, then use the cached process limit for the factor.
19932            // This ensures that the really old empty processes get pushed
19933            // down to the bottom, so if we are running low on memory we will
19934            // have a better chance at keeping around more cached processes
19935            // instead of a gazillion empty processes.
19936            numEmptyProcs = cachedProcessLimit;
19937        }
19938        int emptyFactor = numEmptyProcs/numSlots;
19939        if (emptyFactor < 1) emptyFactor = 1;
19940        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19941        if (cachedFactor < 1) cachedFactor = 1;
19942        int stepCached = 0;
19943        int stepEmpty = 0;
19944        int numCached = 0;
19945        int numEmpty = 0;
19946        int numTrimming = 0;
19947
19948        mNumNonCachedProcs = 0;
19949        mNumCachedHiddenProcs = 0;
19950
19951        // First update the OOM adjustment for each of the
19952        // application processes based on their current state.
19953        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19954        int nextCachedAdj = curCachedAdj+1;
19955        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19956        int nextEmptyAdj = curEmptyAdj+2;
19957        for (int i=N-1; i>=0; i--) {
19958            ProcessRecord app = mLruProcesses.get(i);
19959            if (!app.killedByAm && app.thread != null) {
19960                app.procStateChanged = false;
19961                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19962
19963                // If we haven't yet assigned the final cached adj
19964                // to the process, do that now.
19965                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19966                    switch (app.curProcState) {
19967                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19968                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19969                            // This process is a cached process holding activities...
19970                            // assign it the next cached value for that type, and then
19971                            // step that cached level.
19972                            app.curRawAdj = curCachedAdj;
19973                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19974                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19975                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19976                                    + ")");
19977                            if (curCachedAdj != nextCachedAdj) {
19978                                stepCached++;
19979                                if (stepCached >= cachedFactor) {
19980                                    stepCached = 0;
19981                                    curCachedAdj = nextCachedAdj;
19982                                    nextCachedAdj += 2;
19983                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19984                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19985                                    }
19986                                }
19987                            }
19988                            break;
19989                        default:
19990                            // For everything else, assign next empty cached process
19991                            // level and bump that up.  Note that this means that
19992                            // long-running services that have dropped down to the
19993                            // cached level will be treated as empty (since their process
19994                            // state is still as a service), which is what we want.
19995                            app.curRawAdj = curEmptyAdj;
19996                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19997                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19998                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19999                                    + ")");
20000                            if (curEmptyAdj != nextEmptyAdj) {
20001                                stepEmpty++;
20002                                if (stepEmpty >= emptyFactor) {
20003                                    stepEmpty = 0;
20004                                    curEmptyAdj = nextEmptyAdj;
20005                                    nextEmptyAdj += 2;
20006                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20007                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20008                                    }
20009                                }
20010                            }
20011                            break;
20012                    }
20013                }
20014
20015                applyOomAdjLocked(app, true, now, nowElapsed);
20016
20017                // Count the number of process types.
20018                switch (app.curProcState) {
20019                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20020                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20021                        mNumCachedHiddenProcs++;
20022                        numCached++;
20023                        if (numCached > cachedProcessLimit) {
20024                            app.kill("cached #" + numCached, true);
20025                        }
20026                        break;
20027                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20028                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20029                                && app.lastActivityTime < oldTime) {
20030                            app.kill("empty for "
20031                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20032                                    / 1000) + "s", true);
20033                        } else {
20034                            numEmpty++;
20035                            if (numEmpty > emptyProcessLimit) {
20036                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
20037                            }
20038                        }
20039                        break;
20040                    default:
20041                        mNumNonCachedProcs++;
20042                        break;
20043                }
20044
20045                if (app.isolated && app.services.size() <= 0) {
20046                    // If this is an isolated process, and there are no
20047                    // services running in it, then the process is no longer
20048                    // needed.  We agressively kill these because we can by
20049                    // definition not re-use the same process again, and it is
20050                    // good to avoid having whatever code was running in them
20051                    // left sitting around after no longer needed.
20052                    app.kill("isolated not needed", true);
20053                } else {
20054                    // Keeping this process, update its uid.
20055                    final UidRecord uidRec = app.uidRecord;
20056                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20057                        uidRec.curProcState = app.curProcState;
20058                    }
20059                }
20060
20061                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20062                        && !app.killedByAm) {
20063                    numTrimming++;
20064                }
20065            }
20066        }
20067
20068        mNumServiceProcs = mNewNumServiceProcs;
20069
20070        // Now determine the memory trimming level of background processes.
20071        // Unfortunately we need to start at the back of the list to do this
20072        // properly.  We only do this if the number of background apps we
20073        // are managing to keep around is less than half the maximum we desire;
20074        // if we are keeping a good number around, we'll let them use whatever
20075        // memory they want.
20076        final int numCachedAndEmpty = numCached + numEmpty;
20077        int memFactor;
20078        if (numCached <= ProcessList.TRIM_CACHED_APPS
20079                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20080            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20081                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20082            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20083                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20084            } else {
20085                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20086            }
20087        } else {
20088            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20089        }
20090        // We always allow the memory level to go up (better).  We only allow it to go
20091        // down if we are in a state where that is allowed, *and* the total number of processes
20092        // has gone down since last time.
20093        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20094                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20095                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20096        if (memFactor > mLastMemoryLevel) {
20097            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20098                memFactor = mLastMemoryLevel;
20099                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20100            }
20101        }
20102        mLastMemoryLevel = memFactor;
20103        mLastNumProcesses = mLruProcesses.size();
20104        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20105        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20106        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20107            if (mLowRamStartTime == 0) {
20108                mLowRamStartTime = now;
20109            }
20110            int step = 0;
20111            int fgTrimLevel;
20112            switch (memFactor) {
20113                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20114                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20115                    break;
20116                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20117                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20118                    break;
20119                default:
20120                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20121                    break;
20122            }
20123            int factor = numTrimming/3;
20124            int minFactor = 2;
20125            if (mHomeProcess != null) minFactor++;
20126            if (mPreviousProcess != null) minFactor++;
20127            if (factor < minFactor) factor = minFactor;
20128            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20129            for (int i=N-1; i>=0; i--) {
20130                ProcessRecord app = mLruProcesses.get(i);
20131                if (allChanged || app.procStateChanged) {
20132                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20133                    app.procStateChanged = false;
20134                }
20135                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20136                        && !app.killedByAm) {
20137                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20138                        try {
20139                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20140                                    "Trimming memory of " + app.processName + " to " + curLevel);
20141                            app.thread.scheduleTrimMemory(curLevel);
20142                        } catch (RemoteException e) {
20143                        }
20144                        if (false) {
20145                            // For now we won't do this; our memory trimming seems
20146                            // to be good enough at this point that destroying
20147                            // activities causes more harm than good.
20148                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20149                                    && app != mHomeProcess && app != mPreviousProcess) {
20150                                // Need to do this on its own message because the stack may not
20151                                // be in a consistent state at this point.
20152                                // For these apps we will also finish their activities
20153                                // to help them free memory.
20154                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20155                            }
20156                        }
20157                    }
20158                    app.trimMemoryLevel = curLevel;
20159                    step++;
20160                    if (step >= factor) {
20161                        step = 0;
20162                        switch (curLevel) {
20163                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20164                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20165                                break;
20166                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20167                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20168                                break;
20169                        }
20170                    }
20171                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20172                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20173                            && app.thread != null) {
20174                        try {
20175                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20176                                    "Trimming memory of heavy-weight " + app.processName
20177                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20178                            app.thread.scheduleTrimMemory(
20179                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20180                        } catch (RemoteException e) {
20181                        }
20182                    }
20183                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20184                } else {
20185                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20186                            || app.systemNoUi) && app.pendingUiClean) {
20187                        // If this application is now in the background and it
20188                        // had done UI, then give it the special trim level to
20189                        // have it free UI resources.
20190                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20191                        if (app.trimMemoryLevel < level && app.thread != null) {
20192                            try {
20193                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20194                                        "Trimming memory of bg-ui " + app.processName
20195                                        + " to " + level);
20196                                app.thread.scheduleTrimMemory(level);
20197                            } catch (RemoteException e) {
20198                            }
20199                        }
20200                        app.pendingUiClean = false;
20201                    }
20202                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20203                        try {
20204                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20205                                    "Trimming memory of fg " + app.processName
20206                                    + " to " + fgTrimLevel);
20207                            app.thread.scheduleTrimMemory(fgTrimLevel);
20208                        } catch (RemoteException e) {
20209                        }
20210                    }
20211                    app.trimMemoryLevel = fgTrimLevel;
20212                }
20213            }
20214        } else {
20215            if (mLowRamStartTime != 0) {
20216                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20217                mLowRamStartTime = 0;
20218            }
20219            for (int i=N-1; i>=0; i--) {
20220                ProcessRecord app = mLruProcesses.get(i);
20221                if (allChanged || app.procStateChanged) {
20222                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20223                    app.procStateChanged = false;
20224                }
20225                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20226                        || app.systemNoUi) && app.pendingUiClean) {
20227                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20228                            && app.thread != null) {
20229                        try {
20230                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20231                                    "Trimming memory of ui hidden " + app.processName
20232                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20233                            app.thread.scheduleTrimMemory(
20234                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20235                        } catch (RemoteException e) {
20236                        }
20237                    }
20238                    app.pendingUiClean = false;
20239                }
20240                app.trimMemoryLevel = 0;
20241            }
20242        }
20243
20244        if (mAlwaysFinishActivities) {
20245            // Need to do this on its own message because the stack may not
20246            // be in a consistent state at this point.
20247            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20248        }
20249
20250        if (allChanged) {
20251            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20252        }
20253
20254        // Update from any uid changes.
20255        for (int i=mActiveUids.size()-1; i>=0; i--) {
20256            final UidRecord uidRec = mActiveUids.valueAt(i);
20257            int uidChange = UidRecord.CHANGE_PROCSTATE;
20258            if (uidRec.setProcState != uidRec.curProcState) {
20259                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20260                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20261                        + " to " + uidRec.curProcState);
20262                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20263                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20264                        uidRec.lastBackgroundTime = nowElapsed;
20265                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20266                            // Note: the background settle time is in elapsed realtime, while
20267                            // the handler time base is uptime.  All this means is that we may
20268                            // stop background uids later than we had intended, but that only
20269                            // happens because the device was sleeping so we are okay anyway.
20270                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20271                        }
20272                    }
20273                } else {
20274                    if (uidRec.idle) {
20275                        uidChange = UidRecord.CHANGE_ACTIVE;
20276                        uidRec.idle = false;
20277                    }
20278                    uidRec.lastBackgroundTime = 0;
20279                }
20280                uidRec.setProcState = uidRec.curProcState;
20281                enqueueUidChangeLocked(uidRec, -1, uidChange);
20282                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20283            }
20284        }
20285
20286        if (mProcessStats.shouldWriteNowLocked(now)) {
20287            mHandler.post(new Runnable() {
20288                @Override public void run() {
20289                    synchronized (ActivityManagerService.this) {
20290                        mProcessStats.writeStateAsyncLocked();
20291                    }
20292                }
20293            });
20294        }
20295
20296        if (DEBUG_OOM_ADJ) {
20297            final long duration = SystemClock.uptimeMillis() - now;
20298            if (false) {
20299                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20300                        new RuntimeException("here").fillInStackTrace());
20301            } else {
20302                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20303            }
20304        }
20305    }
20306
20307    final void idleUids() {
20308        synchronized (this) {
20309            final long nowElapsed = SystemClock.elapsedRealtime();
20310            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20311            long nextTime = 0;
20312            for (int i=mActiveUids.size()-1; i>=0; i--) {
20313                final UidRecord uidRec = mActiveUids.valueAt(i);
20314                final long bgTime = uidRec.lastBackgroundTime;
20315                if (bgTime > 0 && !uidRec.idle) {
20316                    if (bgTime <= maxBgTime) {
20317                        uidRec.idle = true;
20318                        doStopUidLocked(uidRec.uid, uidRec);
20319                    } else {
20320                        if (nextTime == 0 || nextTime > bgTime) {
20321                            nextTime = bgTime;
20322                        }
20323                    }
20324                }
20325            }
20326            if (nextTime > 0) {
20327                mHandler.removeMessages(IDLE_UIDS_MSG);
20328                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20329                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20330            }
20331        }
20332    }
20333
20334    final void runInBackgroundDisabled(int uid) {
20335        synchronized (this) {
20336            UidRecord uidRec = mActiveUids.get(uid);
20337            if (uidRec != null) {
20338                // This uid is actually running...  should it be considered background now?
20339                if (uidRec.idle) {
20340                    doStopUidLocked(uidRec.uid, uidRec);
20341                }
20342            } else {
20343                // This uid isn't actually running...  still send a report about it being "stopped".
20344                doStopUidLocked(uid, null);
20345            }
20346        }
20347    }
20348
20349    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20350        mServices.stopInBackgroundLocked(uid);
20351        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20352    }
20353
20354    final void trimApplications() {
20355        synchronized (this) {
20356            int i;
20357
20358            // First remove any unused application processes whose package
20359            // has been removed.
20360            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20361                final ProcessRecord app = mRemovedProcesses.get(i);
20362                if (app.activities.size() == 0
20363                        && app.curReceiver == null && app.services.size() == 0) {
20364                    Slog.i(
20365                        TAG, "Exiting empty application process "
20366                        + app.processName + " ("
20367                        + (app.thread != null ? app.thread.asBinder() : null)
20368                        + ")\n");
20369                    if (app.pid > 0 && app.pid != MY_PID) {
20370                        app.kill("empty", false);
20371                    } else {
20372                        try {
20373                            app.thread.scheduleExit();
20374                        } catch (Exception e) {
20375                            // Ignore exceptions.
20376                        }
20377                    }
20378                    cleanUpApplicationRecordLocked(app, false, true, -1);
20379                    mRemovedProcesses.remove(i);
20380
20381                    if (app.persistent) {
20382                        addAppLocked(app.info, false, null /* ABI override */);
20383                    }
20384                }
20385            }
20386
20387            // Now update the oom adj for all processes.
20388            updateOomAdjLocked();
20389        }
20390    }
20391
20392    /** This method sends the specified signal to each of the persistent apps */
20393    public void signalPersistentProcesses(int sig) throws RemoteException {
20394        if (sig != Process.SIGNAL_USR1) {
20395            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20396        }
20397
20398        synchronized (this) {
20399            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20400                    != PackageManager.PERMISSION_GRANTED) {
20401                throw new SecurityException("Requires permission "
20402                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20403            }
20404
20405            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20406                ProcessRecord r = mLruProcesses.get(i);
20407                if (r.thread != null && r.persistent) {
20408                    Process.sendSignal(r.pid, sig);
20409                }
20410            }
20411        }
20412    }
20413
20414    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20415        if (proc == null || proc == mProfileProc) {
20416            proc = mProfileProc;
20417            profileType = mProfileType;
20418            clearProfilerLocked();
20419        }
20420        if (proc == null) {
20421            return;
20422        }
20423        try {
20424            proc.thread.profilerControl(false, null, profileType);
20425        } catch (RemoteException e) {
20426            throw new IllegalStateException("Process disappeared");
20427        }
20428    }
20429
20430    private void clearProfilerLocked() {
20431        if (mProfileFd != null) {
20432            try {
20433                mProfileFd.close();
20434            } catch (IOException e) {
20435            }
20436        }
20437        mProfileApp = null;
20438        mProfileProc = null;
20439        mProfileFile = null;
20440        mProfileType = 0;
20441        mAutoStopProfiler = false;
20442        mSamplingInterval = 0;
20443    }
20444
20445    public boolean profileControl(String process, int userId, boolean start,
20446            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20447
20448        try {
20449            synchronized (this) {
20450                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20451                // its own permission.
20452                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20453                        != PackageManager.PERMISSION_GRANTED) {
20454                    throw new SecurityException("Requires permission "
20455                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20456                }
20457
20458                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20459                    throw new IllegalArgumentException("null profile info or fd");
20460                }
20461
20462                ProcessRecord proc = null;
20463                if (process != null) {
20464                    proc = findProcessLocked(process, userId, "profileControl");
20465                }
20466
20467                if (start && (proc == null || proc.thread == null)) {
20468                    throw new IllegalArgumentException("Unknown process: " + process);
20469                }
20470
20471                if (start) {
20472                    stopProfilerLocked(null, 0);
20473                    setProfileApp(proc.info, proc.processName, profilerInfo);
20474                    mProfileProc = proc;
20475                    mProfileType = profileType;
20476                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20477                    try {
20478                        fd = fd.dup();
20479                    } catch (IOException e) {
20480                        fd = null;
20481                    }
20482                    profilerInfo.profileFd = fd;
20483                    proc.thread.profilerControl(start, profilerInfo, profileType);
20484                    fd = null;
20485                    mProfileFd = null;
20486                } else {
20487                    stopProfilerLocked(proc, profileType);
20488                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20489                        try {
20490                            profilerInfo.profileFd.close();
20491                        } catch (IOException e) {
20492                        }
20493                    }
20494                }
20495
20496                return true;
20497            }
20498        } catch (RemoteException e) {
20499            throw new IllegalStateException("Process disappeared");
20500        } finally {
20501            if (profilerInfo != null && profilerInfo.profileFd != null) {
20502                try {
20503                    profilerInfo.profileFd.close();
20504                } catch (IOException e) {
20505                }
20506            }
20507        }
20508    }
20509
20510    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20511        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20512                userId, true, ALLOW_FULL_ONLY, callName, null);
20513        ProcessRecord proc = null;
20514        try {
20515            int pid = Integer.parseInt(process);
20516            synchronized (mPidsSelfLocked) {
20517                proc = mPidsSelfLocked.get(pid);
20518            }
20519        } catch (NumberFormatException e) {
20520        }
20521
20522        if (proc == null) {
20523            ArrayMap<String, SparseArray<ProcessRecord>> all
20524                    = mProcessNames.getMap();
20525            SparseArray<ProcessRecord> procs = all.get(process);
20526            if (procs != null && procs.size() > 0) {
20527                proc = procs.valueAt(0);
20528                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20529                    for (int i=1; i<procs.size(); i++) {
20530                        ProcessRecord thisProc = procs.valueAt(i);
20531                        if (thisProc.userId == userId) {
20532                            proc = thisProc;
20533                            break;
20534                        }
20535                    }
20536                }
20537            }
20538        }
20539
20540        return proc;
20541    }
20542
20543    public boolean dumpHeap(String process, int userId, boolean managed,
20544            String path, ParcelFileDescriptor fd) throws RemoteException {
20545
20546        try {
20547            synchronized (this) {
20548                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20549                // its own permission (same as profileControl).
20550                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20551                        != PackageManager.PERMISSION_GRANTED) {
20552                    throw new SecurityException("Requires permission "
20553                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20554                }
20555
20556                if (fd == null) {
20557                    throw new IllegalArgumentException("null fd");
20558                }
20559
20560                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20561                if (proc == null || proc.thread == null) {
20562                    throw new IllegalArgumentException("Unknown process: " + process);
20563                }
20564
20565                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20566                if (!isDebuggable) {
20567                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20568                        throw new SecurityException("Process not debuggable: " + proc);
20569                    }
20570                }
20571
20572                proc.thread.dumpHeap(managed, path, fd);
20573                fd = null;
20574                return true;
20575            }
20576        } catch (RemoteException e) {
20577            throw new IllegalStateException("Process disappeared");
20578        } finally {
20579            if (fd != null) {
20580                try {
20581                    fd.close();
20582                } catch (IOException e) {
20583                }
20584            }
20585        }
20586    }
20587
20588    @Override
20589    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20590            String reportPackage) {
20591        if (processName != null) {
20592            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20593                    "setDumpHeapDebugLimit()");
20594        } else {
20595            synchronized (mPidsSelfLocked) {
20596                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20597                if (proc == null) {
20598                    throw new SecurityException("No process found for calling pid "
20599                            + Binder.getCallingPid());
20600                }
20601                if (!Build.IS_DEBUGGABLE
20602                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20603                    throw new SecurityException("Not running a debuggable build");
20604                }
20605                processName = proc.processName;
20606                uid = proc.uid;
20607                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20608                    throw new SecurityException("Package " + reportPackage + " is not running in "
20609                            + proc);
20610                }
20611            }
20612        }
20613        synchronized (this) {
20614            if (maxMemSize > 0) {
20615                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20616            } else {
20617                if (uid != 0) {
20618                    mMemWatchProcesses.remove(processName, uid);
20619                } else {
20620                    mMemWatchProcesses.getMap().remove(processName);
20621                }
20622            }
20623        }
20624    }
20625
20626    @Override
20627    public void dumpHeapFinished(String path) {
20628        synchronized (this) {
20629            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20630                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20631                        + " does not match last pid " + mMemWatchDumpPid);
20632                return;
20633            }
20634            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20635                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20636                        + " does not match last path " + mMemWatchDumpFile);
20637                return;
20638            }
20639            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20640            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20641        }
20642    }
20643
20644    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20645    public void monitor() {
20646        synchronized (this) { }
20647    }
20648
20649    void onCoreSettingsChange(Bundle settings) {
20650        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20651            ProcessRecord processRecord = mLruProcesses.get(i);
20652            try {
20653                if (processRecord.thread != null) {
20654                    processRecord.thread.setCoreSettings(settings);
20655                }
20656            } catch (RemoteException re) {
20657                /* ignore */
20658            }
20659        }
20660    }
20661
20662    // Multi-user methods
20663
20664    /**
20665     * Start user, if its not already running, but don't bring it to foreground.
20666     */
20667    @Override
20668    public boolean startUserInBackground(final int userId) {
20669        return mUserController.startUser(userId, /* foreground */ false);
20670    }
20671
20672    @Override
20673    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20674        return mUserController.unlockUser(userId, token, secret, new ProgressReporter(0, listener));
20675    }
20676
20677    @Override
20678    public boolean switchUser(final int targetUserId) {
20679        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20680        UserInfo currentUserInfo;
20681        UserInfo targetUserInfo;
20682        synchronized (this) {
20683            int currentUserId = mUserController.getCurrentUserIdLocked();
20684            currentUserInfo = mUserController.getUserInfo(currentUserId);
20685            targetUserInfo = mUserController.getUserInfo(targetUserId);
20686            if (targetUserInfo == null) {
20687                Slog.w(TAG, "No user info for user #" + targetUserId);
20688                return false;
20689            }
20690            if (!targetUserInfo.supportsSwitchTo()) {
20691                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20692                return false;
20693            }
20694            if (targetUserInfo.isManagedProfile()) {
20695                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20696                return false;
20697            }
20698            mUserController.setTargetUserIdLocked(targetUserId);
20699        }
20700        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20701        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20702        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20703        return true;
20704    }
20705
20706    void scheduleStartProfilesLocked() {
20707        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20708            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20709                    DateUtils.SECOND_IN_MILLIS);
20710        }
20711    }
20712
20713    @Override
20714    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20715        return mUserController.stopUser(userId, force, callback);
20716    }
20717
20718    @Override
20719    public UserInfo getCurrentUser() {
20720        return mUserController.getCurrentUser();
20721    }
20722
20723    @Override
20724    public boolean isUserRunning(int userId, int flags) {
20725        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20726                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20727            String msg = "Permission Denial: isUserRunning() from pid="
20728                    + Binder.getCallingPid()
20729                    + ", uid=" + Binder.getCallingUid()
20730                    + " requires " + INTERACT_ACROSS_USERS;
20731            Slog.w(TAG, msg);
20732            throw new SecurityException(msg);
20733        }
20734        synchronized (this) {
20735            return mUserController.isUserRunningLocked(userId, flags);
20736        }
20737    }
20738
20739    @Override
20740    public int[] getRunningUserIds() {
20741        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20742                != PackageManager.PERMISSION_GRANTED) {
20743            String msg = "Permission Denial: isUserRunning() from pid="
20744                    + Binder.getCallingPid()
20745                    + ", uid=" + Binder.getCallingUid()
20746                    + " requires " + INTERACT_ACROSS_USERS;
20747            Slog.w(TAG, msg);
20748            throw new SecurityException(msg);
20749        }
20750        synchronized (this) {
20751            return mUserController.getStartedUserArrayLocked();
20752        }
20753    }
20754
20755    @Override
20756    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20757        mUserController.registerUserSwitchObserver(observer);
20758    }
20759
20760    @Override
20761    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20762        mUserController.unregisterUserSwitchObserver(observer);
20763    }
20764
20765    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20766        if (info == null) return null;
20767        ApplicationInfo newInfo = new ApplicationInfo(info);
20768        newInfo.initForUser(userId);
20769        return newInfo;
20770    }
20771
20772    public boolean isUserStopped(int userId) {
20773        synchronized (this) {
20774            return mUserController.getStartedUserStateLocked(userId) == null;
20775        }
20776    }
20777
20778    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20779        if (aInfo == null
20780                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20781            return aInfo;
20782        }
20783
20784        ActivityInfo info = new ActivityInfo(aInfo);
20785        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20786        return info;
20787    }
20788
20789    private boolean processSanityChecksLocked(ProcessRecord process) {
20790        if (process == null || process.thread == null) {
20791            return false;
20792        }
20793
20794        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20795        if (!isDebuggable) {
20796            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20797                return false;
20798            }
20799        }
20800
20801        return true;
20802    }
20803
20804    public boolean startBinderTracking() throws RemoteException {
20805        synchronized (this) {
20806            mBinderTransactionTrackingEnabled = true;
20807            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20808            // permission (same as profileControl).
20809            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20810                    != PackageManager.PERMISSION_GRANTED) {
20811                throw new SecurityException("Requires permission "
20812                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20813            }
20814
20815            for (int i = 0; i < mLruProcesses.size(); i++) {
20816                ProcessRecord process = mLruProcesses.get(i);
20817                if (!processSanityChecksLocked(process)) {
20818                    continue;
20819                }
20820                try {
20821                    process.thread.startBinderTracking();
20822                } catch (RemoteException e) {
20823                    Log.v(TAG, "Process disappared");
20824                }
20825            }
20826            return true;
20827        }
20828    }
20829
20830    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20831        try {
20832            synchronized (this) {
20833                mBinderTransactionTrackingEnabled = false;
20834                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20835                // permission (same as profileControl).
20836                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20837                        != PackageManager.PERMISSION_GRANTED) {
20838                    throw new SecurityException("Requires permission "
20839                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20840                }
20841
20842                if (fd == null) {
20843                    throw new IllegalArgumentException("null fd");
20844                }
20845
20846                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20847                pw.println("Binder transaction traces for all processes.\n");
20848                for (ProcessRecord process : mLruProcesses) {
20849                    if (!processSanityChecksLocked(process)) {
20850                        continue;
20851                    }
20852
20853                    pw.println("Traces for process: " + process.processName);
20854                    pw.flush();
20855                    try {
20856                        TransferPipe tp = new TransferPipe();
20857                        try {
20858                            process.thread.stopBinderTrackingAndDump(
20859                                    tp.getWriteFd().getFileDescriptor());
20860                            tp.go(fd.getFileDescriptor());
20861                        } finally {
20862                            tp.kill();
20863                        }
20864                    } catch (IOException e) {
20865                        pw.println("Failure while dumping IPC traces from " + process +
20866                                ".  Exception: " + e);
20867                        pw.flush();
20868                    } catch (RemoteException e) {
20869                        pw.println("Got a RemoteException while dumping IPC traces from " +
20870                                process + ".  Exception: " + e);
20871                        pw.flush();
20872                    }
20873                }
20874                fd = null;
20875                return true;
20876            }
20877        } finally {
20878            if (fd != null) {
20879                try {
20880                    fd.close();
20881                } catch (IOException e) {
20882                }
20883            }
20884        }
20885    }
20886
20887    private final class LocalService extends ActivityManagerInternal {
20888        @Override
20889        public void onWakefulnessChanged(int wakefulness) {
20890            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20891        }
20892
20893        @Override
20894        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20895                String processName, String abiOverride, int uid, Runnable crashHandler) {
20896            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20897                    processName, abiOverride, uid, crashHandler);
20898        }
20899
20900        @Override
20901        public SleepToken acquireSleepToken(String tag) {
20902            Preconditions.checkNotNull(tag);
20903
20904            synchronized (ActivityManagerService.this) {
20905                SleepTokenImpl token = new SleepTokenImpl(tag);
20906                mSleepTokens.add(token);
20907                updateSleepIfNeededLocked();
20908                return token;
20909            }
20910        }
20911
20912        @Override
20913        public ComponentName getHomeActivityForUser(int userId) {
20914            synchronized (ActivityManagerService.this) {
20915                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20916                return homeActivity == null ? null : homeActivity.realActivity;
20917            }
20918        }
20919
20920        @Override
20921        public void onUserRemoved(int userId) {
20922            synchronized (ActivityManagerService.this) {
20923                ActivityManagerService.this.onUserStoppedLocked(userId);
20924            }
20925        }
20926
20927        @Override
20928        public void onLocalVoiceInteractionStarted(IBinder activity,
20929                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20930            synchronized (ActivityManagerService.this) {
20931                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20932                        voiceSession, voiceInteractor);
20933            }
20934        }
20935
20936        @Override
20937        public void notifyStartingWindowDrawn() {
20938            synchronized (ActivityManagerService.this) {
20939                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20940            }
20941        }
20942
20943        @Override
20944        public void notifyAppTransitionStarting(int reason) {
20945            synchronized (ActivityManagerService.this) {
20946                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20947            }
20948        }
20949
20950        @Override
20951        public void notifyAppTransitionFinished() {
20952            synchronized (ActivityManagerService.this) {
20953                mStackSupervisor.notifyAppTransitionDone();
20954            }
20955        }
20956
20957        @Override
20958        public void notifyAppTransitionCancelled() {
20959            synchronized (ActivityManagerService.this) {
20960                mStackSupervisor.notifyAppTransitionDone();
20961            }
20962        }
20963    }
20964
20965    private final class SleepTokenImpl extends SleepToken {
20966        private final String mTag;
20967        private final long mAcquireTime;
20968
20969        public SleepTokenImpl(String tag) {
20970            mTag = tag;
20971            mAcquireTime = SystemClock.uptimeMillis();
20972        }
20973
20974        @Override
20975        public void release() {
20976            synchronized (ActivityManagerService.this) {
20977                if (mSleepTokens.remove(this)) {
20978                    updateSleepIfNeededLocked();
20979                }
20980            }
20981        }
20982
20983        @Override
20984        public String toString() {
20985            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20986        }
20987    }
20988
20989    /**
20990     * An implementation of IAppTask, that allows an app to manage its own tasks via
20991     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20992     * only the process that calls getAppTasks() can call the AppTask methods.
20993     */
20994    class AppTaskImpl extends IAppTask.Stub {
20995        private int mTaskId;
20996        private int mCallingUid;
20997
20998        public AppTaskImpl(int taskId, int callingUid) {
20999            mTaskId = taskId;
21000            mCallingUid = callingUid;
21001        }
21002
21003        private void checkCaller() {
21004            if (mCallingUid != Binder.getCallingUid()) {
21005                throw new SecurityException("Caller " + mCallingUid
21006                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21007            }
21008        }
21009
21010        @Override
21011        public void finishAndRemoveTask() {
21012            checkCaller();
21013
21014            synchronized (ActivityManagerService.this) {
21015                long origId = Binder.clearCallingIdentity();
21016                try {
21017                    // We remove the task from recents to preserve backwards
21018                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21019                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21020                    }
21021                } finally {
21022                    Binder.restoreCallingIdentity(origId);
21023                }
21024            }
21025        }
21026
21027        @Override
21028        public ActivityManager.RecentTaskInfo getTaskInfo() {
21029            checkCaller();
21030
21031            synchronized (ActivityManagerService.this) {
21032                long origId = Binder.clearCallingIdentity();
21033                try {
21034                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21035                    if (tr == null) {
21036                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21037                    }
21038                    return createRecentTaskInfoFromTaskRecord(tr);
21039                } finally {
21040                    Binder.restoreCallingIdentity(origId);
21041                }
21042            }
21043        }
21044
21045        @Override
21046        public void moveToFront() {
21047            checkCaller();
21048            // Will bring task to front if it already has a root activity.
21049            final long origId = Binder.clearCallingIdentity();
21050            try {
21051                synchronized (this) {
21052                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21053                }
21054            } finally {
21055                Binder.restoreCallingIdentity(origId);
21056            }
21057        }
21058
21059        @Override
21060        public int startActivity(IBinder whoThread, String callingPackage,
21061                Intent intent, String resolvedType, Bundle bOptions) {
21062            checkCaller();
21063
21064            int callingUser = UserHandle.getCallingUserId();
21065            TaskRecord tr;
21066            IApplicationThread appThread;
21067            synchronized (ActivityManagerService.this) {
21068                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21069                if (tr == null) {
21070                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21071                }
21072                appThread = ApplicationThreadNative.asInterface(whoThread);
21073                if (appThread == null) {
21074                    throw new IllegalArgumentException("Bad app thread " + appThread);
21075                }
21076            }
21077            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21078                    resolvedType, null, null, null, null, 0, 0, null, null,
21079                    null, bOptions, false, callingUser, null, tr);
21080        }
21081
21082        @Override
21083        public void setExcludeFromRecents(boolean exclude) {
21084            checkCaller();
21085
21086            synchronized (ActivityManagerService.this) {
21087                long origId = Binder.clearCallingIdentity();
21088                try {
21089                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21090                    if (tr == null) {
21091                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21092                    }
21093                    Intent intent = tr.getBaseIntent();
21094                    if (exclude) {
21095                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21096                    } else {
21097                        intent.setFlags(intent.getFlags()
21098                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21099                    }
21100                } finally {
21101                    Binder.restoreCallingIdentity(origId);
21102                }
21103            }
21104        }
21105    }
21106
21107    /**
21108     * Kill processes for the user with id userId and that depend on the package named packageName
21109     */
21110    @Override
21111    public void killPackageDependents(String packageName, int userId) {
21112        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21113        if (packageName == null) {
21114            throw new NullPointerException(
21115                    "Cannot kill the dependents of a package without its name.");
21116        }
21117
21118        long callingId = Binder.clearCallingIdentity();
21119        IPackageManager pm = AppGlobals.getPackageManager();
21120        int pkgUid = -1;
21121        try {
21122            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21123        } catch (RemoteException e) {
21124        }
21125        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21126            throw new IllegalArgumentException(
21127                    "Cannot kill dependents of non-existing package " + packageName);
21128        }
21129        try {
21130            synchronized(this) {
21131                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21132                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21133                        "dep: " + packageName);
21134            }
21135        } finally {
21136            Binder.restoreCallingIdentity(callingId);
21137        }
21138    }
21139}
21140