ActivityManagerService.java revision c27916642d59c9d13a5e33019871149971e5fe57
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                    false /* forceNonResizable */);
9429        } finally {
9430            Binder.restoreCallingIdentity(origId);
9431        }
9432        ActivityOptions.abort(options);
9433    }
9434
9435    /**
9436     * Moves an activity, and all of the other activities within the same task, to the bottom
9437     * of the history stack.  The activity's order within the task is unchanged.
9438     *
9439     * @param token A reference to the activity we wish to move
9440     * @param nonRoot If false then this only works if the activity is the root
9441     *                of a task; if true it will work for any activity in a task.
9442     * @return Returns true if the move completed, false if not.
9443     */
9444    @Override
9445    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9446        enforceNotIsolatedCaller("moveActivityTaskToBack");
9447        synchronized(this) {
9448            final long origId = Binder.clearCallingIdentity();
9449            try {
9450                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9451                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9452                if (task != null) {
9453                    if (mStackSupervisor.isLockedTask(task)) {
9454                        mStackSupervisor.showLockTaskToast();
9455                        return false;
9456                    }
9457                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9458                }
9459            } finally {
9460                Binder.restoreCallingIdentity(origId);
9461            }
9462        }
9463        return false;
9464    }
9465
9466    @Override
9467    public void moveTaskBackwards(int task) {
9468        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9469                "moveTaskBackwards()");
9470
9471        synchronized(this) {
9472            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9473                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9474                return;
9475            }
9476            final long origId = Binder.clearCallingIdentity();
9477            moveTaskBackwardsLocked(task);
9478            Binder.restoreCallingIdentity(origId);
9479        }
9480    }
9481
9482    private final void moveTaskBackwardsLocked(int task) {
9483        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9484    }
9485
9486    @Override
9487    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9488            IActivityContainerCallback callback) throws RemoteException {
9489        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9490        synchronized (this) {
9491            if (parentActivityToken == null) {
9492                throw new IllegalArgumentException("parent token must not be null");
9493            }
9494            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9495            if (r == null) {
9496                return null;
9497            }
9498            if (callback == null) {
9499                throw new IllegalArgumentException("callback must not be null");
9500            }
9501            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9502        }
9503    }
9504
9505    @Override
9506    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9507        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9508        synchronized (this) {
9509            mStackSupervisor.deleteActivityContainer(container);
9510        }
9511    }
9512
9513    @Override
9514    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9515        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9516        synchronized (this) {
9517            final int stackId = mStackSupervisor.getNextStackId();
9518            final ActivityStack stack =
9519                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9520            if (stack == null) {
9521                return null;
9522            }
9523            return stack.mActivityContainer;
9524        }
9525    }
9526
9527    @Override
9528    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9529        synchronized (this) {
9530            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9531            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9532                return stack.mActivityContainer.getDisplayId();
9533            }
9534            return Display.DEFAULT_DISPLAY;
9535        }
9536    }
9537
9538    @Override
9539    public int getActivityStackId(IBinder token) throws RemoteException {
9540        synchronized (this) {
9541            ActivityStack stack = ActivityRecord.getStackLocked(token);
9542            if (stack == null) {
9543                return INVALID_STACK_ID;
9544            }
9545            return stack.mStackId;
9546        }
9547    }
9548
9549    @Override
9550    public void exitFreeformMode(IBinder token) throws RemoteException {
9551        synchronized (this) {
9552            long ident = Binder.clearCallingIdentity();
9553            try {
9554                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9555                if (r == null) {
9556                    throw new IllegalArgumentException(
9557                            "exitFreeformMode: No activity record matching token=" + token);
9558                }
9559                final ActivityStack stack = r.getStackLocked(token);
9560                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9561                    throw new IllegalStateException(
9562                            "exitFreeformMode: You can only go fullscreen from freeform.");
9563                }
9564                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9565                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9566                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9567            } finally {
9568                Binder.restoreCallingIdentity(ident);
9569            }
9570        }
9571    }
9572
9573    @Override
9574    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9575        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9576        if (stackId == HOME_STACK_ID) {
9577            throw new IllegalArgumentException(
9578                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9579        }
9580        synchronized (this) {
9581            long ident = Binder.clearCallingIdentity();
9582            try {
9583                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9584                        + " to stackId=" + stackId + " toTop=" + toTop);
9585                if (stackId == DOCKED_STACK_ID) {
9586                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9587                            null /* initialBounds */);
9588                }
9589                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9590                        "moveTaskToStack", ANIMATE);
9591            } finally {
9592                Binder.restoreCallingIdentity(ident);
9593            }
9594        }
9595    }
9596
9597    @Override
9598    public void swapDockedAndFullscreenStack() throws RemoteException {
9599        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9600        synchronized (this) {
9601            long ident = Binder.clearCallingIdentity();
9602            try {
9603                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9604                        FULLSCREEN_WORKSPACE_STACK_ID);
9605                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9606                        : null;
9607                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9608                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9609                        : null;
9610                if (topTask == null || tasks == null || tasks.size() == 0) {
9611                    Slog.w(TAG,
9612                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9613                    return;
9614                }
9615
9616                // TODO: App transition
9617                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9618
9619                // Defer the resume so resume/pausing while moving stacks is dangerous.
9620                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9621                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9622                        ANIMATE, true /* deferResume */);
9623                final int size = tasks.size();
9624                for (int i = 0; i < size; i++) {
9625                    final int id = tasks.get(i).taskId;
9626                    if (id == topTask.taskId) {
9627                        continue;
9628                    }
9629                    mStackSupervisor.moveTaskToStackLocked(id,
9630                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9631                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9632                }
9633
9634                // Because we deferred the resume, to avoid conflicts with stack switches while
9635                // resuming, we need to do it after all the tasks are moved.
9636                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9637                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9638
9639                mWindowManager.executeAppTransition();
9640            } finally {
9641                Binder.restoreCallingIdentity(ident);
9642            }
9643        }
9644    }
9645
9646    /**
9647     * Moves the input task to the docked stack.
9648     *
9649     * @param taskId Id of task to move.
9650     * @param createMode The mode the docked stack should be created in if it doesn't exist
9651     *                   already. See
9652     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9653     *                   and
9654     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9655     * @param toTop If the task and stack should be moved to the top.
9656     * @param animate Whether we should play an animation for the moving the task
9657     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9658     *                      docked stack. Pass {@code null} to use default bounds.
9659     */
9660    @Override
9661    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9662            Rect initialBounds) {
9663        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9664        synchronized (this) {
9665            long ident = Binder.clearCallingIdentity();
9666            try {
9667                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9668                        + " to createMode=" + createMode + " toTop=" + toTop);
9669                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9670                return mStackSupervisor.moveTaskToStackLocked(
9671                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9672                        "moveTaskToDockedStack", animate);
9673            } finally {
9674                Binder.restoreCallingIdentity(ident);
9675            }
9676        }
9677    }
9678
9679    /**
9680     * Moves the top activity in the input stackId to the pinned stack.
9681     *
9682     * @param stackId Id of stack to move the top activity to pinned stack.
9683     * @param bounds Bounds to use for pinned stack.
9684     *
9685     * @return True if the top activity of the input stack was successfully moved to the pinned
9686     *          stack.
9687     */
9688    @Override
9689    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9690        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9691        synchronized (this) {
9692            if (!mSupportsPictureInPicture) {
9693                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9694                        + "Device doesn't support picture-in-pciture mode");
9695            }
9696
9697            long ident = Binder.clearCallingIdentity();
9698            try {
9699                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9700            } finally {
9701                Binder.restoreCallingIdentity(ident);
9702            }
9703        }
9704    }
9705
9706    @Override
9707    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9708            boolean preserveWindows, boolean animate, int animationDuration) {
9709        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9710        long ident = Binder.clearCallingIdentity();
9711        try {
9712            synchronized (this) {
9713                if (animate) {
9714                    if (stackId == PINNED_STACK_ID) {
9715                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9716                    } else {
9717                        throw new IllegalArgumentException("Stack: " + stackId
9718                                + " doesn't support animated resize.");
9719                    }
9720                } else {
9721                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9722                            null /* tempTaskInsetBounds */, preserveWindows,
9723                            allowResizeInDockedMode);
9724                }
9725            }
9726        } finally {
9727            Binder.restoreCallingIdentity(ident);
9728        }
9729    }
9730
9731    @Override
9732    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9733            Rect tempDockedTaskInsetBounds,
9734            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9735        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9736                "resizeDockedStack()");
9737        long ident = Binder.clearCallingIdentity();
9738        try {
9739            synchronized (this) {
9740                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9741                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9742                        PRESERVE_WINDOWS);
9743            }
9744        } finally {
9745            Binder.restoreCallingIdentity(ident);
9746        }
9747    }
9748
9749    @Override
9750    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9751        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9752                "resizePinnedStack()");
9753        final long ident = Binder.clearCallingIdentity();
9754        try {
9755            synchronized (this) {
9756                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9757            }
9758        } finally {
9759            Binder.restoreCallingIdentity(ident);
9760        }
9761    }
9762
9763    @Override
9764    public void positionTaskInStack(int taskId, int stackId, int position) {
9765        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9766        if (stackId == HOME_STACK_ID) {
9767            throw new IllegalArgumentException(
9768                    "positionTaskInStack: Attempt to change the position of task "
9769                    + taskId + " in/to home stack");
9770        }
9771        synchronized (this) {
9772            long ident = Binder.clearCallingIdentity();
9773            try {
9774                if (DEBUG_STACK) Slog.d(TAG_STACK,
9775                        "positionTaskInStack: positioning task=" + taskId
9776                        + " in stackId=" + stackId + " at position=" + position);
9777                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9778            } finally {
9779                Binder.restoreCallingIdentity(ident);
9780            }
9781        }
9782    }
9783
9784    @Override
9785    public List<StackInfo> getAllStackInfos() {
9786        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9787        long ident = Binder.clearCallingIdentity();
9788        try {
9789            synchronized (this) {
9790                return mStackSupervisor.getAllStackInfosLocked();
9791            }
9792        } finally {
9793            Binder.restoreCallingIdentity(ident);
9794        }
9795    }
9796
9797    @Override
9798    public StackInfo getStackInfo(int stackId) {
9799        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9800        long ident = Binder.clearCallingIdentity();
9801        try {
9802            synchronized (this) {
9803                return mStackSupervisor.getStackInfoLocked(stackId);
9804            }
9805        } finally {
9806            Binder.restoreCallingIdentity(ident);
9807        }
9808    }
9809
9810    @Override
9811    public boolean isInHomeStack(int taskId) {
9812        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9813        long ident = Binder.clearCallingIdentity();
9814        try {
9815            synchronized (this) {
9816                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9817                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9818                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9819            }
9820        } finally {
9821            Binder.restoreCallingIdentity(ident);
9822        }
9823    }
9824
9825    @Override
9826    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9827        synchronized(this) {
9828            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9829        }
9830    }
9831
9832    @Override
9833    public void updateDeviceOwner(String packageName) {
9834        final int callingUid = Binder.getCallingUid();
9835        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9836            throw new SecurityException("updateDeviceOwner called from non-system process");
9837        }
9838        synchronized (this) {
9839            mDeviceOwnerName = packageName;
9840        }
9841    }
9842
9843    @Override
9844    public void updateLockTaskPackages(int userId, String[] packages) {
9845        final int callingUid = Binder.getCallingUid();
9846        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9847            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9848                    "updateLockTaskPackages()");
9849        }
9850        synchronized (this) {
9851            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9852                    Arrays.toString(packages));
9853            mLockTaskPackages.put(userId, packages);
9854            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9855        }
9856    }
9857
9858
9859    void startLockTaskModeLocked(TaskRecord task) {
9860        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9861        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9862            return;
9863        }
9864
9865        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9866        // is initiated by system after the pinning request was shown and locked mode is initiated
9867        // by an authorized app directly
9868        final int callingUid = Binder.getCallingUid();
9869        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9870        long ident = Binder.clearCallingIdentity();
9871        try {
9872            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9873            if (!isSystemInitiated) {
9874                task.mLockTaskUid = callingUid;
9875                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9876                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9877                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9878                    StatusBarManagerInternal statusBarManager =
9879                            LocalServices.getService(StatusBarManagerInternal.class);
9880                    if (statusBarManager != null) {
9881                        statusBarManager.showScreenPinningRequest();
9882                    }
9883                    return;
9884                }
9885
9886                if (stack == null || task != stack.topTask()) {
9887                    throw new IllegalArgumentException("Invalid task, not in foreground");
9888                }
9889            }
9890            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9891                    "Locking fully");
9892            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9893                    ActivityManager.LOCK_TASK_MODE_PINNED :
9894                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9895                    "startLockTask", true);
9896        } finally {
9897            Binder.restoreCallingIdentity(ident);
9898        }
9899    }
9900
9901    @Override
9902    public void startLockTaskMode(int taskId) {
9903        synchronized (this) {
9904            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9905            if (task != null) {
9906                startLockTaskModeLocked(task);
9907            }
9908        }
9909    }
9910
9911    @Override
9912    public void startLockTaskMode(IBinder token) {
9913        synchronized (this) {
9914            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9915            if (r == null) {
9916                return;
9917            }
9918            final TaskRecord task = r.task;
9919            if (task != null) {
9920                startLockTaskModeLocked(task);
9921            }
9922        }
9923    }
9924
9925    @Override
9926    public void startLockTaskModeOnCurrent() throws RemoteException {
9927        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9928        long ident = Binder.clearCallingIdentity();
9929        try {
9930            synchronized (this) {
9931                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9932                if (r != null) {
9933                    startLockTaskModeLocked(r.task);
9934                }
9935            }
9936        } finally {
9937            Binder.restoreCallingIdentity(ident);
9938        }
9939    }
9940
9941    @Override
9942    public void stopLockTaskMode() {
9943        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9944        if (lockTask == null) {
9945            // Our work here is done.
9946            return;
9947        }
9948
9949        final int callingUid = Binder.getCallingUid();
9950        final int lockTaskUid = lockTask.mLockTaskUid;
9951        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9952        // It is possible lockTaskMode was started by the system process because
9953        // android:lockTaskMode is set to a locking value in the application manifest instead of
9954        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9955        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9956        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9957                callingUid != lockTaskUid
9958                && (lockTaskUid != 0
9959                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9960            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9961                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9962        }
9963
9964        long ident = Binder.clearCallingIdentity();
9965        try {
9966            Log.d(TAG, "stopLockTaskMode");
9967            // Stop lock task
9968            synchronized (this) {
9969                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9970                        "stopLockTask", true);
9971            }
9972        } finally {
9973            Binder.restoreCallingIdentity(ident);
9974        }
9975    }
9976
9977    @Override
9978    public void stopLockTaskModeOnCurrent() throws RemoteException {
9979        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9980        long ident = Binder.clearCallingIdentity();
9981        try {
9982            stopLockTaskMode();
9983        } finally {
9984            Binder.restoreCallingIdentity(ident);
9985        }
9986    }
9987
9988    @Override
9989    public boolean isInLockTaskMode() {
9990        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9991    }
9992
9993    @Override
9994    public int getLockTaskModeState() {
9995        synchronized (this) {
9996            return mStackSupervisor.getLockTaskModeState();
9997        }
9998    }
9999
10000    @Override
10001    public void showLockTaskEscapeMessage(IBinder token) {
10002        synchronized (this) {
10003            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10004            if (r == null) {
10005                return;
10006            }
10007            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10008        }
10009    }
10010
10011    // =========================================================
10012    // CONTENT PROVIDERS
10013    // =========================================================
10014
10015    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10016        List<ProviderInfo> providers = null;
10017        try {
10018            providers = AppGlobals.getPackageManager()
10019                    .queryContentProviders(app.processName, app.uid,
10020                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10021                                    | MATCH_DEBUG_TRIAGED_MISSING)
10022                    .getList();
10023        } catch (RemoteException ex) {
10024        }
10025        if (DEBUG_MU) Slog.v(TAG_MU,
10026                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10027        int userId = app.userId;
10028        if (providers != null) {
10029            int N = providers.size();
10030            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10031            for (int i=0; i<N; i++) {
10032                ProviderInfo cpi =
10033                    (ProviderInfo)providers.get(i);
10034                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10035                        cpi.name, cpi.flags);
10036                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10037                    // This is a singleton provider, but a user besides the
10038                    // default user is asking to initialize a process it runs
10039                    // in...  well, no, it doesn't actually run in this process,
10040                    // it runs in the process of the default user.  Get rid of it.
10041                    providers.remove(i);
10042                    N--;
10043                    i--;
10044                    continue;
10045                }
10046
10047                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10048                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10049                if (cpr == null) {
10050                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10051                    mProviderMap.putProviderByClass(comp, cpr);
10052                }
10053                if (DEBUG_MU) Slog.v(TAG_MU,
10054                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10055                app.pubProviders.put(cpi.name, cpr);
10056                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10057                    // Don't add this if it is a platform component that is marked
10058                    // to run in multiple processes, because this is actually
10059                    // part of the framework so doesn't make sense to track as a
10060                    // separate apk in the process.
10061                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10062                            mProcessStats);
10063                }
10064                notifyPackageUse(cpi.applicationInfo.packageName);
10065            }
10066        }
10067        return providers;
10068    }
10069
10070    /**
10071     * Check if {@link ProcessRecord} has a possible chance at accessing the
10072     * given {@link ProviderInfo}. Final permission checking is always done
10073     * in {@link ContentProvider}.
10074     */
10075    private final String checkContentProviderPermissionLocked(
10076            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10077        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10078        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10079        boolean checkedGrants = false;
10080        if (checkUser) {
10081            // Looking for cross-user grants before enforcing the typical cross-users permissions
10082            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10083            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10084                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10085                    return null;
10086                }
10087                checkedGrants = true;
10088            }
10089            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10090                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10091            if (userId != tmpTargetUserId) {
10092                // When we actually went to determine the final targer user ID, this ended
10093                // up different than our initial check for the authority.  This is because
10094                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10095                // SELF.  So we need to re-check the grants again.
10096                checkedGrants = false;
10097            }
10098        }
10099        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10100                cpi.applicationInfo.uid, cpi.exported)
10101                == PackageManager.PERMISSION_GRANTED) {
10102            return null;
10103        }
10104        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10105                cpi.applicationInfo.uid, cpi.exported)
10106                == PackageManager.PERMISSION_GRANTED) {
10107            return null;
10108        }
10109
10110        PathPermission[] pps = cpi.pathPermissions;
10111        if (pps != null) {
10112            int i = pps.length;
10113            while (i > 0) {
10114                i--;
10115                PathPermission pp = pps[i];
10116                String pprperm = pp.getReadPermission();
10117                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10118                        cpi.applicationInfo.uid, cpi.exported)
10119                        == PackageManager.PERMISSION_GRANTED) {
10120                    return null;
10121                }
10122                String ppwperm = pp.getWritePermission();
10123                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10124                        cpi.applicationInfo.uid, cpi.exported)
10125                        == PackageManager.PERMISSION_GRANTED) {
10126                    return null;
10127                }
10128            }
10129        }
10130        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10131            return null;
10132        }
10133
10134        String msg;
10135        if (!cpi.exported) {
10136            msg = "Permission Denial: opening provider " + cpi.name
10137                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10138                    + ", uid=" + callingUid + ") that is not exported from uid "
10139                    + cpi.applicationInfo.uid;
10140        } else {
10141            msg = "Permission Denial: opening provider " + cpi.name
10142                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10143                    + ", uid=" + callingUid + ") requires "
10144                    + cpi.readPermission + " or " + cpi.writePermission;
10145        }
10146        Slog.w(TAG, msg);
10147        return msg;
10148    }
10149
10150    /**
10151     * Returns if the ContentProvider has granted a uri to callingUid
10152     */
10153    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10154        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10155        if (perms != null) {
10156            for (int i=perms.size()-1; i>=0; i--) {
10157                GrantUri grantUri = perms.keyAt(i);
10158                if (grantUri.sourceUserId == userId || !checkUser) {
10159                    if (matchesProvider(grantUri.uri, cpi)) {
10160                        return true;
10161                    }
10162                }
10163            }
10164        }
10165        return false;
10166    }
10167
10168    /**
10169     * Returns true if the uri authority is one of the authorities specified in the provider.
10170     */
10171    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10172        String uriAuth = uri.getAuthority();
10173        String cpiAuth = cpi.authority;
10174        if (cpiAuth.indexOf(';') == -1) {
10175            return cpiAuth.equals(uriAuth);
10176        }
10177        String[] cpiAuths = cpiAuth.split(";");
10178        int length = cpiAuths.length;
10179        for (int i = 0; i < length; i++) {
10180            if (cpiAuths[i].equals(uriAuth)) return true;
10181        }
10182        return false;
10183    }
10184
10185    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10186            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10187        if (r != null) {
10188            for (int i=0; i<r.conProviders.size(); i++) {
10189                ContentProviderConnection conn = r.conProviders.get(i);
10190                if (conn.provider == cpr) {
10191                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10192                            "Adding provider requested by "
10193                            + r.processName + " from process "
10194                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10195                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10196                    if (stable) {
10197                        conn.stableCount++;
10198                        conn.numStableIncs++;
10199                    } else {
10200                        conn.unstableCount++;
10201                        conn.numUnstableIncs++;
10202                    }
10203                    return conn;
10204                }
10205            }
10206            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10207            if (stable) {
10208                conn.stableCount = 1;
10209                conn.numStableIncs = 1;
10210            } else {
10211                conn.unstableCount = 1;
10212                conn.numUnstableIncs = 1;
10213            }
10214            cpr.connections.add(conn);
10215            r.conProviders.add(conn);
10216            startAssociationLocked(r.uid, r.processName, r.curProcState,
10217                    cpr.uid, cpr.name, cpr.info.processName);
10218            return conn;
10219        }
10220        cpr.addExternalProcessHandleLocked(externalProcessToken);
10221        return null;
10222    }
10223
10224    boolean decProviderCountLocked(ContentProviderConnection conn,
10225            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10226        if (conn != null) {
10227            cpr = conn.provider;
10228            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10229                    "Removing provider requested by "
10230                    + conn.client.processName + " from process "
10231                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10232                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10233            if (stable) {
10234                conn.stableCount--;
10235            } else {
10236                conn.unstableCount--;
10237            }
10238            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10239                cpr.connections.remove(conn);
10240                conn.client.conProviders.remove(conn);
10241                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10242                    // The client is more important than last activity -- note the time this
10243                    // is happening, so we keep the old provider process around a bit as last
10244                    // activity to avoid thrashing it.
10245                    if (cpr.proc != null) {
10246                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10247                    }
10248                }
10249                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10250                return true;
10251            }
10252            return false;
10253        }
10254        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10255        return false;
10256    }
10257
10258    private void checkTime(long startTime, String where) {
10259        long now = SystemClock.elapsedRealtime();
10260        if ((now-startTime) > 1000) {
10261            // If we are taking more than a second, log about it.
10262            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10263        }
10264    }
10265
10266    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10267            String name, IBinder token, boolean stable, int userId) {
10268        ContentProviderRecord cpr;
10269        ContentProviderConnection conn = null;
10270        ProviderInfo cpi = null;
10271
10272        synchronized(this) {
10273            long startTime = SystemClock.elapsedRealtime();
10274
10275            ProcessRecord r = null;
10276            if (caller != null) {
10277                r = getRecordForAppLocked(caller);
10278                if (r == null) {
10279                    throw new SecurityException(
10280                            "Unable to find app for caller " + caller
10281                          + " (pid=" + Binder.getCallingPid()
10282                          + ") when getting content provider " + name);
10283                }
10284            }
10285
10286            boolean checkCrossUser = true;
10287
10288            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10289
10290            // First check if this content provider has been published...
10291            cpr = mProviderMap.getProviderByName(name, userId);
10292            // If that didn't work, check if it exists for user 0 and then
10293            // verify that it's a singleton provider before using it.
10294            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10295                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10296                if (cpr != null) {
10297                    cpi = cpr.info;
10298                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10299                            cpi.name, cpi.flags)
10300                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10301                        userId = UserHandle.USER_SYSTEM;
10302                        checkCrossUser = false;
10303                    } else {
10304                        cpr = null;
10305                        cpi = null;
10306                    }
10307                }
10308            }
10309
10310            boolean providerRunning = cpr != null;
10311            if (providerRunning) {
10312                cpi = cpr.info;
10313                String msg;
10314                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10315                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10316                        != null) {
10317                    throw new SecurityException(msg);
10318                }
10319                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10320
10321                if (r != null && cpr.canRunHere(r)) {
10322                    // This provider has been published or is in the process
10323                    // of being published...  but it is also allowed to run
10324                    // in the caller's process, so don't make a connection
10325                    // and just let the caller instantiate its own instance.
10326                    ContentProviderHolder holder = cpr.newHolder(null);
10327                    // don't give caller the provider object, it needs
10328                    // to make its own.
10329                    holder.provider = null;
10330                    return holder;
10331                }
10332
10333                final long origId = Binder.clearCallingIdentity();
10334
10335                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10336
10337                // In this case the provider instance already exists, so we can
10338                // return it right away.
10339                conn = incProviderCountLocked(r, cpr, token, stable);
10340                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10341                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10342                        // If this is a perceptible app accessing the provider,
10343                        // make sure to count it as being accessed and thus
10344                        // back up on the LRU list.  This is good because
10345                        // content providers are often expensive to start.
10346                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10347                        updateLruProcessLocked(cpr.proc, false, null);
10348                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10349                    }
10350                }
10351
10352                if (cpr.proc != null) {
10353                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10354                    boolean success = updateOomAdjLocked(cpr.proc);
10355                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10356                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10357                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10358                    // NOTE: there is still a race here where a signal could be
10359                    // pending on the process even though we managed to update its
10360                    // adj level.  Not sure what to do about this, but at least
10361                    // the race is now smaller.
10362                    if (!success) {
10363                        // Uh oh...  it looks like the provider's process
10364                        // has been killed on us.  We need to wait for a new
10365                        // process to be started, and make sure its death
10366                        // doesn't kill our process.
10367                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10368                                + " is crashing; detaching " + r);
10369                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10370                        checkTime(startTime, "getContentProviderImpl: before appDied");
10371                        appDiedLocked(cpr.proc);
10372                        checkTime(startTime, "getContentProviderImpl: after appDied");
10373                        if (!lastRef) {
10374                            // This wasn't the last ref our process had on
10375                            // the provider...  we have now been killed, bail.
10376                            return null;
10377                        }
10378                        providerRunning = false;
10379                        conn = null;
10380                    }
10381                }
10382
10383                Binder.restoreCallingIdentity(origId);
10384            }
10385
10386            if (!providerRunning) {
10387                try {
10388                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10389                    cpi = AppGlobals.getPackageManager().
10390                        resolveContentProvider(name,
10391                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10392                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10393                } catch (RemoteException ex) {
10394                }
10395                if (cpi == null) {
10396                    return null;
10397                }
10398                // If the provider is a singleton AND
10399                // (it's a call within the same user || the provider is a
10400                // privileged app)
10401                // Then allow connecting to the singleton provider
10402                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10403                        cpi.name, cpi.flags)
10404                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10405                if (singleton) {
10406                    userId = UserHandle.USER_SYSTEM;
10407                }
10408                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10409                checkTime(startTime, "getContentProviderImpl: got app info for user");
10410
10411                String msg;
10412                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10413                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10414                        != null) {
10415                    throw new SecurityException(msg);
10416                }
10417                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10418
10419                if (!mProcessesReady
10420                        && !cpi.processName.equals("system")) {
10421                    // If this content provider does not run in the system
10422                    // process, and the system is not yet ready to run other
10423                    // processes, then fail fast instead of hanging.
10424                    throw new IllegalArgumentException(
10425                            "Attempt to launch content provider before system ready");
10426                }
10427
10428                // Make sure that the user who owns this provider is running.  If not,
10429                // we don't want to allow it to run.
10430                if (!mUserController.isUserRunningLocked(userId, 0)) {
10431                    Slog.w(TAG, "Unable to launch app "
10432                            + cpi.applicationInfo.packageName + "/"
10433                            + cpi.applicationInfo.uid + " for provider "
10434                            + name + ": user " + userId + " is stopped");
10435                    return null;
10436                }
10437
10438                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10439                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10440                cpr = mProviderMap.getProviderByClass(comp, userId);
10441                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10442                final boolean firstClass = cpr == null;
10443                if (firstClass) {
10444                    final long ident = Binder.clearCallingIdentity();
10445
10446                    // If permissions need a review before any of the app components can run,
10447                    // we return no provider and launch a review activity if the calling app
10448                    // is in the foreground.
10449                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10450                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10451                            return null;
10452                        }
10453                    }
10454
10455                    try {
10456                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10457                        ApplicationInfo ai =
10458                            AppGlobals.getPackageManager().
10459                                getApplicationInfo(
10460                                        cpi.applicationInfo.packageName,
10461                                        STOCK_PM_FLAGS, userId);
10462                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10463                        if (ai == null) {
10464                            Slog.w(TAG, "No package info for content provider "
10465                                    + cpi.name);
10466                            return null;
10467                        }
10468                        ai = getAppInfoForUser(ai, userId);
10469                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10470                    } catch (RemoteException ex) {
10471                        // pm is in same process, this will never happen.
10472                    } finally {
10473                        Binder.restoreCallingIdentity(ident);
10474                    }
10475                }
10476
10477                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10478
10479                if (r != null && cpr.canRunHere(r)) {
10480                    // If this is a multiprocess provider, then just return its
10481                    // info and allow the caller to instantiate it.  Only do
10482                    // this if the provider is the same user as the caller's
10483                    // process, or can run as root (so can be in any process).
10484                    return cpr.newHolder(null);
10485                }
10486
10487                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10488                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10489                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10490
10491                // This is single process, and our app is now connecting to it.
10492                // See if we are already in the process of launching this
10493                // provider.
10494                final int N = mLaunchingProviders.size();
10495                int i;
10496                for (i = 0; i < N; i++) {
10497                    if (mLaunchingProviders.get(i) == cpr) {
10498                        break;
10499                    }
10500                }
10501
10502                // If the provider is not already being launched, then get it
10503                // started.
10504                if (i >= N) {
10505                    final long origId = Binder.clearCallingIdentity();
10506
10507                    try {
10508                        // Content provider is now in use, its package can't be stopped.
10509                        try {
10510                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10511                            AppGlobals.getPackageManager().setPackageStoppedState(
10512                                    cpr.appInfo.packageName, false, userId);
10513                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10514                        } catch (RemoteException e) {
10515                        } catch (IllegalArgumentException e) {
10516                            Slog.w(TAG, "Failed trying to unstop package "
10517                                    + cpr.appInfo.packageName + ": " + e);
10518                        }
10519
10520                        // Use existing process if already started
10521                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10522                        ProcessRecord proc = getProcessRecordLocked(
10523                                cpi.processName, cpr.appInfo.uid, false);
10524                        if (proc != null && proc.thread != null) {
10525                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10526                                    "Installing in existing process " + proc);
10527                            if (!proc.pubProviders.containsKey(cpi.name)) {
10528                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10529                                proc.pubProviders.put(cpi.name, cpr);
10530                                try {
10531                                    proc.thread.scheduleInstallProvider(cpi);
10532                                } catch (RemoteException e) {
10533                                }
10534                            }
10535                        } else {
10536                            checkTime(startTime, "getContentProviderImpl: before start process");
10537                            proc = startProcessLocked(cpi.processName,
10538                                    cpr.appInfo, false, 0, "content provider",
10539                                    new ComponentName(cpi.applicationInfo.packageName,
10540                                            cpi.name), false, false, false);
10541                            checkTime(startTime, "getContentProviderImpl: after start process");
10542                            if (proc == null) {
10543                                Slog.w(TAG, "Unable to launch app "
10544                                        + cpi.applicationInfo.packageName + "/"
10545                                        + cpi.applicationInfo.uid + " for provider "
10546                                        + name + ": process is bad");
10547                                return null;
10548                            }
10549                        }
10550                        cpr.launchingApp = proc;
10551                        mLaunchingProviders.add(cpr);
10552                    } finally {
10553                        Binder.restoreCallingIdentity(origId);
10554                    }
10555                }
10556
10557                checkTime(startTime, "getContentProviderImpl: updating data structures");
10558
10559                // Make sure the provider is published (the same provider class
10560                // may be published under multiple names).
10561                if (firstClass) {
10562                    mProviderMap.putProviderByClass(comp, cpr);
10563                }
10564
10565                mProviderMap.putProviderByName(name, cpr);
10566                conn = incProviderCountLocked(r, cpr, token, stable);
10567                if (conn != null) {
10568                    conn.waiting = true;
10569                }
10570            }
10571            checkTime(startTime, "getContentProviderImpl: done!");
10572        }
10573
10574        // Wait for the provider to be published...
10575        synchronized (cpr) {
10576            while (cpr.provider == null) {
10577                if (cpr.launchingApp == null) {
10578                    Slog.w(TAG, "Unable to launch app "
10579                            + cpi.applicationInfo.packageName + "/"
10580                            + cpi.applicationInfo.uid + " for provider "
10581                            + name + ": launching app became null");
10582                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10583                            UserHandle.getUserId(cpi.applicationInfo.uid),
10584                            cpi.applicationInfo.packageName,
10585                            cpi.applicationInfo.uid, name);
10586                    return null;
10587                }
10588                try {
10589                    if (DEBUG_MU) Slog.v(TAG_MU,
10590                            "Waiting to start provider " + cpr
10591                            + " launchingApp=" + cpr.launchingApp);
10592                    if (conn != null) {
10593                        conn.waiting = true;
10594                    }
10595                    cpr.wait();
10596                } catch (InterruptedException ex) {
10597                } finally {
10598                    if (conn != null) {
10599                        conn.waiting = false;
10600                    }
10601                }
10602            }
10603        }
10604        return cpr != null ? cpr.newHolder(conn) : null;
10605    }
10606
10607    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10608            ProcessRecord r, final int userId) {
10609        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10610                cpi.packageName, userId)) {
10611
10612            final boolean callerForeground = r == null || r.setSchedGroup
10613                    != ProcessList.SCHED_GROUP_BACKGROUND;
10614
10615            // Show a permission review UI only for starting from a foreground app
10616            if (!callerForeground) {
10617                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10618                        + cpi.packageName + " requires a permissions review");
10619                return false;
10620            }
10621
10622            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10623            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10624                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10625            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10626
10627            if (DEBUG_PERMISSIONS_REVIEW) {
10628                Slog.i(TAG, "u" + userId + " Launching permission review "
10629                        + "for package " + cpi.packageName);
10630            }
10631
10632            final UserHandle userHandle = new UserHandle(userId);
10633            mHandler.post(new Runnable() {
10634                @Override
10635                public void run() {
10636                    mContext.startActivityAsUser(intent, userHandle);
10637                }
10638            });
10639
10640            return false;
10641        }
10642
10643        return true;
10644    }
10645
10646    PackageManagerInternal getPackageManagerInternalLocked() {
10647        if (mPackageManagerInt == null) {
10648            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10649        }
10650        return mPackageManagerInt;
10651    }
10652
10653    @Override
10654    public final ContentProviderHolder getContentProvider(
10655            IApplicationThread caller, String name, int userId, boolean stable) {
10656        enforceNotIsolatedCaller("getContentProvider");
10657        if (caller == null) {
10658            String msg = "null IApplicationThread when getting content provider "
10659                    + name;
10660            Slog.w(TAG, msg);
10661            throw new SecurityException(msg);
10662        }
10663        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10664        // with cross-user grant.
10665        return getContentProviderImpl(caller, name, null, stable, userId);
10666    }
10667
10668    public ContentProviderHolder getContentProviderExternal(
10669            String name, int userId, IBinder token) {
10670        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10671            "Do not have permission in call getContentProviderExternal()");
10672        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10673                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10674        return getContentProviderExternalUnchecked(name, token, userId);
10675    }
10676
10677    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10678            IBinder token, int userId) {
10679        return getContentProviderImpl(null, name, token, true, userId);
10680    }
10681
10682    /**
10683     * Drop a content provider from a ProcessRecord's bookkeeping
10684     */
10685    public void removeContentProvider(IBinder connection, boolean stable) {
10686        enforceNotIsolatedCaller("removeContentProvider");
10687        long ident = Binder.clearCallingIdentity();
10688        try {
10689            synchronized (this) {
10690                ContentProviderConnection conn;
10691                try {
10692                    conn = (ContentProviderConnection)connection;
10693                } catch (ClassCastException e) {
10694                    String msg ="removeContentProvider: " + connection
10695                            + " not a ContentProviderConnection";
10696                    Slog.w(TAG, msg);
10697                    throw new IllegalArgumentException(msg);
10698                }
10699                if (conn == null) {
10700                    throw new NullPointerException("connection is null");
10701                }
10702                if (decProviderCountLocked(conn, null, null, stable)) {
10703                    updateOomAdjLocked();
10704                }
10705            }
10706        } finally {
10707            Binder.restoreCallingIdentity(ident);
10708        }
10709    }
10710
10711    public void removeContentProviderExternal(String name, IBinder token) {
10712        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10713            "Do not have permission in call removeContentProviderExternal()");
10714        int userId = UserHandle.getCallingUserId();
10715        long ident = Binder.clearCallingIdentity();
10716        try {
10717            removeContentProviderExternalUnchecked(name, token, userId);
10718        } finally {
10719            Binder.restoreCallingIdentity(ident);
10720        }
10721    }
10722
10723    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10724        synchronized (this) {
10725            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10726            if(cpr == null) {
10727                //remove from mProvidersByClass
10728                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10729                return;
10730            }
10731
10732            //update content provider record entry info
10733            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10734            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10735            if (localCpr.hasExternalProcessHandles()) {
10736                if (localCpr.removeExternalProcessHandleLocked(token)) {
10737                    updateOomAdjLocked();
10738                } else {
10739                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10740                            + " with no external reference for token: "
10741                            + token + ".");
10742                }
10743            } else {
10744                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10745                        + " with no external references.");
10746            }
10747        }
10748    }
10749
10750    public final void publishContentProviders(IApplicationThread caller,
10751            List<ContentProviderHolder> providers) {
10752        if (providers == null) {
10753            return;
10754        }
10755
10756        enforceNotIsolatedCaller("publishContentProviders");
10757        synchronized (this) {
10758            final ProcessRecord r = getRecordForAppLocked(caller);
10759            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10760            if (r == null) {
10761                throw new SecurityException(
10762                        "Unable to find app for caller " + caller
10763                      + " (pid=" + Binder.getCallingPid()
10764                      + ") when publishing content providers");
10765            }
10766
10767            final long origId = Binder.clearCallingIdentity();
10768
10769            final int N = providers.size();
10770            for (int i = 0; i < N; i++) {
10771                ContentProviderHolder src = providers.get(i);
10772                if (src == null || src.info == null || src.provider == null) {
10773                    continue;
10774                }
10775                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10776                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10777                if (dst != null) {
10778                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10779                    mProviderMap.putProviderByClass(comp, dst);
10780                    String names[] = dst.info.authority.split(";");
10781                    for (int j = 0; j < names.length; j++) {
10782                        mProviderMap.putProviderByName(names[j], dst);
10783                    }
10784
10785                    int launchingCount = mLaunchingProviders.size();
10786                    int j;
10787                    boolean wasInLaunchingProviders = false;
10788                    for (j = 0; j < launchingCount; j++) {
10789                        if (mLaunchingProviders.get(j) == dst) {
10790                            mLaunchingProviders.remove(j);
10791                            wasInLaunchingProviders = true;
10792                            j--;
10793                            launchingCount--;
10794                        }
10795                    }
10796                    if (wasInLaunchingProviders) {
10797                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10798                    }
10799                    synchronized (dst) {
10800                        dst.provider = src.provider;
10801                        dst.proc = r;
10802                        dst.notifyAll();
10803                    }
10804                    updateOomAdjLocked(r);
10805                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10806                            src.info.authority);
10807                }
10808            }
10809
10810            Binder.restoreCallingIdentity(origId);
10811        }
10812    }
10813
10814    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10815        ContentProviderConnection conn;
10816        try {
10817            conn = (ContentProviderConnection)connection;
10818        } catch (ClassCastException e) {
10819            String msg ="refContentProvider: " + connection
10820                    + " not a ContentProviderConnection";
10821            Slog.w(TAG, msg);
10822            throw new IllegalArgumentException(msg);
10823        }
10824        if (conn == null) {
10825            throw new NullPointerException("connection is null");
10826        }
10827
10828        synchronized (this) {
10829            if (stable > 0) {
10830                conn.numStableIncs += stable;
10831            }
10832            stable = conn.stableCount + stable;
10833            if (stable < 0) {
10834                throw new IllegalStateException("stableCount < 0: " + stable);
10835            }
10836
10837            if (unstable > 0) {
10838                conn.numUnstableIncs += unstable;
10839            }
10840            unstable = conn.unstableCount + unstable;
10841            if (unstable < 0) {
10842                throw new IllegalStateException("unstableCount < 0: " + unstable);
10843            }
10844
10845            if ((stable+unstable) <= 0) {
10846                throw new IllegalStateException("ref counts can't go to zero here: stable="
10847                        + stable + " unstable=" + unstable);
10848            }
10849            conn.stableCount = stable;
10850            conn.unstableCount = unstable;
10851            return !conn.dead;
10852        }
10853    }
10854
10855    public void unstableProviderDied(IBinder connection) {
10856        ContentProviderConnection conn;
10857        try {
10858            conn = (ContentProviderConnection)connection;
10859        } catch (ClassCastException e) {
10860            String msg ="refContentProvider: " + connection
10861                    + " not a ContentProviderConnection";
10862            Slog.w(TAG, msg);
10863            throw new IllegalArgumentException(msg);
10864        }
10865        if (conn == null) {
10866            throw new NullPointerException("connection is null");
10867        }
10868
10869        // Safely retrieve the content provider associated with the connection.
10870        IContentProvider provider;
10871        synchronized (this) {
10872            provider = conn.provider.provider;
10873        }
10874
10875        if (provider == null) {
10876            // Um, yeah, we're way ahead of you.
10877            return;
10878        }
10879
10880        // Make sure the caller is being honest with us.
10881        if (provider.asBinder().pingBinder()) {
10882            // Er, no, still looks good to us.
10883            synchronized (this) {
10884                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10885                        + " says " + conn + " died, but we don't agree");
10886                return;
10887            }
10888        }
10889
10890        // Well look at that!  It's dead!
10891        synchronized (this) {
10892            if (conn.provider.provider != provider) {
10893                // But something changed...  good enough.
10894                return;
10895            }
10896
10897            ProcessRecord proc = conn.provider.proc;
10898            if (proc == null || proc.thread == null) {
10899                // Seems like the process is already cleaned up.
10900                return;
10901            }
10902
10903            // As far as we're concerned, this is just like receiving a
10904            // death notification...  just a bit prematurely.
10905            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10906                    + ") early provider death");
10907            final long ident = Binder.clearCallingIdentity();
10908            try {
10909                appDiedLocked(proc);
10910            } finally {
10911                Binder.restoreCallingIdentity(ident);
10912            }
10913        }
10914    }
10915
10916    @Override
10917    public void appNotRespondingViaProvider(IBinder connection) {
10918        enforceCallingPermission(
10919                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10920
10921        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10922        if (conn == null) {
10923            Slog.w(TAG, "ContentProviderConnection is null");
10924            return;
10925        }
10926
10927        final ProcessRecord host = conn.provider.proc;
10928        if (host == null) {
10929            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10930            return;
10931        }
10932
10933        mHandler.post(new Runnable() {
10934            @Override
10935            public void run() {
10936                mAppErrors.appNotResponding(host, null, null, false,
10937                        "ContentProvider not responding");
10938            }
10939        });
10940    }
10941
10942    public final void installSystemProviders() {
10943        List<ProviderInfo> providers;
10944        synchronized (this) {
10945            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10946            providers = generateApplicationProvidersLocked(app);
10947            if (providers != null) {
10948                for (int i=providers.size()-1; i>=0; i--) {
10949                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10950                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10951                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10952                                + ": not system .apk");
10953                        providers.remove(i);
10954                    }
10955                }
10956            }
10957        }
10958        if (providers != null) {
10959            mSystemThread.installSystemProviders(providers);
10960        }
10961
10962        mCoreSettingsObserver = new CoreSettingsObserver(this);
10963        mFontScaleSettingObserver = new FontScaleSettingObserver();
10964
10965        //mUsageStatsService.monitorPackages();
10966    }
10967
10968    private void startPersistentApps(int matchFlags) {
10969        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
10970
10971        synchronized (this) {
10972            try {
10973                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
10974                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
10975                for (ApplicationInfo app : apps) {
10976                    if (!"android".equals(app.packageName)) {
10977                        addAppLocked(app, false, null /* ABI override */);
10978                    }
10979                }
10980            } catch (RemoteException ex) {
10981            }
10982        }
10983    }
10984
10985    /**
10986     * When a user is unlocked, we need to install encryption-unaware providers
10987     * belonging to any running apps.
10988     */
10989    private void installEncryptionUnawareProviders(int userId) {
10990        if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
10991            // TODO: eventually pivot this back to look at current user state,
10992            // similar to the comment in UserManager.isUserUnlocked(), but for
10993            // now, if we started apps when "unlocked" then unaware providers
10994            // have already been spun up.
10995            return;
10996        }
10997
10998        // We're only interested in providers that are encryption unaware, and
10999        // we don't care about uninstalled apps, since there's no way they're
11000        // running at this point.
11001        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11002
11003        synchronized (this) {
11004            final int NP = mProcessNames.getMap().size();
11005            for (int ip = 0; ip < NP; ip++) {
11006                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11007                final int NA = apps.size();
11008                for (int ia = 0; ia < NA; ia++) {
11009                    final ProcessRecord app = apps.valueAt(ia);
11010                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11011
11012                    final int NG = app.pkgList.size();
11013                    for (int ig = 0; ig < NG; ig++) {
11014                        try {
11015                            final String pkgName = app.pkgList.keyAt(ig);
11016                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11017                                    .getPackageInfo(pkgName, matchFlags, userId);
11018                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11019                                for (ProviderInfo provInfo : pkgInfo.providers) {
11020                                    Log.v(TAG, "Installing " + provInfo);
11021                                    app.thread.scheduleInstallProvider(provInfo);
11022                                }
11023                            }
11024                        } catch (RemoteException ignored) {
11025                        }
11026                    }
11027                }
11028            }
11029        }
11030    }
11031
11032    /**
11033     * Allows apps to retrieve the MIME type of a URI.
11034     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11035     * users, then it does not need permission to access the ContentProvider.
11036     * Either, it needs cross-user uri grants.
11037     *
11038     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11039     *
11040     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11041     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11042     */
11043    public String getProviderMimeType(Uri uri, int userId) {
11044        enforceNotIsolatedCaller("getProviderMimeType");
11045        final String name = uri.getAuthority();
11046        int callingUid = Binder.getCallingUid();
11047        int callingPid = Binder.getCallingPid();
11048        long ident = 0;
11049        boolean clearedIdentity = false;
11050        synchronized (this) {
11051            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11052        }
11053        if (canClearIdentity(callingPid, callingUid, userId)) {
11054            clearedIdentity = true;
11055            ident = Binder.clearCallingIdentity();
11056        }
11057        ContentProviderHolder holder = null;
11058        try {
11059            holder = getContentProviderExternalUnchecked(name, null, userId);
11060            if (holder != null) {
11061                return holder.provider.getType(uri);
11062            }
11063        } catch (RemoteException e) {
11064            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11065            return null;
11066        } finally {
11067            // We need to clear the identity to call removeContentProviderExternalUnchecked
11068            if (!clearedIdentity) {
11069                ident = Binder.clearCallingIdentity();
11070            }
11071            try {
11072                if (holder != null) {
11073                    removeContentProviderExternalUnchecked(name, null, userId);
11074                }
11075            } finally {
11076                Binder.restoreCallingIdentity(ident);
11077            }
11078        }
11079
11080        return null;
11081    }
11082
11083    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11084        if (UserHandle.getUserId(callingUid) == userId) {
11085            return true;
11086        }
11087        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11088                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11089                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11090                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11091                return true;
11092        }
11093        return false;
11094    }
11095
11096    // =========================================================
11097    // GLOBAL MANAGEMENT
11098    // =========================================================
11099
11100    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11101            boolean isolated, int isolatedUid) {
11102        String proc = customProcess != null ? customProcess : info.processName;
11103        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11104        final int userId = UserHandle.getUserId(info.uid);
11105        int uid = info.uid;
11106        if (isolated) {
11107            if (isolatedUid == 0) {
11108                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11109                while (true) {
11110                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11111                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11112                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11113                    }
11114                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11115                    mNextIsolatedProcessUid++;
11116                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11117                        // No process for this uid, use it.
11118                        break;
11119                    }
11120                    stepsLeft--;
11121                    if (stepsLeft <= 0) {
11122                        return null;
11123                    }
11124                }
11125            } else {
11126                // Special case for startIsolatedProcess (internal only), where
11127                // the uid of the isolated process is specified by the caller.
11128                uid = isolatedUid;
11129            }
11130        }
11131        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11132        if (!mBooted && !mBooting
11133                && userId == UserHandle.USER_SYSTEM
11134                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11135            r.persistent = true;
11136        }
11137        addProcessNameLocked(r);
11138        return r;
11139    }
11140
11141    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11142            String abiOverride) {
11143        ProcessRecord app;
11144        if (!isolated) {
11145            app = getProcessRecordLocked(info.processName, info.uid, true);
11146        } else {
11147            app = null;
11148        }
11149
11150        if (app == null) {
11151            app = newProcessRecordLocked(info, null, isolated, 0);
11152            updateLruProcessLocked(app, false, null);
11153            updateOomAdjLocked();
11154        }
11155
11156        // This package really, really can not be stopped.
11157        try {
11158            AppGlobals.getPackageManager().setPackageStoppedState(
11159                    info.packageName, false, UserHandle.getUserId(app.uid));
11160        } catch (RemoteException e) {
11161        } catch (IllegalArgumentException e) {
11162            Slog.w(TAG, "Failed trying to unstop package "
11163                    + info.packageName + ": " + e);
11164        }
11165
11166        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11167            app.persistent = true;
11168            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11169        }
11170        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11171            mPersistentStartingProcesses.add(app);
11172            startProcessLocked(app, "added application", app.processName, abiOverride,
11173                    null /* entryPoint */, null /* entryPointArgs */);
11174        }
11175
11176        return app;
11177    }
11178
11179    public void unhandledBack() {
11180        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11181                "unhandledBack()");
11182
11183        synchronized(this) {
11184            final long origId = Binder.clearCallingIdentity();
11185            try {
11186                getFocusedStack().unhandledBackLocked();
11187            } finally {
11188                Binder.restoreCallingIdentity(origId);
11189            }
11190        }
11191    }
11192
11193    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11194        enforceNotIsolatedCaller("openContentUri");
11195        final int userId = UserHandle.getCallingUserId();
11196        String name = uri.getAuthority();
11197        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11198        ParcelFileDescriptor pfd = null;
11199        if (cph != null) {
11200            // We record the binder invoker's uid in thread-local storage before
11201            // going to the content provider to open the file.  Later, in the code
11202            // that handles all permissions checks, we look for this uid and use
11203            // that rather than the Activity Manager's own uid.  The effect is that
11204            // we do the check against the caller's permissions even though it looks
11205            // to the content provider like the Activity Manager itself is making
11206            // the request.
11207            Binder token = new Binder();
11208            sCallerIdentity.set(new Identity(
11209                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11210            try {
11211                pfd = cph.provider.openFile(null, uri, "r", null, token);
11212            } catch (FileNotFoundException e) {
11213                // do nothing; pfd will be returned null
11214            } finally {
11215                // Ensure that whatever happens, we clean up the identity state
11216                sCallerIdentity.remove();
11217                // Ensure we're done with the provider.
11218                removeContentProviderExternalUnchecked(name, null, userId);
11219            }
11220        } else {
11221            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11222        }
11223        return pfd;
11224    }
11225
11226    // Actually is sleeping or shutting down or whatever else in the future
11227    // is an inactive state.
11228    public boolean isSleepingOrShuttingDown() {
11229        return isSleeping() || mShuttingDown;
11230    }
11231
11232    public boolean isSleeping() {
11233        return mSleeping;
11234    }
11235
11236    void onWakefulnessChanged(int wakefulness) {
11237        synchronized(this) {
11238            mWakefulness = wakefulness;
11239            updateSleepIfNeededLocked();
11240        }
11241    }
11242
11243    void finishRunningVoiceLocked() {
11244        if (mRunningVoice != null) {
11245            mRunningVoice = null;
11246            mVoiceWakeLock.release();
11247            updateSleepIfNeededLocked();
11248        }
11249    }
11250
11251    void startTimeTrackingFocusedActivityLocked() {
11252        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11253            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11254        }
11255    }
11256
11257    void updateSleepIfNeededLocked() {
11258        if (mSleeping && !shouldSleepLocked()) {
11259            mSleeping = false;
11260            startTimeTrackingFocusedActivityLocked();
11261            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11262            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11263            updateOomAdjLocked();
11264        } else if (!mSleeping && shouldSleepLocked()) {
11265            mSleeping = true;
11266            if (mCurAppTimeTracker != null) {
11267                mCurAppTimeTracker.stop();
11268            }
11269            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11270            mStackSupervisor.goingToSleepLocked();
11271            updateOomAdjLocked();
11272
11273            // Initialize the wake times of all processes.
11274            checkExcessivePowerUsageLocked(false);
11275            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11276            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11277            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11278        }
11279    }
11280
11281    private boolean shouldSleepLocked() {
11282        // Resume applications while running a voice interactor.
11283        if (mRunningVoice != null) {
11284            return false;
11285        }
11286
11287        // TODO: Transform the lock screen state into a sleep token instead.
11288        switch (mWakefulness) {
11289            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11290            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11291            case PowerManagerInternal.WAKEFULNESS_DOZING:
11292                // Pause applications whenever the lock screen is shown or any sleep
11293                // tokens have been acquired.
11294                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11295            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11296            default:
11297                // If we're asleep then pause applications unconditionally.
11298                return true;
11299        }
11300    }
11301
11302    /** Pokes the task persister. */
11303    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11304        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11305    }
11306
11307    /** Notifies all listeners when the task stack has changed. */
11308    void notifyTaskStackChangedLocked() {
11309        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11310        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11311        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11312        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11313    }
11314
11315    /** Notifies all listeners when an Activity is pinned. */
11316    void notifyActivityPinnedLocked() {
11317        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11318        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11319    }
11320
11321    /**
11322     * Notifies all listeners when an attempt was made to start an an activity that is already
11323     * running in the pinned stack and the activity was not actually started, but the task is
11324     * either brought to the front or a new Intent is delivered to it.
11325     */
11326    void notifyPinnedActivityRestartAttemptLocked() {
11327        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11328        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11329    }
11330
11331    /** Notifies all listeners when the pinned stack animation ends. */
11332    @Override
11333    public void notifyPinnedStackAnimationEnded() {
11334        synchronized (this) {
11335            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11336            mHandler.obtainMessage(
11337                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11338        }
11339    }
11340
11341    @Override
11342    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11343        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11344    }
11345
11346    @Override
11347    public boolean shutdown(int timeout) {
11348        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11349                != PackageManager.PERMISSION_GRANTED) {
11350            throw new SecurityException("Requires permission "
11351                    + android.Manifest.permission.SHUTDOWN);
11352        }
11353
11354        boolean timedout = false;
11355
11356        synchronized(this) {
11357            mShuttingDown = true;
11358            updateEventDispatchingLocked();
11359            timedout = mStackSupervisor.shutdownLocked(timeout);
11360        }
11361
11362        mAppOpsService.shutdown();
11363        if (mUsageStatsService != null) {
11364            mUsageStatsService.prepareShutdown();
11365        }
11366        mBatteryStatsService.shutdown();
11367        synchronized (this) {
11368            mProcessStats.shutdownLocked();
11369            notifyTaskPersisterLocked(null, true);
11370        }
11371
11372        return timedout;
11373    }
11374
11375    public final void activitySlept(IBinder token) {
11376        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11377
11378        final long origId = Binder.clearCallingIdentity();
11379
11380        synchronized (this) {
11381            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11382            if (r != null) {
11383                mStackSupervisor.activitySleptLocked(r);
11384            }
11385        }
11386
11387        Binder.restoreCallingIdentity(origId);
11388    }
11389
11390    private String lockScreenShownToString() {
11391        switch (mLockScreenShown) {
11392            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11393            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11394            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11395            default: return "Unknown=" + mLockScreenShown;
11396        }
11397    }
11398
11399    void logLockScreen(String msg) {
11400        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11401                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11402                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11403                + " mSleeping=" + mSleeping);
11404    }
11405
11406    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11407        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11408        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11409        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11410            boolean wasRunningVoice = mRunningVoice != null;
11411            mRunningVoice = session;
11412            if (!wasRunningVoice) {
11413                mVoiceWakeLock.acquire();
11414                updateSleepIfNeededLocked();
11415            }
11416        }
11417    }
11418
11419    private void updateEventDispatchingLocked() {
11420        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11421    }
11422
11423    public void setLockScreenShown(boolean shown) {
11424        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11425                != PackageManager.PERMISSION_GRANTED) {
11426            throw new SecurityException("Requires permission "
11427                    + android.Manifest.permission.DEVICE_POWER);
11428        }
11429
11430        synchronized(this) {
11431            long ident = Binder.clearCallingIdentity();
11432            try {
11433                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11434                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11435                updateSleepIfNeededLocked();
11436            } finally {
11437                Binder.restoreCallingIdentity(ident);
11438            }
11439        }
11440    }
11441
11442    @Override
11443    public void notifyLockedProfile(@UserIdInt int userId) {
11444        try {
11445            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11446                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11447            }
11448        } catch (RemoteException ex) {
11449            throw new SecurityException("Fail to check is caller a privileged app", ex);
11450        }
11451
11452        synchronized (this) {
11453            if (mStackSupervisor.isFocusedUserLockedProfile()) {
11454                final long ident = Binder.clearCallingIdentity();
11455                try {
11456                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11457                    // Get the focused task before launching launcher.
11458
11459                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11460
11461                        // If there is no device lock, we will show the profile's credential page.
11462                        // startActivityFromRecentsInner is intercepted and will forward user to it.
11463                        if (mFocusedActivity != null) {
11464                            mStackSupervisor.startActivityFromRecentsInner(
11465                                    mFocusedActivity.task.taskId, null);
11466                        }
11467                    } else {
11468                        // Showing launcher to avoid user entering credential twice.
11469                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11470                    }
11471                } finally {
11472                    Binder.restoreCallingIdentity(ident);
11473                }
11474            }
11475        }
11476    }
11477
11478    @Override
11479    public void stopAppSwitches() {
11480        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11481                != PackageManager.PERMISSION_GRANTED) {
11482            throw new SecurityException("viewquires permission "
11483                    + android.Manifest.permission.STOP_APP_SWITCHES);
11484        }
11485
11486        synchronized(this) {
11487            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11488                    + APP_SWITCH_DELAY_TIME;
11489            mDidAppSwitch = false;
11490            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11491            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11492            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11493        }
11494    }
11495
11496    public void resumeAppSwitches() {
11497        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11498                != PackageManager.PERMISSION_GRANTED) {
11499            throw new SecurityException("Requires permission "
11500                    + android.Manifest.permission.STOP_APP_SWITCHES);
11501        }
11502
11503        synchronized(this) {
11504            // Note that we don't execute any pending app switches... we will
11505            // let those wait until either the timeout, or the next start
11506            // activity request.
11507            mAppSwitchesAllowedTime = 0;
11508        }
11509    }
11510
11511    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11512            int callingPid, int callingUid, String name) {
11513        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11514            return true;
11515        }
11516
11517        int perm = checkComponentPermission(
11518                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11519                sourceUid, -1, true);
11520        if (perm == PackageManager.PERMISSION_GRANTED) {
11521            return true;
11522        }
11523
11524        // If the actual IPC caller is different from the logical source, then
11525        // also see if they are allowed to control app switches.
11526        if (callingUid != -1 && callingUid != sourceUid) {
11527            perm = checkComponentPermission(
11528                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11529                    callingUid, -1, true);
11530            if (perm == PackageManager.PERMISSION_GRANTED) {
11531                return true;
11532            }
11533        }
11534
11535        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11536        return false;
11537    }
11538
11539    public void setDebugApp(String packageName, boolean waitForDebugger,
11540            boolean persistent) {
11541        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11542                "setDebugApp()");
11543
11544        long ident = Binder.clearCallingIdentity();
11545        try {
11546            // Note that this is not really thread safe if there are multiple
11547            // callers into it at the same time, but that's not a situation we
11548            // care about.
11549            if (persistent) {
11550                final ContentResolver resolver = mContext.getContentResolver();
11551                Settings.Global.putString(
11552                    resolver, Settings.Global.DEBUG_APP,
11553                    packageName);
11554                Settings.Global.putInt(
11555                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11556                    waitForDebugger ? 1 : 0);
11557            }
11558
11559            synchronized (this) {
11560                if (!persistent) {
11561                    mOrigDebugApp = mDebugApp;
11562                    mOrigWaitForDebugger = mWaitForDebugger;
11563                }
11564                mDebugApp = packageName;
11565                mWaitForDebugger = waitForDebugger;
11566                mDebugTransient = !persistent;
11567                if (packageName != null) {
11568                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11569                            false, UserHandle.USER_ALL, "set debug app");
11570                }
11571            }
11572        } finally {
11573            Binder.restoreCallingIdentity(ident);
11574        }
11575    }
11576
11577    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11578        synchronized (this) {
11579            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11580            if (!isDebuggable) {
11581                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11582                    throw new SecurityException("Process not debuggable: " + app.packageName);
11583                }
11584            }
11585
11586            mTrackAllocationApp = processName;
11587        }
11588    }
11589
11590    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11591        synchronized (this) {
11592            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11593            if (!isDebuggable) {
11594                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11595                    throw new SecurityException("Process not debuggable: " + app.packageName);
11596                }
11597            }
11598            mProfileApp = processName;
11599            mProfileFile = profilerInfo.profileFile;
11600            if (mProfileFd != null) {
11601                try {
11602                    mProfileFd.close();
11603                } catch (IOException e) {
11604                }
11605                mProfileFd = null;
11606            }
11607            mProfileFd = profilerInfo.profileFd;
11608            mSamplingInterval = profilerInfo.samplingInterval;
11609            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11610            mProfileType = 0;
11611        }
11612    }
11613
11614    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11615        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11616        if (!isDebuggable) {
11617            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11618                throw new SecurityException("Process not debuggable: " + app.packageName);
11619            }
11620        }
11621        mNativeDebuggingApp = processName;
11622    }
11623
11624    @Override
11625    public void setAlwaysFinish(boolean enabled) {
11626        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11627                "setAlwaysFinish()");
11628
11629        long ident = Binder.clearCallingIdentity();
11630        try {
11631            Settings.Global.putInt(
11632                    mContext.getContentResolver(),
11633                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11634
11635            synchronized (this) {
11636                mAlwaysFinishActivities = enabled;
11637            }
11638        } finally {
11639            Binder.restoreCallingIdentity(ident);
11640        }
11641    }
11642
11643    @Override
11644    public void setLenientBackgroundCheck(boolean enabled) {
11645        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11646                "setLenientBackgroundCheck()");
11647
11648        long ident = Binder.clearCallingIdentity();
11649        try {
11650            Settings.Global.putInt(
11651                    mContext.getContentResolver(),
11652                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11653
11654            synchronized (this) {
11655                mLenientBackgroundCheck = enabled;
11656            }
11657        } finally {
11658            Binder.restoreCallingIdentity(ident);
11659        }
11660    }
11661
11662    @Override
11663    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11664        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11665                "setActivityController()");
11666        synchronized (this) {
11667            mController = controller;
11668            mControllerIsAMonkey = imAMonkey;
11669            Watchdog.getInstance().setActivityController(controller);
11670        }
11671    }
11672
11673    @Override
11674    public void setUserIsMonkey(boolean userIsMonkey) {
11675        synchronized (this) {
11676            synchronized (mPidsSelfLocked) {
11677                final int callingPid = Binder.getCallingPid();
11678                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11679                if (precessRecord == null) {
11680                    throw new SecurityException("Unknown process: " + callingPid);
11681                }
11682                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11683                    throw new SecurityException("Only an instrumentation process "
11684                            + "with a UiAutomation can call setUserIsMonkey");
11685                }
11686            }
11687            mUserIsMonkey = userIsMonkey;
11688        }
11689    }
11690
11691    @Override
11692    public boolean isUserAMonkey() {
11693        synchronized (this) {
11694            // If there is a controller also implies the user is a monkey.
11695            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11696        }
11697    }
11698
11699    public void requestBugReport(int bugreportType) {
11700        String service = null;
11701        switch (bugreportType) {
11702            case ActivityManager.BUGREPORT_OPTION_FULL:
11703                service = "bugreport";
11704                break;
11705            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11706                service = "bugreportplus";
11707                break;
11708            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11709                service = "bugreportremote";
11710                break;
11711        }
11712        if (service == null) {
11713            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11714                    + bugreportType);
11715        }
11716        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11717        SystemProperties.set("ctl.start", service);
11718    }
11719
11720    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11721        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11722    }
11723
11724    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11725        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11726            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11727        }
11728        return KEY_DISPATCHING_TIMEOUT;
11729    }
11730
11731    @Override
11732    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11733        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11734                != PackageManager.PERMISSION_GRANTED) {
11735            throw new SecurityException("Requires permission "
11736                    + android.Manifest.permission.FILTER_EVENTS);
11737        }
11738        ProcessRecord proc;
11739        long timeout;
11740        synchronized (this) {
11741            synchronized (mPidsSelfLocked) {
11742                proc = mPidsSelfLocked.get(pid);
11743            }
11744            timeout = getInputDispatchingTimeoutLocked(proc);
11745        }
11746
11747        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11748            return -1;
11749        }
11750
11751        return timeout;
11752    }
11753
11754    /**
11755     * Handle input dispatching timeouts.
11756     * Returns whether input dispatching should be aborted or not.
11757     */
11758    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11759            final ActivityRecord activity, final ActivityRecord parent,
11760            final boolean aboveSystem, String reason) {
11761        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11762                != PackageManager.PERMISSION_GRANTED) {
11763            throw new SecurityException("Requires permission "
11764                    + android.Manifest.permission.FILTER_EVENTS);
11765        }
11766
11767        final String annotation;
11768        if (reason == null) {
11769            annotation = "Input dispatching timed out";
11770        } else {
11771            annotation = "Input dispatching timed out (" + reason + ")";
11772        }
11773
11774        if (proc != null) {
11775            synchronized (this) {
11776                if (proc.debugging) {
11777                    return false;
11778                }
11779
11780                if (mDidDexOpt) {
11781                    // Give more time since we were dexopting.
11782                    mDidDexOpt = false;
11783                    return false;
11784                }
11785
11786                if (proc.instrumentationClass != null) {
11787                    Bundle info = new Bundle();
11788                    info.putString("shortMsg", "keyDispatchingTimedOut");
11789                    info.putString("longMsg", annotation);
11790                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11791                    return true;
11792                }
11793            }
11794            mHandler.post(new Runnable() {
11795                @Override
11796                public void run() {
11797                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11798                }
11799            });
11800        }
11801
11802        return true;
11803    }
11804
11805    @Override
11806    public Bundle getAssistContextExtras(int requestType) {
11807        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11808                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11809        if (pae == null) {
11810            return null;
11811        }
11812        synchronized (pae) {
11813            while (!pae.haveResult) {
11814                try {
11815                    pae.wait();
11816                } catch (InterruptedException e) {
11817                }
11818            }
11819        }
11820        synchronized (this) {
11821            buildAssistBundleLocked(pae, pae.result);
11822            mPendingAssistExtras.remove(pae);
11823            mUiHandler.removeCallbacks(pae);
11824        }
11825        return pae.extras;
11826    }
11827
11828    @Override
11829    public boolean isAssistDataAllowedOnCurrentActivity() {
11830        int userId;
11831        synchronized (this) {
11832            userId = mUserController.getCurrentUserIdLocked();
11833            ActivityRecord activity = getFocusedStack().topActivity();
11834            if (activity == null) {
11835                return false;
11836            }
11837            userId = activity.userId;
11838        }
11839        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11840                Context.DEVICE_POLICY_SERVICE);
11841        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11842    }
11843
11844    @Override
11845    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11846        long ident = Binder.clearCallingIdentity();
11847        try {
11848            synchronized (this) {
11849                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11850                ActivityRecord top = getFocusedStack().topActivity();
11851                if (top != caller) {
11852                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11853                            + " is not current top " + top);
11854                    return false;
11855                }
11856                if (!top.nowVisible) {
11857                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11858                            + " is not visible");
11859                    return false;
11860                }
11861            }
11862            AssistUtils utils = new AssistUtils(mContext);
11863            return utils.showSessionForActiveService(args,
11864                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11865        } finally {
11866            Binder.restoreCallingIdentity(ident);
11867        }
11868    }
11869
11870    @Override
11871    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11872            IBinder activityToken) {
11873        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11874                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11875    }
11876
11877    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11878            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11879            long timeout) {
11880        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11881                "enqueueAssistContext()");
11882        synchronized (this) {
11883            ActivityRecord activity = getFocusedStack().topActivity();
11884            if (activity == null) {
11885                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11886                return null;
11887            }
11888            if (activity.app == null || activity.app.thread == null) {
11889                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11890                return null;
11891            }
11892            if (activityToken != null) {
11893                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11894                if (activity != caller) {
11895                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11896                            + " is not current top " + activity);
11897                    return null;
11898                }
11899            }
11900            PendingAssistExtras pae;
11901            Bundle extras = new Bundle();
11902            if (args != null) {
11903                extras.putAll(args);
11904            }
11905            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11906            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11907            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11908            try {
11909                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11910                        requestType);
11911                mPendingAssistExtras.add(pae);
11912                mUiHandler.postDelayed(pae, timeout);
11913            } catch (RemoteException e) {
11914                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11915                return null;
11916            }
11917            return pae;
11918        }
11919    }
11920
11921    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11922        IResultReceiver receiver;
11923        synchronized (this) {
11924            mPendingAssistExtras.remove(pae);
11925            receiver = pae.receiver;
11926        }
11927        if (receiver != null) {
11928            // Caller wants result sent back to them.
11929            try {
11930                pae.receiver.send(0, null);
11931            } catch (RemoteException e) {
11932            }
11933        }
11934    }
11935
11936    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11937        if (result != null) {
11938            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11939        }
11940        if (pae.hint != null) {
11941            pae.extras.putBoolean(pae.hint, true);
11942        }
11943    }
11944
11945    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11946            AssistContent content, Uri referrer) {
11947        PendingAssistExtras pae = (PendingAssistExtras)token;
11948        synchronized (pae) {
11949            pae.result = extras;
11950            pae.structure = structure;
11951            pae.content = content;
11952            if (referrer != null) {
11953                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11954            }
11955            pae.haveResult = true;
11956            pae.notifyAll();
11957            if (pae.intent == null && pae.receiver == null) {
11958                // Caller is just waiting for the result.
11959                return;
11960            }
11961        }
11962
11963        // We are now ready to launch the assist activity.
11964        IResultReceiver sendReceiver = null;
11965        Bundle sendBundle = null;
11966        synchronized (this) {
11967            buildAssistBundleLocked(pae, extras);
11968            boolean exists = mPendingAssistExtras.remove(pae);
11969            mUiHandler.removeCallbacks(pae);
11970            if (!exists) {
11971                // Timed out.
11972                return;
11973            }
11974            if ((sendReceiver=pae.receiver) != null) {
11975                // Caller wants result sent back to them.
11976                sendBundle = new Bundle();
11977                sendBundle.putBundle("data", pae.extras);
11978                sendBundle.putParcelable("structure", pae.structure);
11979                sendBundle.putParcelable("content", pae.content);
11980            }
11981        }
11982        if (sendReceiver != null) {
11983            try {
11984                sendReceiver.send(0, sendBundle);
11985            } catch (RemoteException e) {
11986            }
11987            return;
11988        }
11989
11990        long ident = Binder.clearCallingIdentity();
11991        try {
11992            pae.intent.replaceExtras(pae.extras);
11993            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11994                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11995                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11996            closeSystemDialogs("assist");
11997            try {
11998                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11999            } catch (ActivityNotFoundException e) {
12000                Slog.w(TAG, "No activity to handle assist action.", e);
12001            }
12002        } finally {
12003            Binder.restoreCallingIdentity(ident);
12004        }
12005    }
12006
12007    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12008            Bundle args) {
12009        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
12010                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12011    }
12012
12013    public void registerProcessObserver(IProcessObserver observer) {
12014        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12015                "registerProcessObserver()");
12016        synchronized (this) {
12017            mProcessObservers.register(observer);
12018        }
12019    }
12020
12021    @Override
12022    public void unregisterProcessObserver(IProcessObserver observer) {
12023        synchronized (this) {
12024            mProcessObservers.unregister(observer);
12025        }
12026    }
12027
12028    @Override
12029    public void registerUidObserver(IUidObserver observer, int which) {
12030        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12031                "registerUidObserver()");
12032        synchronized (this) {
12033            mUidObservers.register(observer, which);
12034        }
12035    }
12036
12037    @Override
12038    public void unregisterUidObserver(IUidObserver observer) {
12039        synchronized (this) {
12040            mUidObservers.unregister(observer);
12041        }
12042    }
12043
12044    @Override
12045    public boolean convertFromTranslucent(IBinder token) {
12046        final long origId = Binder.clearCallingIdentity();
12047        try {
12048            synchronized (this) {
12049                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12050                if (r == null) {
12051                    return false;
12052                }
12053                final boolean translucentChanged = r.changeWindowTranslucency(true);
12054                if (translucentChanged) {
12055                    r.task.stack.releaseBackgroundResources(r);
12056                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12057                }
12058                mWindowManager.setAppFullscreen(token, true);
12059                return translucentChanged;
12060            }
12061        } finally {
12062            Binder.restoreCallingIdentity(origId);
12063        }
12064    }
12065
12066    @Override
12067    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12068        final long origId = Binder.clearCallingIdentity();
12069        try {
12070            synchronized (this) {
12071                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12072                if (r == null) {
12073                    return false;
12074                }
12075                int index = r.task.mActivities.lastIndexOf(r);
12076                if (index > 0) {
12077                    ActivityRecord under = r.task.mActivities.get(index - 1);
12078                    under.returningOptions = options;
12079                }
12080                final boolean translucentChanged = r.changeWindowTranslucency(false);
12081                if (translucentChanged) {
12082                    r.task.stack.convertActivityToTranslucent(r);
12083                }
12084                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12085                mWindowManager.setAppFullscreen(token, false);
12086                return translucentChanged;
12087            }
12088        } finally {
12089            Binder.restoreCallingIdentity(origId);
12090        }
12091    }
12092
12093    @Override
12094    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12095        final long origId = Binder.clearCallingIdentity();
12096        try {
12097            synchronized (this) {
12098                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12099                if (r != null) {
12100                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12101                }
12102            }
12103            return false;
12104        } finally {
12105            Binder.restoreCallingIdentity(origId);
12106        }
12107    }
12108
12109    @Override
12110    public boolean isBackgroundVisibleBehind(IBinder token) {
12111        final long origId = Binder.clearCallingIdentity();
12112        try {
12113            synchronized (this) {
12114                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12115                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12116                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12117                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12118                return visible;
12119            }
12120        } finally {
12121            Binder.restoreCallingIdentity(origId);
12122        }
12123    }
12124
12125    @Override
12126    public ActivityOptions getActivityOptions(IBinder token) {
12127        final long origId = Binder.clearCallingIdentity();
12128        try {
12129            synchronized (this) {
12130                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12131                if (r != null) {
12132                    final ActivityOptions activityOptions = r.pendingOptions;
12133                    r.pendingOptions = null;
12134                    return activityOptions;
12135                }
12136                return null;
12137            }
12138        } finally {
12139            Binder.restoreCallingIdentity(origId);
12140        }
12141    }
12142
12143    @Override
12144    public void setImmersive(IBinder token, boolean immersive) {
12145        synchronized(this) {
12146            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12147            if (r == null) {
12148                throw new IllegalArgumentException();
12149            }
12150            r.immersive = immersive;
12151
12152            // update associated state if we're frontmost
12153            if (r == mFocusedActivity) {
12154                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12155                applyUpdateLockStateLocked(r);
12156            }
12157        }
12158    }
12159
12160    @Override
12161    public boolean isImmersive(IBinder token) {
12162        synchronized (this) {
12163            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12164            if (r == null) {
12165                throw new IllegalArgumentException();
12166            }
12167            return r.immersive;
12168        }
12169    }
12170
12171    @Override
12172    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12173        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12174            throw new UnsupportedOperationException("VR mode not supported on this device!");
12175        }
12176
12177        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12178
12179        ActivityRecord r;
12180        synchronized (this) {
12181            r = ActivityRecord.isInStackLocked(token);
12182        }
12183
12184        if (r == null) {
12185            throw new IllegalArgumentException();
12186        }
12187
12188        int err;
12189        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12190                VrManagerInternal.NO_ERROR) {
12191            return err;
12192        }
12193
12194        synchronized(this) {
12195            r.requestedVrComponent = (enabled) ? packageName : null;
12196
12197            // Update associated state if this activity is currently focused
12198            if (r == mFocusedActivity) {
12199                applyUpdateVrModeLocked(r);
12200            }
12201            return 0;
12202        }
12203    }
12204
12205    @Override
12206    public boolean isVrModePackageEnabled(ComponentName packageName) {
12207        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12208            throw new UnsupportedOperationException("VR mode not supported on this device!");
12209        }
12210
12211        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12212
12213        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12214                VrManagerInternal.NO_ERROR;
12215    }
12216
12217    public boolean isTopActivityImmersive() {
12218        enforceNotIsolatedCaller("startActivity");
12219        synchronized (this) {
12220            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12221            return (r != null) ? r.immersive : false;
12222        }
12223    }
12224
12225    @Override
12226    public boolean isTopOfTask(IBinder token) {
12227        synchronized (this) {
12228            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12229            if (r == null) {
12230                throw new IllegalArgumentException();
12231            }
12232            return r.task.getTopActivity() == r;
12233        }
12234    }
12235
12236    public final void enterSafeMode() {
12237        synchronized(this) {
12238            // It only makes sense to do this before the system is ready
12239            // and started launching other packages.
12240            if (!mSystemReady) {
12241                try {
12242                    AppGlobals.getPackageManager().enterSafeMode();
12243                } catch (RemoteException e) {
12244                }
12245            }
12246
12247            mSafeMode = true;
12248        }
12249    }
12250
12251    public final void showSafeModeOverlay() {
12252        View v = LayoutInflater.from(mContext).inflate(
12253                com.android.internal.R.layout.safe_mode, null);
12254        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12255        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12256        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12257        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12258        lp.gravity = Gravity.BOTTOM | Gravity.START;
12259        lp.format = v.getBackground().getOpacity();
12260        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12261                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12262        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12263        ((WindowManager)mContext.getSystemService(
12264                Context.WINDOW_SERVICE)).addView(v, lp);
12265    }
12266
12267    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12268        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12269            return;
12270        }
12271        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12272        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12273        synchronized (stats) {
12274            if (mBatteryStatsService.isOnBattery()) {
12275                mBatteryStatsService.enforceCallingPermission();
12276                int MY_UID = Binder.getCallingUid();
12277                final int uid;
12278                if (sender == null) {
12279                    uid = sourceUid;
12280                } else {
12281                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12282                }
12283                BatteryStatsImpl.Uid.Pkg pkg =
12284                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12285                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12286                pkg.noteWakeupAlarmLocked(tag);
12287            }
12288        }
12289    }
12290
12291    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12292        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12293            return;
12294        }
12295        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12296        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12297        synchronized (stats) {
12298            mBatteryStatsService.enforceCallingPermission();
12299            int MY_UID = Binder.getCallingUid();
12300            final int uid;
12301            if (sender == null) {
12302                uid = sourceUid;
12303            } else {
12304                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12305            }
12306            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12307        }
12308    }
12309
12310    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12311        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12312            return;
12313        }
12314        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12315        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12316        synchronized (stats) {
12317            mBatteryStatsService.enforceCallingPermission();
12318            int MY_UID = Binder.getCallingUid();
12319            final int uid;
12320            if (sender == null) {
12321                uid = sourceUid;
12322            } else {
12323                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12324            }
12325            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12326        }
12327    }
12328
12329    public boolean killPids(int[] pids, String pReason, boolean secure) {
12330        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12331            throw new SecurityException("killPids only available to the system");
12332        }
12333        String reason = (pReason == null) ? "Unknown" : pReason;
12334        // XXX Note: don't acquire main activity lock here, because the window
12335        // manager calls in with its locks held.
12336
12337        boolean killed = false;
12338        synchronized (mPidsSelfLocked) {
12339            int worstType = 0;
12340            for (int i=0; i<pids.length; i++) {
12341                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12342                if (proc != null) {
12343                    int type = proc.setAdj;
12344                    if (type > worstType) {
12345                        worstType = type;
12346                    }
12347                }
12348            }
12349
12350            // If the worst oom_adj is somewhere in the cached proc LRU range,
12351            // then constrain it so we will kill all cached procs.
12352            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12353                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12354                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12355            }
12356
12357            // If this is not a secure call, don't let it kill processes that
12358            // are important.
12359            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12360                worstType = ProcessList.SERVICE_ADJ;
12361            }
12362
12363            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12364            for (int i=0; i<pids.length; i++) {
12365                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12366                if (proc == null) {
12367                    continue;
12368                }
12369                int adj = proc.setAdj;
12370                if (adj >= worstType && !proc.killedByAm) {
12371                    proc.kill(reason, true);
12372                    killed = true;
12373                }
12374            }
12375        }
12376        return killed;
12377    }
12378
12379    @Override
12380    public void killUid(int appId, int userId, String reason) {
12381        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12382        synchronized (this) {
12383            final long identity = Binder.clearCallingIdentity();
12384            try {
12385                killPackageProcessesLocked(null, appId, userId,
12386                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12387                        reason != null ? reason : "kill uid");
12388            } finally {
12389                Binder.restoreCallingIdentity(identity);
12390            }
12391        }
12392    }
12393
12394    @Override
12395    public boolean killProcessesBelowForeground(String reason) {
12396        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12397            throw new SecurityException("killProcessesBelowForeground() only available to system");
12398        }
12399
12400        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12401    }
12402
12403    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12404        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12405            throw new SecurityException("killProcessesBelowAdj() only available to system");
12406        }
12407
12408        boolean killed = false;
12409        synchronized (mPidsSelfLocked) {
12410            final int size = mPidsSelfLocked.size();
12411            for (int i = 0; i < size; i++) {
12412                final int pid = mPidsSelfLocked.keyAt(i);
12413                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12414                if (proc == null) continue;
12415
12416                final int adj = proc.setAdj;
12417                if (adj > belowAdj && !proc.killedByAm) {
12418                    proc.kill(reason, true);
12419                    killed = true;
12420                }
12421            }
12422        }
12423        return killed;
12424    }
12425
12426    @Override
12427    public void hang(final IBinder who, boolean allowRestart) {
12428        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12429                != PackageManager.PERMISSION_GRANTED) {
12430            throw new SecurityException("Requires permission "
12431                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12432        }
12433
12434        final IBinder.DeathRecipient death = new DeathRecipient() {
12435            @Override
12436            public void binderDied() {
12437                synchronized (this) {
12438                    notifyAll();
12439                }
12440            }
12441        };
12442
12443        try {
12444            who.linkToDeath(death, 0);
12445        } catch (RemoteException e) {
12446            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12447            return;
12448        }
12449
12450        synchronized (this) {
12451            Watchdog.getInstance().setAllowRestart(allowRestart);
12452            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12453            synchronized (death) {
12454                while (who.isBinderAlive()) {
12455                    try {
12456                        death.wait();
12457                    } catch (InterruptedException e) {
12458                    }
12459                }
12460            }
12461            Watchdog.getInstance().setAllowRestart(true);
12462        }
12463    }
12464
12465    @Override
12466    public void restart() {
12467        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12468                != PackageManager.PERMISSION_GRANTED) {
12469            throw new SecurityException("Requires permission "
12470                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12471        }
12472
12473        Log.i(TAG, "Sending shutdown broadcast...");
12474
12475        BroadcastReceiver br = new BroadcastReceiver() {
12476            @Override public void onReceive(Context context, Intent intent) {
12477                // Now the broadcast is done, finish up the low-level shutdown.
12478                Log.i(TAG, "Shutting down activity manager...");
12479                shutdown(10000);
12480                Log.i(TAG, "Shutdown complete, restarting!");
12481                Process.killProcess(Process.myPid());
12482                System.exit(10);
12483            }
12484        };
12485
12486        // First send the high-level shut down broadcast.
12487        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12488        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12489        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12490        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12491        mContext.sendOrderedBroadcastAsUser(intent,
12492                UserHandle.ALL, null, br, mHandler, 0, null, null);
12493        */
12494        br.onReceive(mContext, intent);
12495    }
12496
12497    private long getLowRamTimeSinceIdle(long now) {
12498        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12499    }
12500
12501    @Override
12502    public void performIdleMaintenance() {
12503        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12504                != PackageManager.PERMISSION_GRANTED) {
12505            throw new SecurityException("Requires permission "
12506                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12507        }
12508
12509        synchronized (this) {
12510            final long now = SystemClock.uptimeMillis();
12511            final long timeSinceLastIdle = now - mLastIdleTime;
12512            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12513            mLastIdleTime = now;
12514            mLowRamTimeSinceLastIdle = 0;
12515            if (mLowRamStartTime != 0) {
12516                mLowRamStartTime = now;
12517            }
12518
12519            StringBuilder sb = new StringBuilder(128);
12520            sb.append("Idle maintenance over ");
12521            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12522            sb.append(" low RAM for ");
12523            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12524            Slog.i(TAG, sb.toString());
12525
12526            // If at least 1/3 of our time since the last idle period has been spent
12527            // with RAM low, then we want to kill processes.
12528            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12529
12530            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12531                ProcessRecord proc = mLruProcesses.get(i);
12532                if (proc.notCachedSinceIdle) {
12533                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12534                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12535                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12536                        if (doKilling && proc.initialIdlePss != 0
12537                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12538                            sb = new StringBuilder(128);
12539                            sb.append("Kill");
12540                            sb.append(proc.processName);
12541                            sb.append(" in idle maint: pss=");
12542                            sb.append(proc.lastPss);
12543                            sb.append(", swapPss=");
12544                            sb.append(proc.lastSwapPss);
12545                            sb.append(", initialPss=");
12546                            sb.append(proc.initialIdlePss);
12547                            sb.append(", period=");
12548                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12549                            sb.append(", lowRamPeriod=");
12550                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12551                            Slog.wtfQuiet(TAG, sb.toString());
12552                            proc.kill("idle maint (pss " + proc.lastPss
12553                                    + " from " + proc.initialIdlePss + ")", true);
12554                        }
12555                    }
12556                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12557                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12558                    proc.notCachedSinceIdle = true;
12559                    proc.initialIdlePss = 0;
12560                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12561                            mTestPssMode, isSleeping(), now);
12562                }
12563            }
12564
12565            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12566            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12567        }
12568    }
12569
12570    private void retrieveSettings() {
12571        final ContentResolver resolver = mContext.getContentResolver();
12572        final boolean freeformWindowManagement =
12573                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12574                        || Settings.Global.getInt(
12575                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12576        final boolean supportsPictureInPicture =
12577                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12578
12579        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12580        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12581        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12582        final boolean alwaysFinishActivities =
12583                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12584        final boolean lenientBackgroundCheck =
12585                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12586        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12587        final boolean forceResizable = Settings.Global.getInt(
12588                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12589        // Transfer any global setting for forcing RTL layout, into a System Property
12590        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12591
12592        final Configuration configuration = new Configuration();
12593        Settings.System.getConfiguration(resolver, configuration);
12594        if (forceRtl) {
12595            // This will take care of setting the correct layout direction flags
12596            configuration.setLayoutDirection(configuration.locale);
12597        }
12598
12599        synchronized (this) {
12600            mDebugApp = mOrigDebugApp = debugApp;
12601            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12602            mAlwaysFinishActivities = alwaysFinishActivities;
12603            mLenientBackgroundCheck = lenientBackgroundCheck;
12604            mForceResizableActivities = forceResizable;
12605            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12606            if (supportsMultiWindow || forceResizable) {
12607                mSupportsMultiWindow = true;
12608                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12609                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12610            } else {
12611                mSupportsMultiWindow = false;
12612                mSupportsFreeformWindowManagement = false;
12613                mSupportsPictureInPicture = false;
12614            }
12615            // This happens before any activities are started, so we can
12616            // change mConfiguration in-place.
12617            updateConfigurationLocked(configuration, null, true);
12618            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12619                    "Initial config: " + mConfiguration);
12620
12621            // Load resources only after the current configuration has been set.
12622            final Resources res = mContext.getResources();
12623            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12624            mThumbnailWidth = res.getDimensionPixelSize(
12625                    com.android.internal.R.dimen.thumbnail_width);
12626            mThumbnailHeight = res.getDimensionPixelSize(
12627                    com.android.internal.R.dimen.thumbnail_height);
12628            mFullscreenThumbnailScale = res.getFraction(
12629                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12630            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12631                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12632            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12633                    com.android.internal.R.string.config_appsNotReportingCrashes));
12634        }
12635    }
12636
12637    public boolean testIsSystemReady() {
12638        // no need to synchronize(this) just to read & return the value
12639        return mSystemReady;
12640    }
12641
12642    public void systemReady(final Runnable goingCallback) {
12643        synchronized(this) {
12644            if (mSystemReady) {
12645                // If we're done calling all the receivers, run the next "boot phase" passed in
12646                // by the SystemServer
12647                if (goingCallback != null) {
12648                    goingCallback.run();
12649                }
12650                return;
12651            }
12652
12653            mLocalDeviceIdleController
12654                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12655
12656            // Make sure we have the current profile info, since it is needed for security checks.
12657            mUserController.onSystemReady();
12658            mRecentTasks.onSystemReadyLocked();
12659            mAppOpsService.systemReady();
12660            mSystemReady = true;
12661        }
12662
12663        ArrayList<ProcessRecord> procsToKill = null;
12664        synchronized(mPidsSelfLocked) {
12665            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12666                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12667                if (!isAllowedWhileBooting(proc.info)){
12668                    if (procsToKill == null) {
12669                        procsToKill = new ArrayList<ProcessRecord>();
12670                    }
12671                    procsToKill.add(proc);
12672                }
12673            }
12674        }
12675
12676        synchronized(this) {
12677            if (procsToKill != null) {
12678                for (int i=procsToKill.size()-1; i>=0; i--) {
12679                    ProcessRecord proc = procsToKill.get(i);
12680                    Slog.i(TAG, "Removing system update proc: " + proc);
12681                    removeProcessLocked(proc, true, false, "system update done");
12682                }
12683            }
12684
12685            // Now that we have cleaned up any update processes, we
12686            // are ready to start launching real processes and know that
12687            // we won't trample on them any more.
12688            mProcessesReady = true;
12689        }
12690
12691        Slog.i(TAG, "System now ready");
12692        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12693            SystemClock.uptimeMillis());
12694
12695        synchronized(this) {
12696            // Make sure we have no pre-ready processes sitting around.
12697
12698            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12699                ResolveInfo ri = mContext.getPackageManager()
12700                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12701                                STOCK_PM_FLAGS);
12702                CharSequence errorMsg = null;
12703                if (ri != null) {
12704                    ActivityInfo ai = ri.activityInfo;
12705                    ApplicationInfo app = ai.applicationInfo;
12706                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12707                        mTopAction = Intent.ACTION_FACTORY_TEST;
12708                        mTopData = null;
12709                        mTopComponent = new ComponentName(app.packageName,
12710                                ai.name);
12711                    } else {
12712                        errorMsg = mContext.getResources().getText(
12713                                com.android.internal.R.string.factorytest_not_system);
12714                    }
12715                } else {
12716                    errorMsg = mContext.getResources().getText(
12717                            com.android.internal.R.string.factorytest_no_action);
12718                }
12719                if (errorMsg != null) {
12720                    mTopAction = null;
12721                    mTopData = null;
12722                    mTopComponent = null;
12723                    Message msg = Message.obtain();
12724                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12725                    msg.getData().putCharSequence("msg", errorMsg);
12726                    mUiHandler.sendMessage(msg);
12727                }
12728            }
12729        }
12730
12731        retrieveSettings();
12732        final int currentUserId;
12733        synchronized (this) {
12734            currentUserId = mUserController.getCurrentUserIdLocked();
12735            readGrantedUriPermissionsLocked();
12736        }
12737
12738        if (goingCallback != null) goingCallback.run();
12739
12740        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12741                Integer.toString(currentUserId), currentUserId);
12742        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12743                Integer.toString(currentUserId), currentUserId);
12744        mSystemServiceManager.startUser(currentUserId);
12745
12746        synchronized (this) {
12747            // Only start up encryption-aware persistent apps; once user is
12748            // unlocked we'll come back around and start unaware apps
12749            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12750
12751            // Start up initial activity.
12752            mBooting = true;
12753            // Enable home activity for system user, so that the system can always boot
12754            if (UserManager.isSplitSystemUser()) {
12755                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12756                try {
12757                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12758                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12759                            UserHandle.USER_SYSTEM);
12760                } catch (RemoteException e) {
12761                    throw e.rethrowAsRuntimeException();
12762                }
12763            }
12764            startHomeActivityLocked(currentUserId, "systemReady");
12765
12766            try {
12767                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12768                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12769                            + " data partition or your device will be unstable.");
12770                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12771                }
12772            } catch (RemoteException e) {
12773            }
12774
12775            if (!Build.isBuildConsistent()) {
12776                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12777                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12778            }
12779
12780            long ident = Binder.clearCallingIdentity();
12781            try {
12782                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12783                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12784                        | Intent.FLAG_RECEIVER_FOREGROUND);
12785                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12786                broadcastIntentLocked(null, null, intent,
12787                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12788                        null, false, false, MY_PID, Process.SYSTEM_UID,
12789                        currentUserId);
12790                intent = new Intent(Intent.ACTION_USER_STARTING);
12791                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12792                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12793                broadcastIntentLocked(null, null, intent,
12794                        null, new IIntentReceiver.Stub() {
12795                            @Override
12796                            public void performReceive(Intent intent, int resultCode, String data,
12797                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12798                                    throws RemoteException {
12799                            }
12800                        }, 0, null, null,
12801                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12802                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12803            } catch (Throwable t) {
12804                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12805            } finally {
12806                Binder.restoreCallingIdentity(ident);
12807            }
12808            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12809            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12810        }
12811    }
12812
12813    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12814        synchronized (this) {
12815            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12816        }
12817    }
12818
12819    void skipCurrentReceiverLocked(ProcessRecord app) {
12820        for (BroadcastQueue queue : mBroadcastQueues) {
12821            queue.skipCurrentReceiverLocked(app);
12822        }
12823    }
12824
12825    /**
12826     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12827     * The application process will exit immediately after this call returns.
12828     * @param app object of the crashing app, null for the system server
12829     * @param crashInfo describing the exception
12830     */
12831    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12832        ProcessRecord r = findAppProcess(app, "Crash");
12833        final String processName = app == null ? "system_server"
12834                : (r == null ? "unknown" : r.processName);
12835
12836        handleApplicationCrashInner("crash", r, processName, crashInfo);
12837    }
12838
12839    /* Native crash reporting uses this inner version because it needs to be somewhat
12840     * decoupled from the AM-managed cleanup lifecycle
12841     */
12842    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12843            ApplicationErrorReport.CrashInfo crashInfo) {
12844        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12845                UserHandle.getUserId(Binder.getCallingUid()), processName,
12846                r == null ? -1 : r.info.flags,
12847                crashInfo.exceptionClassName,
12848                crashInfo.exceptionMessage,
12849                crashInfo.throwFileName,
12850                crashInfo.throwLineNumber);
12851
12852        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12853
12854        mAppErrors.crashApplication(r, crashInfo);
12855    }
12856
12857    public void handleApplicationStrictModeViolation(
12858            IBinder app,
12859            int violationMask,
12860            StrictMode.ViolationInfo info) {
12861        ProcessRecord r = findAppProcess(app, "StrictMode");
12862        if (r == null) {
12863            return;
12864        }
12865
12866        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12867            Integer stackFingerprint = info.hashCode();
12868            boolean logIt = true;
12869            synchronized (mAlreadyLoggedViolatedStacks) {
12870                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12871                    logIt = false;
12872                    // TODO: sub-sample into EventLog for these, with
12873                    // the info.durationMillis?  Then we'd get
12874                    // the relative pain numbers, without logging all
12875                    // the stack traces repeatedly.  We'd want to do
12876                    // likewise in the client code, which also does
12877                    // dup suppression, before the Binder call.
12878                } else {
12879                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12880                        mAlreadyLoggedViolatedStacks.clear();
12881                    }
12882                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12883                }
12884            }
12885            if (logIt) {
12886                logStrictModeViolationToDropBox(r, info);
12887            }
12888        }
12889
12890        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12891            AppErrorResult result = new AppErrorResult();
12892            synchronized (this) {
12893                final long origId = Binder.clearCallingIdentity();
12894
12895                Message msg = Message.obtain();
12896                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12897                HashMap<String, Object> data = new HashMap<String, Object>();
12898                data.put("result", result);
12899                data.put("app", r);
12900                data.put("violationMask", violationMask);
12901                data.put("info", info);
12902                msg.obj = data;
12903                mUiHandler.sendMessage(msg);
12904
12905                Binder.restoreCallingIdentity(origId);
12906            }
12907            int res = result.get();
12908            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12909        }
12910    }
12911
12912    // Depending on the policy in effect, there could be a bunch of
12913    // these in quick succession so we try to batch these together to
12914    // minimize disk writes, number of dropbox entries, and maximize
12915    // compression, by having more fewer, larger records.
12916    private void logStrictModeViolationToDropBox(
12917            ProcessRecord process,
12918            StrictMode.ViolationInfo info) {
12919        if (info == null) {
12920            return;
12921        }
12922        final boolean isSystemApp = process == null ||
12923                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12924                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12925        final String processName = process == null ? "unknown" : process.processName;
12926        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12927        final DropBoxManager dbox = (DropBoxManager)
12928                mContext.getSystemService(Context.DROPBOX_SERVICE);
12929
12930        // Exit early if the dropbox isn't configured to accept this report type.
12931        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12932
12933        boolean bufferWasEmpty;
12934        boolean needsFlush;
12935        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12936        synchronized (sb) {
12937            bufferWasEmpty = sb.length() == 0;
12938            appendDropBoxProcessHeaders(process, processName, sb);
12939            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12940            sb.append("System-App: ").append(isSystemApp).append("\n");
12941            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12942            if (info.violationNumThisLoop != 0) {
12943                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12944            }
12945            if (info.numAnimationsRunning != 0) {
12946                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12947            }
12948            if (info.broadcastIntentAction != null) {
12949                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12950            }
12951            if (info.durationMillis != -1) {
12952                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12953            }
12954            if (info.numInstances != -1) {
12955                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12956            }
12957            if (info.tags != null) {
12958                for (String tag : info.tags) {
12959                    sb.append("Span-Tag: ").append(tag).append("\n");
12960                }
12961            }
12962            sb.append("\n");
12963            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12964                sb.append(info.crashInfo.stackTrace);
12965                sb.append("\n");
12966            }
12967            if (info.message != null) {
12968                sb.append(info.message);
12969                sb.append("\n");
12970            }
12971
12972            // Only buffer up to ~64k.  Various logging bits truncate
12973            // things at 128k.
12974            needsFlush = (sb.length() > 64 * 1024);
12975        }
12976
12977        // Flush immediately if the buffer's grown too large, or this
12978        // is a non-system app.  Non-system apps are isolated with a
12979        // different tag & policy and not batched.
12980        //
12981        // Batching is useful during internal testing with
12982        // StrictMode settings turned up high.  Without batching,
12983        // thousands of separate files could be created on boot.
12984        if (!isSystemApp || needsFlush) {
12985            new Thread("Error dump: " + dropboxTag) {
12986                @Override
12987                public void run() {
12988                    String report;
12989                    synchronized (sb) {
12990                        report = sb.toString();
12991                        sb.delete(0, sb.length());
12992                        sb.trimToSize();
12993                    }
12994                    if (report.length() != 0) {
12995                        dbox.addText(dropboxTag, report);
12996                    }
12997                }
12998            }.start();
12999            return;
13000        }
13001
13002        // System app batching:
13003        if (!bufferWasEmpty) {
13004            // An existing dropbox-writing thread is outstanding, so
13005            // we don't need to start it up.  The existing thread will
13006            // catch the buffer appends we just did.
13007            return;
13008        }
13009
13010        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13011        // (After this point, we shouldn't access AMS internal data structures.)
13012        new Thread("Error dump: " + dropboxTag) {
13013            @Override
13014            public void run() {
13015                // 5 second sleep to let stacks arrive and be batched together
13016                try {
13017                    Thread.sleep(5000);  // 5 seconds
13018                } catch (InterruptedException e) {}
13019
13020                String errorReport;
13021                synchronized (mStrictModeBuffer) {
13022                    errorReport = mStrictModeBuffer.toString();
13023                    if (errorReport.length() == 0) {
13024                        return;
13025                    }
13026                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13027                    mStrictModeBuffer.trimToSize();
13028                }
13029                dbox.addText(dropboxTag, errorReport);
13030            }
13031        }.start();
13032    }
13033
13034    /**
13035     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13036     * @param app object of the crashing app, null for the system server
13037     * @param tag reported by the caller
13038     * @param system whether this wtf is coming from the system
13039     * @param crashInfo describing the context of the error
13040     * @return true if the process should exit immediately (WTF is fatal)
13041     */
13042    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13043            final ApplicationErrorReport.CrashInfo crashInfo) {
13044        final int callingUid = Binder.getCallingUid();
13045        final int callingPid = Binder.getCallingPid();
13046
13047        if (system) {
13048            // If this is coming from the system, we could very well have low-level
13049            // system locks held, so we want to do this all asynchronously.  And we
13050            // never want this to become fatal, so there is that too.
13051            mHandler.post(new Runnable() {
13052                @Override public void run() {
13053                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13054                }
13055            });
13056            return false;
13057        }
13058
13059        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13060                crashInfo);
13061
13062        if (r != null && r.pid != Process.myPid() &&
13063                Settings.Global.getInt(mContext.getContentResolver(),
13064                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13065            mAppErrors.crashApplication(r, crashInfo);
13066            return true;
13067        } else {
13068            return false;
13069        }
13070    }
13071
13072    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13073            final ApplicationErrorReport.CrashInfo crashInfo) {
13074        final ProcessRecord r = findAppProcess(app, "WTF");
13075        final String processName = app == null ? "system_server"
13076                : (r == null ? "unknown" : r.processName);
13077
13078        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13079                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13080
13081        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13082
13083        return r;
13084    }
13085
13086    /**
13087     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13088     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13089     */
13090    private ProcessRecord findAppProcess(IBinder app, String reason) {
13091        if (app == null) {
13092            return null;
13093        }
13094
13095        synchronized (this) {
13096            final int NP = mProcessNames.getMap().size();
13097            for (int ip=0; ip<NP; ip++) {
13098                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13099                final int NA = apps.size();
13100                for (int ia=0; ia<NA; ia++) {
13101                    ProcessRecord p = apps.valueAt(ia);
13102                    if (p.thread != null && p.thread.asBinder() == app) {
13103                        return p;
13104                    }
13105                }
13106            }
13107
13108            Slog.w(TAG, "Can't find mystery application for " + reason
13109                    + " from pid=" + Binder.getCallingPid()
13110                    + " uid=" + Binder.getCallingUid() + ": " + app);
13111            return null;
13112        }
13113    }
13114
13115    /**
13116     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13117     * to append various headers to the dropbox log text.
13118     */
13119    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13120            StringBuilder sb) {
13121        // Watchdog thread ends up invoking this function (with
13122        // a null ProcessRecord) to add the stack file to dropbox.
13123        // Do not acquire a lock on this (am) in such cases, as it
13124        // could cause a potential deadlock, if and when watchdog
13125        // is invoked due to unavailability of lock on am and it
13126        // would prevent watchdog from killing system_server.
13127        if (process == null) {
13128            sb.append("Process: ").append(processName).append("\n");
13129            return;
13130        }
13131        // Note: ProcessRecord 'process' is guarded by the service
13132        // instance.  (notably process.pkgList, which could otherwise change
13133        // concurrently during execution of this method)
13134        synchronized (this) {
13135            sb.append("Process: ").append(processName).append("\n");
13136            int flags = process.info.flags;
13137            IPackageManager pm = AppGlobals.getPackageManager();
13138            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13139            for (int ip=0; ip<process.pkgList.size(); ip++) {
13140                String pkg = process.pkgList.keyAt(ip);
13141                sb.append("Package: ").append(pkg);
13142                try {
13143                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13144                    if (pi != null) {
13145                        sb.append(" v").append(pi.versionCode);
13146                        if (pi.versionName != null) {
13147                            sb.append(" (").append(pi.versionName).append(")");
13148                        }
13149                    }
13150                } catch (RemoteException e) {
13151                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13152                }
13153                sb.append("\n");
13154            }
13155        }
13156    }
13157
13158    private static String processClass(ProcessRecord process) {
13159        if (process == null || process.pid == MY_PID) {
13160            return "system_server";
13161        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13162            return "system_app";
13163        } else {
13164            return "data_app";
13165        }
13166    }
13167
13168    private volatile long mWtfClusterStart;
13169    private volatile int mWtfClusterCount;
13170
13171    /**
13172     * Write a description of an error (crash, WTF, ANR) to the drop box.
13173     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13174     * @param process which caused the error, null means the system server
13175     * @param activity which triggered the error, null if unknown
13176     * @param parent activity related to the error, null if unknown
13177     * @param subject line related to the error, null if absent
13178     * @param report in long form describing the error, null if absent
13179     * @param logFile to include in the report, null if none
13180     * @param crashInfo giving an application stack trace, null if absent
13181     */
13182    public void addErrorToDropBox(String eventType,
13183            ProcessRecord process, String processName, ActivityRecord activity,
13184            ActivityRecord parent, String subject,
13185            final String report, final File logFile,
13186            final ApplicationErrorReport.CrashInfo crashInfo) {
13187        // NOTE -- this must never acquire the ActivityManagerService lock,
13188        // otherwise the watchdog may be prevented from resetting the system.
13189
13190        final String dropboxTag = processClass(process) + "_" + eventType;
13191        final DropBoxManager dbox = (DropBoxManager)
13192                mContext.getSystemService(Context.DROPBOX_SERVICE);
13193
13194        // Exit early if the dropbox isn't configured to accept this report type.
13195        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13196
13197        // Rate-limit how often we're willing to do the heavy lifting below to
13198        // collect and record logs; currently 5 logs per 10 second period.
13199        final long now = SystemClock.elapsedRealtime();
13200        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13201            mWtfClusterStart = now;
13202            mWtfClusterCount = 1;
13203        } else {
13204            if (mWtfClusterCount++ >= 5) return;
13205        }
13206
13207        final StringBuilder sb = new StringBuilder(1024);
13208        appendDropBoxProcessHeaders(process, processName, sb);
13209        if (process != null) {
13210            sb.append("Foreground: ")
13211                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13212                    .append("\n");
13213        }
13214        if (activity != null) {
13215            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13216        }
13217        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13218            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13219        }
13220        if (parent != null && parent != activity) {
13221            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13222        }
13223        if (subject != null) {
13224            sb.append("Subject: ").append(subject).append("\n");
13225        }
13226        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13227        if (Debug.isDebuggerConnected()) {
13228            sb.append("Debugger: Connected\n");
13229        }
13230        sb.append("\n");
13231
13232        // Do the rest in a worker thread to avoid blocking the caller on I/O
13233        // (After this point, we shouldn't access AMS internal data structures.)
13234        Thread worker = new Thread("Error dump: " + dropboxTag) {
13235            @Override
13236            public void run() {
13237                if (report != null) {
13238                    sb.append(report);
13239                }
13240                if (logFile != null) {
13241                    try {
13242                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13243                                    "\n\n[[TRUNCATED]]"));
13244                    } catch (IOException e) {
13245                        Slog.e(TAG, "Error reading " + logFile, e);
13246                    }
13247                }
13248                if (crashInfo != null && crashInfo.stackTrace != null) {
13249                    sb.append(crashInfo.stackTrace);
13250                }
13251
13252                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13253                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13254                if (lines > 0) {
13255                    sb.append("\n");
13256
13257                    // Merge several logcat streams, and take the last N lines
13258                    InputStreamReader input = null;
13259                    try {
13260                        java.lang.Process logcat = new ProcessBuilder(
13261                                "/system/bin/timeout", "-k", "15s", "10s",
13262                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13263                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13264                                        .redirectErrorStream(true).start();
13265
13266                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13267                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13268                        input = new InputStreamReader(logcat.getInputStream());
13269
13270                        int num;
13271                        char[] buf = new char[8192];
13272                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13273                    } catch (IOException e) {
13274                        Slog.e(TAG, "Error running logcat", e);
13275                    } finally {
13276                        if (input != null) try { input.close(); } catch (IOException e) {}
13277                    }
13278                }
13279
13280                dbox.addText(dropboxTag, sb.toString());
13281            }
13282        };
13283
13284        if (process == null) {
13285            // If process is null, we are being called from some internal code
13286            // and may be about to die -- run this synchronously.
13287            worker.run();
13288        } else {
13289            worker.start();
13290        }
13291    }
13292
13293    @Override
13294    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13295        enforceNotIsolatedCaller("getProcessesInErrorState");
13296        // assume our apps are happy - lazy create the list
13297        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13298
13299        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13300                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13301        int userId = UserHandle.getUserId(Binder.getCallingUid());
13302
13303        synchronized (this) {
13304
13305            // iterate across all processes
13306            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13307                ProcessRecord app = mLruProcesses.get(i);
13308                if (!allUsers && app.userId != userId) {
13309                    continue;
13310                }
13311                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13312                    // This one's in trouble, so we'll generate a report for it
13313                    // crashes are higher priority (in case there's a crash *and* an anr)
13314                    ActivityManager.ProcessErrorStateInfo report = null;
13315                    if (app.crashing) {
13316                        report = app.crashingReport;
13317                    } else if (app.notResponding) {
13318                        report = app.notRespondingReport;
13319                    }
13320
13321                    if (report != null) {
13322                        if (errList == null) {
13323                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13324                        }
13325                        errList.add(report);
13326                    } else {
13327                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13328                                " crashing = " + app.crashing +
13329                                " notResponding = " + app.notResponding);
13330                    }
13331                }
13332            }
13333        }
13334
13335        return errList;
13336    }
13337
13338    static int procStateToImportance(int procState, int memAdj,
13339            ActivityManager.RunningAppProcessInfo currApp) {
13340        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13341        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13342            currApp.lru = memAdj;
13343        } else {
13344            currApp.lru = 0;
13345        }
13346        return imp;
13347    }
13348
13349    private void fillInProcMemInfo(ProcessRecord app,
13350            ActivityManager.RunningAppProcessInfo outInfo) {
13351        outInfo.pid = app.pid;
13352        outInfo.uid = app.info.uid;
13353        if (mHeavyWeightProcess == app) {
13354            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13355        }
13356        if (app.persistent) {
13357            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13358        }
13359        if (app.activities.size() > 0) {
13360            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13361        }
13362        outInfo.lastTrimLevel = app.trimMemoryLevel;
13363        int adj = app.curAdj;
13364        int procState = app.curProcState;
13365        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13366        outInfo.importanceReasonCode = app.adjTypeCode;
13367        outInfo.processState = app.curProcState;
13368    }
13369
13370    @Override
13371    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13372        enforceNotIsolatedCaller("getRunningAppProcesses");
13373
13374        final int callingUid = Binder.getCallingUid();
13375
13376        // Lazy instantiation of list
13377        List<ActivityManager.RunningAppProcessInfo> runList = null;
13378        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13379                callingUid) == PackageManager.PERMISSION_GRANTED;
13380        final int userId = UserHandle.getUserId(callingUid);
13381        final boolean allUids = isGetTasksAllowed(
13382                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13383
13384        synchronized (this) {
13385            // Iterate across all processes
13386            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13387                ProcessRecord app = mLruProcesses.get(i);
13388                if ((!allUsers && app.userId != userId)
13389                        || (!allUids && app.uid != callingUid)) {
13390                    continue;
13391                }
13392                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13393                    // Generate process state info for running application
13394                    ActivityManager.RunningAppProcessInfo currApp =
13395                        new ActivityManager.RunningAppProcessInfo(app.processName,
13396                                app.pid, app.getPackageList());
13397                    fillInProcMemInfo(app, currApp);
13398                    if (app.adjSource instanceof ProcessRecord) {
13399                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13400                        currApp.importanceReasonImportance =
13401                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13402                                        app.adjSourceProcState);
13403                    } else if (app.adjSource instanceof ActivityRecord) {
13404                        ActivityRecord r = (ActivityRecord)app.adjSource;
13405                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13406                    }
13407                    if (app.adjTarget instanceof ComponentName) {
13408                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13409                    }
13410                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13411                    //        + " lru=" + currApp.lru);
13412                    if (runList == null) {
13413                        runList = new ArrayList<>();
13414                    }
13415                    runList.add(currApp);
13416                }
13417            }
13418        }
13419        return runList;
13420    }
13421
13422    @Override
13423    public List<ApplicationInfo> getRunningExternalApplications() {
13424        enforceNotIsolatedCaller("getRunningExternalApplications");
13425        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13426        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13427        if (runningApps != null && runningApps.size() > 0) {
13428            Set<String> extList = new HashSet<String>();
13429            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13430                if (app.pkgList != null) {
13431                    for (String pkg : app.pkgList) {
13432                        extList.add(pkg);
13433                    }
13434                }
13435            }
13436            IPackageManager pm = AppGlobals.getPackageManager();
13437            for (String pkg : extList) {
13438                try {
13439                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13440                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13441                        retList.add(info);
13442                    }
13443                } catch (RemoteException e) {
13444                }
13445            }
13446        }
13447        return retList;
13448    }
13449
13450    @Override
13451    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13452        enforceNotIsolatedCaller("getMyMemoryState");
13453        synchronized (this) {
13454            ProcessRecord proc;
13455            synchronized (mPidsSelfLocked) {
13456                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13457            }
13458            fillInProcMemInfo(proc, outInfo);
13459        }
13460    }
13461
13462    @Override
13463    public int getMemoryTrimLevel() {
13464        enforceNotIsolatedCaller("getMyMemoryState");
13465        synchronized (this) {
13466            return mLastMemoryLevel;
13467        }
13468    }
13469
13470    @Override
13471    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13472            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13473        (new ActivityManagerShellCommand(this, false)).exec(
13474                this, in, out, err, args, resultReceiver);
13475    }
13476
13477    @Override
13478    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13479        if (checkCallingPermission(android.Manifest.permission.DUMP)
13480                != PackageManager.PERMISSION_GRANTED) {
13481            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13482                    + Binder.getCallingPid()
13483                    + ", uid=" + Binder.getCallingUid()
13484                    + " without permission "
13485                    + android.Manifest.permission.DUMP);
13486            return;
13487        }
13488
13489        boolean dumpAll = false;
13490        boolean dumpClient = false;
13491        String dumpPackage = null;
13492
13493        int opti = 0;
13494        while (opti < args.length) {
13495            String opt = args[opti];
13496            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13497                break;
13498            }
13499            opti++;
13500            if ("-a".equals(opt)) {
13501                dumpAll = true;
13502            } else if ("-c".equals(opt)) {
13503                dumpClient = true;
13504            } else if ("-p".equals(opt)) {
13505                if (opti < args.length) {
13506                    dumpPackage = args[opti];
13507                    opti++;
13508                } else {
13509                    pw.println("Error: -p option requires package argument");
13510                    return;
13511                }
13512                dumpClient = true;
13513            } else if ("-h".equals(opt)) {
13514                ActivityManagerShellCommand.dumpHelp(pw, true);
13515                return;
13516            } else {
13517                pw.println("Unknown argument: " + opt + "; use -h for help");
13518            }
13519        }
13520
13521        long origId = Binder.clearCallingIdentity();
13522        boolean more = false;
13523        // Is the caller requesting to dump a particular piece of data?
13524        if (opti < args.length) {
13525            String cmd = args[opti];
13526            opti++;
13527            if ("activities".equals(cmd) || "a".equals(cmd)) {
13528                synchronized (this) {
13529                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13530                }
13531            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13532                synchronized (this) {
13533                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13534                }
13535            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13536                String[] newArgs;
13537                String name;
13538                if (opti >= args.length) {
13539                    name = null;
13540                    newArgs = EMPTY_STRING_ARRAY;
13541                } else {
13542                    dumpPackage = args[opti];
13543                    opti++;
13544                    newArgs = new String[args.length - opti];
13545                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13546                            args.length - opti);
13547                }
13548                synchronized (this) {
13549                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13550                }
13551            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13552                String[] newArgs;
13553                String name;
13554                if (opti >= args.length) {
13555                    name = null;
13556                    newArgs = EMPTY_STRING_ARRAY;
13557                } else {
13558                    dumpPackage = args[opti];
13559                    opti++;
13560                    newArgs = new String[args.length - opti];
13561                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13562                            args.length - opti);
13563                }
13564                synchronized (this) {
13565                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13566                }
13567            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13568                String[] newArgs;
13569                String name;
13570                if (opti >= args.length) {
13571                    name = null;
13572                    newArgs = EMPTY_STRING_ARRAY;
13573                } else {
13574                    dumpPackage = args[opti];
13575                    opti++;
13576                    newArgs = new String[args.length - opti];
13577                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13578                            args.length - opti);
13579                }
13580                synchronized (this) {
13581                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13582                }
13583            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13584                synchronized (this) {
13585                    dumpOomLocked(fd, pw, args, opti, true);
13586                }
13587            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13588                synchronized (this) {
13589                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13590                }
13591            } else if ("provider".equals(cmd)) {
13592                String[] newArgs;
13593                String name;
13594                if (opti >= args.length) {
13595                    name = null;
13596                    newArgs = EMPTY_STRING_ARRAY;
13597                } else {
13598                    name = args[opti];
13599                    opti++;
13600                    newArgs = new String[args.length - opti];
13601                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13602                }
13603                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13604                    pw.println("No providers match: " + name);
13605                    pw.println("Use -h for help.");
13606                }
13607            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13608                synchronized (this) {
13609                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13610                }
13611            } else if ("service".equals(cmd)) {
13612                String[] newArgs;
13613                String name;
13614                if (opti >= args.length) {
13615                    name = null;
13616                    newArgs = EMPTY_STRING_ARRAY;
13617                } else {
13618                    name = args[opti];
13619                    opti++;
13620                    newArgs = new String[args.length - opti];
13621                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13622                            args.length - opti);
13623                }
13624                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13625                    pw.println("No services match: " + name);
13626                    pw.println("Use -h for help.");
13627                }
13628            } else if ("package".equals(cmd)) {
13629                String[] newArgs;
13630                if (opti >= args.length) {
13631                    pw.println("package: no package name specified");
13632                    pw.println("Use -h for help.");
13633                } else {
13634                    dumpPackage = args[opti];
13635                    opti++;
13636                    newArgs = new String[args.length - opti];
13637                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13638                            args.length - opti);
13639                    args = newArgs;
13640                    opti = 0;
13641                    more = true;
13642                }
13643            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13644                synchronized (this) {
13645                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13646                }
13647            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13648                synchronized (this) {
13649                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13650                }
13651            } else if ("locks".equals(cmd)) {
13652                LockGuard.dump(fd, pw, args);
13653            } else {
13654                // Dumping a single activity?
13655                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13656                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13657                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13658                    if (res < 0) {
13659                        pw.println("Bad activity command, or no activities match: " + cmd);
13660                        pw.println("Use -h for help.");
13661                    }
13662                }
13663            }
13664            if (!more) {
13665                Binder.restoreCallingIdentity(origId);
13666                return;
13667            }
13668        }
13669
13670        // No piece of data specified, dump everything.
13671        synchronized (this) {
13672            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13673            pw.println();
13674            if (dumpAll) {
13675                pw.println("-------------------------------------------------------------------------------");
13676            }
13677            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13678            pw.println();
13679            if (dumpAll) {
13680                pw.println("-------------------------------------------------------------------------------");
13681            }
13682            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13683            pw.println();
13684            if (dumpAll) {
13685                pw.println("-------------------------------------------------------------------------------");
13686            }
13687            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13688            pw.println();
13689            if (dumpAll) {
13690                pw.println("-------------------------------------------------------------------------------");
13691            }
13692            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13693            pw.println();
13694            if (dumpAll) {
13695                pw.println("-------------------------------------------------------------------------------");
13696            }
13697            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13698            pw.println();
13699            if (dumpAll) {
13700                pw.println("-------------------------------------------------------------------------------");
13701            }
13702            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13703            if (mAssociations.size() > 0) {
13704                pw.println();
13705                if (dumpAll) {
13706                    pw.println("-------------------------------------------------------------------------------");
13707                }
13708                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13709            }
13710            pw.println();
13711            if (dumpAll) {
13712                pw.println("-------------------------------------------------------------------------------");
13713            }
13714            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13715        }
13716        Binder.restoreCallingIdentity(origId);
13717    }
13718
13719    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13720            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13721        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13722
13723        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13724                dumpPackage);
13725        boolean needSep = printedAnything;
13726
13727        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13728                dumpPackage, needSep, "  mFocusedActivity: ");
13729        if (printed) {
13730            printedAnything = true;
13731            needSep = false;
13732        }
13733
13734        if (dumpPackage == null) {
13735            if (needSep) {
13736                pw.println();
13737            }
13738            needSep = true;
13739            printedAnything = true;
13740            mStackSupervisor.dump(pw, "  ");
13741        }
13742
13743        if (!printedAnything) {
13744            pw.println("  (nothing)");
13745        }
13746    }
13747
13748    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13749            int opti, boolean dumpAll, String dumpPackage) {
13750        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13751
13752        boolean printedAnything = false;
13753
13754        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13755            boolean printedHeader = false;
13756
13757            final int N = mRecentTasks.size();
13758            for (int i=0; i<N; i++) {
13759                TaskRecord tr = mRecentTasks.get(i);
13760                if (dumpPackage != null) {
13761                    if (tr.realActivity == null ||
13762                            !dumpPackage.equals(tr.realActivity)) {
13763                        continue;
13764                    }
13765                }
13766                if (!printedHeader) {
13767                    pw.println("  Recent tasks:");
13768                    printedHeader = true;
13769                    printedAnything = true;
13770                }
13771                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13772                        pw.println(tr);
13773                if (dumpAll) {
13774                    mRecentTasks.get(i).dump(pw, "    ");
13775                }
13776            }
13777        }
13778
13779        if (!printedAnything) {
13780            pw.println("  (nothing)");
13781        }
13782    }
13783
13784    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13785            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13786        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13787
13788        int dumpUid = 0;
13789        if (dumpPackage != null) {
13790            IPackageManager pm = AppGlobals.getPackageManager();
13791            try {
13792                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13793            } catch (RemoteException e) {
13794            }
13795        }
13796
13797        boolean printedAnything = false;
13798
13799        final long now = SystemClock.uptimeMillis();
13800
13801        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13802            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13803                    = mAssociations.valueAt(i1);
13804            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13805                SparseArray<ArrayMap<String, Association>> sourceUids
13806                        = targetComponents.valueAt(i2);
13807                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13808                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13809                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13810                        Association ass = sourceProcesses.valueAt(i4);
13811                        if (dumpPackage != null) {
13812                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13813                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13814                                continue;
13815                            }
13816                        }
13817                        printedAnything = true;
13818                        pw.print("  ");
13819                        pw.print(ass.mTargetProcess);
13820                        pw.print("/");
13821                        UserHandle.formatUid(pw, ass.mTargetUid);
13822                        pw.print(" <- ");
13823                        pw.print(ass.mSourceProcess);
13824                        pw.print("/");
13825                        UserHandle.formatUid(pw, ass.mSourceUid);
13826                        pw.println();
13827                        pw.print("    via ");
13828                        pw.print(ass.mTargetComponent.flattenToShortString());
13829                        pw.println();
13830                        pw.print("    ");
13831                        long dur = ass.mTime;
13832                        if (ass.mNesting > 0) {
13833                            dur += now - ass.mStartTime;
13834                        }
13835                        TimeUtils.formatDuration(dur, pw);
13836                        pw.print(" (");
13837                        pw.print(ass.mCount);
13838                        pw.print(" times)");
13839                        pw.print("  ");
13840                        for (int i=0; i<ass.mStateTimes.length; i++) {
13841                            long amt = ass.mStateTimes[i];
13842                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13843                                amt += now - ass.mLastStateUptime;
13844                            }
13845                            if (amt != 0) {
13846                                pw.print(" ");
13847                                pw.print(ProcessList.makeProcStateString(
13848                                            i + ActivityManager.MIN_PROCESS_STATE));
13849                                pw.print("=");
13850                                TimeUtils.formatDuration(amt, pw);
13851                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13852                                    pw.print("*");
13853                                }
13854                            }
13855                        }
13856                        pw.println();
13857                        if (ass.mNesting > 0) {
13858                            pw.print("    Currently active: ");
13859                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13860                            pw.println();
13861                        }
13862                    }
13863                }
13864            }
13865
13866        }
13867
13868        if (!printedAnything) {
13869            pw.println("  (nothing)");
13870        }
13871    }
13872
13873    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13874            String header, boolean needSep) {
13875        boolean printed = false;
13876        int whichAppId = -1;
13877        if (dumpPackage != null) {
13878            try {
13879                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13880                        dumpPackage, 0);
13881                whichAppId = UserHandle.getAppId(info.uid);
13882            } catch (NameNotFoundException e) {
13883                e.printStackTrace();
13884            }
13885        }
13886        for (int i=0; i<uids.size(); i++) {
13887            UidRecord uidRec = uids.valueAt(i);
13888            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13889                continue;
13890            }
13891            if (!printed) {
13892                printed = true;
13893                if (needSep) {
13894                    pw.println();
13895                }
13896                pw.print("  ");
13897                pw.println(header);
13898                needSep = true;
13899            }
13900            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13901            pw.print(": "); pw.println(uidRec);
13902        }
13903        return printed;
13904    }
13905
13906    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13907            int opti, boolean dumpAll, String dumpPackage) {
13908        boolean needSep = false;
13909        boolean printedAnything = false;
13910        int numPers = 0;
13911
13912        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13913
13914        if (dumpAll) {
13915            final int NP = mProcessNames.getMap().size();
13916            for (int ip=0; ip<NP; ip++) {
13917                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13918                final int NA = procs.size();
13919                for (int ia=0; ia<NA; ia++) {
13920                    ProcessRecord r = procs.valueAt(ia);
13921                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13922                        continue;
13923                    }
13924                    if (!needSep) {
13925                        pw.println("  All known processes:");
13926                        needSep = true;
13927                        printedAnything = true;
13928                    }
13929                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13930                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13931                        pw.print(" "); pw.println(r);
13932                    r.dump(pw, "    ");
13933                    if (r.persistent) {
13934                        numPers++;
13935                    }
13936                }
13937            }
13938        }
13939
13940        if (mIsolatedProcesses.size() > 0) {
13941            boolean printed = false;
13942            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13943                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13944                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13945                    continue;
13946                }
13947                if (!printed) {
13948                    if (needSep) {
13949                        pw.println();
13950                    }
13951                    pw.println("  Isolated process list (sorted by uid):");
13952                    printedAnything = true;
13953                    printed = true;
13954                    needSep = true;
13955                }
13956                pw.println(String.format("%sIsolated #%2d: %s",
13957                        "    ", i, r.toString()));
13958            }
13959        }
13960
13961        if (mActiveUids.size() > 0) {
13962            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13963                printedAnything = needSep = true;
13964            }
13965        }
13966        if (mValidateUids.size() > 0) {
13967            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13968                printedAnything = needSep = true;
13969            }
13970        }
13971
13972        if (mLruProcesses.size() > 0) {
13973            if (needSep) {
13974                pw.println();
13975            }
13976            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13977                    pw.print(" total, non-act at ");
13978                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13979                    pw.print(", non-svc at ");
13980                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13981                    pw.println("):");
13982            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13983            needSep = true;
13984            printedAnything = true;
13985        }
13986
13987        if (dumpAll || dumpPackage != null) {
13988            synchronized (mPidsSelfLocked) {
13989                boolean printed = false;
13990                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13991                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13992                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13993                        continue;
13994                    }
13995                    if (!printed) {
13996                        if (needSep) pw.println();
13997                        needSep = true;
13998                        pw.println("  PID mappings:");
13999                        printed = true;
14000                        printedAnything = true;
14001                    }
14002                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14003                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14004                }
14005            }
14006        }
14007
14008        if (mForegroundProcesses.size() > 0) {
14009            synchronized (mPidsSelfLocked) {
14010                boolean printed = false;
14011                for (int i=0; i<mForegroundProcesses.size(); i++) {
14012                    ProcessRecord r = mPidsSelfLocked.get(
14013                            mForegroundProcesses.valueAt(i).pid);
14014                    if (dumpPackage != null && (r == null
14015                            || !r.pkgList.containsKey(dumpPackage))) {
14016                        continue;
14017                    }
14018                    if (!printed) {
14019                        if (needSep) pw.println();
14020                        needSep = true;
14021                        pw.println("  Foreground Processes:");
14022                        printed = true;
14023                        printedAnything = true;
14024                    }
14025                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14026                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14027                }
14028            }
14029        }
14030
14031        if (mPersistentStartingProcesses.size() > 0) {
14032            if (needSep) pw.println();
14033            needSep = true;
14034            printedAnything = true;
14035            pw.println("  Persisent processes that are starting:");
14036            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14037                    "Starting Norm", "Restarting PERS", dumpPackage);
14038        }
14039
14040        if (mRemovedProcesses.size() > 0) {
14041            if (needSep) pw.println();
14042            needSep = true;
14043            printedAnything = true;
14044            pw.println("  Processes that are being removed:");
14045            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14046                    "Removed Norm", "Removed PERS", dumpPackage);
14047        }
14048
14049        if (mProcessesOnHold.size() > 0) {
14050            if (needSep) pw.println();
14051            needSep = true;
14052            printedAnything = true;
14053            pw.println("  Processes that are on old until the system is ready:");
14054            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14055                    "OnHold Norm", "OnHold PERS", dumpPackage);
14056        }
14057
14058        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14059
14060        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14061        if (needSep) {
14062            printedAnything = true;
14063        }
14064
14065        if (dumpPackage == null) {
14066            pw.println();
14067            needSep = false;
14068            mUserController.dump(pw, dumpAll);
14069        }
14070        if (mHomeProcess != null && (dumpPackage == null
14071                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14072            if (needSep) {
14073                pw.println();
14074                needSep = false;
14075            }
14076            pw.println("  mHomeProcess: " + mHomeProcess);
14077        }
14078        if (mPreviousProcess != null && (dumpPackage == null
14079                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14080            if (needSep) {
14081                pw.println();
14082                needSep = false;
14083            }
14084            pw.println("  mPreviousProcess: " + mPreviousProcess);
14085        }
14086        if (dumpAll) {
14087            StringBuilder sb = new StringBuilder(128);
14088            sb.append("  mPreviousProcessVisibleTime: ");
14089            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14090            pw.println(sb);
14091        }
14092        if (mHeavyWeightProcess != null && (dumpPackage == null
14093                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14094            if (needSep) {
14095                pw.println();
14096                needSep = false;
14097            }
14098            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14099        }
14100        if (dumpPackage == null) {
14101            pw.println("  mConfiguration: " + mConfiguration);
14102        }
14103        if (dumpAll) {
14104            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14105            if (mCompatModePackages.getPackages().size() > 0) {
14106                boolean printed = false;
14107                for (Map.Entry<String, Integer> entry
14108                        : mCompatModePackages.getPackages().entrySet()) {
14109                    String pkg = entry.getKey();
14110                    int mode = entry.getValue();
14111                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14112                        continue;
14113                    }
14114                    if (!printed) {
14115                        pw.println("  mScreenCompatPackages:");
14116                        printed = true;
14117                    }
14118                    pw.print("    "); pw.print(pkg); pw.print(": ");
14119                            pw.print(mode); pw.println();
14120                }
14121            }
14122        }
14123        if (dumpPackage == null) {
14124            pw.println("  mWakefulness="
14125                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14126            pw.println("  mSleepTokens=" + mSleepTokens);
14127            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14128                    + lockScreenShownToString());
14129            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14130            if (mRunningVoice != null) {
14131                pw.println("  mRunningVoice=" + mRunningVoice);
14132                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14133            }
14134        }
14135        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14136                || mOrigWaitForDebugger) {
14137            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14138                    || dumpPackage.equals(mOrigDebugApp)) {
14139                if (needSep) {
14140                    pw.println();
14141                    needSep = false;
14142                }
14143                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14144                        + " mDebugTransient=" + mDebugTransient
14145                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14146            }
14147        }
14148        if (mCurAppTimeTracker != null) {
14149            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14150        }
14151        if (mMemWatchProcesses.getMap().size() > 0) {
14152            pw.println("  Mem watch processes:");
14153            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14154                    = mMemWatchProcesses.getMap();
14155            for (int i=0; i<procs.size(); i++) {
14156                final String proc = procs.keyAt(i);
14157                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14158                for (int j=0; j<uids.size(); j++) {
14159                    if (needSep) {
14160                        pw.println();
14161                        needSep = false;
14162                    }
14163                    StringBuilder sb = new StringBuilder();
14164                    sb.append("    ").append(proc).append('/');
14165                    UserHandle.formatUid(sb, uids.keyAt(j));
14166                    Pair<Long, String> val = uids.valueAt(j);
14167                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14168                    if (val.second != null) {
14169                        sb.append(", report to ").append(val.second);
14170                    }
14171                    pw.println(sb.toString());
14172                }
14173            }
14174            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14175            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14176            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14177                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14178        }
14179        if (mTrackAllocationApp != null) {
14180            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14181                if (needSep) {
14182                    pw.println();
14183                    needSep = false;
14184                }
14185                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14186            }
14187        }
14188        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14189                || mProfileFd != null) {
14190            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14191                if (needSep) {
14192                    pw.println();
14193                    needSep = false;
14194                }
14195                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14196                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14197                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14198                        + mAutoStopProfiler);
14199                pw.println("  mProfileType=" + mProfileType);
14200            }
14201        }
14202        if (mNativeDebuggingApp != null) {
14203            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14204                if (needSep) {
14205                    pw.println();
14206                    needSep = false;
14207                }
14208                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14209            }
14210        }
14211        if (dumpPackage == null) {
14212            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14213                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14214                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14215            }
14216            if (mController != null) {
14217                pw.println("  mController=" + mController
14218                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14219            }
14220            if (dumpAll) {
14221                pw.println("  Total persistent processes: " + numPers);
14222                pw.println("  mProcessesReady=" + mProcessesReady
14223                        + " mSystemReady=" + mSystemReady
14224                        + " mBooted=" + mBooted
14225                        + " mFactoryTest=" + mFactoryTest);
14226                pw.println("  mBooting=" + mBooting
14227                        + " mCallFinishBooting=" + mCallFinishBooting
14228                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14229                pw.print("  mLastPowerCheckRealtime=");
14230                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14231                        pw.println("");
14232                pw.print("  mLastPowerCheckUptime=");
14233                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14234                        pw.println("");
14235                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14236                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14237                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14238                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14239                        + " (" + mLruProcesses.size() + " total)"
14240                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14241                        + " mNumServiceProcs=" + mNumServiceProcs
14242                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14243                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14244                        + " mLastMemoryLevel" + mLastMemoryLevel
14245                        + " mLastNumProcesses" + mLastNumProcesses);
14246                long now = SystemClock.uptimeMillis();
14247                pw.print("  mLastIdleTime=");
14248                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14249                        pw.print(" mLowRamSinceLastIdle=");
14250                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14251                        pw.println();
14252            }
14253        }
14254
14255        if (!printedAnything) {
14256            pw.println("  (nothing)");
14257        }
14258    }
14259
14260    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14261            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14262        if (mProcessesToGc.size() > 0) {
14263            boolean printed = false;
14264            long now = SystemClock.uptimeMillis();
14265            for (int i=0; i<mProcessesToGc.size(); i++) {
14266                ProcessRecord proc = mProcessesToGc.get(i);
14267                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14268                    continue;
14269                }
14270                if (!printed) {
14271                    if (needSep) pw.println();
14272                    needSep = true;
14273                    pw.println("  Processes that are waiting to GC:");
14274                    printed = true;
14275                }
14276                pw.print("    Process "); pw.println(proc);
14277                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14278                        pw.print(", last gced=");
14279                        pw.print(now-proc.lastRequestedGc);
14280                        pw.print(" ms ago, last lowMem=");
14281                        pw.print(now-proc.lastLowMemory);
14282                        pw.println(" ms ago");
14283
14284            }
14285        }
14286        return needSep;
14287    }
14288
14289    void printOomLevel(PrintWriter pw, String name, int adj) {
14290        pw.print("    ");
14291        if (adj >= 0) {
14292            pw.print(' ');
14293            if (adj < 10) pw.print(' ');
14294        } else {
14295            if (adj > -10) pw.print(' ');
14296        }
14297        pw.print(adj);
14298        pw.print(": ");
14299        pw.print(name);
14300        pw.print(" (");
14301        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14302        pw.println(")");
14303    }
14304
14305    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14306            int opti, boolean dumpAll) {
14307        boolean needSep = false;
14308
14309        if (mLruProcesses.size() > 0) {
14310            if (needSep) pw.println();
14311            needSep = true;
14312            pw.println("  OOM levels:");
14313            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14314            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14315            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14316            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14317            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14318            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14319            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14320            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14321            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14322            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14323            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14324            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14325            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14326            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14327
14328            if (needSep) pw.println();
14329            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14330                    pw.print(" total, non-act at ");
14331                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14332                    pw.print(", non-svc at ");
14333                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14334                    pw.println("):");
14335            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14336            needSep = true;
14337        }
14338
14339        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14340
14341        pw.println();
14342        pw.println("  mHomeProcess: " + mHomeProcess);
14343        pw.println("  mPreviousProcess: " + mPreviousProcess);
14344        if (mHeavyWeightProcess != null) {
14345            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14346        }
14347
14348        return true;
14349    }
14350
14351    /**
14352     * There are three ways to call this:
14353     *  - no provider specified: dump all the providers
14354     *  - a flattened component name that matched an existing provider was specified as the
14355     *    first arg: dump that one provider
14356     *  - the first arg isn't the flattened component name of an existing provider:
14357     *    dump all providers whose component contains the first arg as a substring
14358     */
14359    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14360            int opti, boolean dumpAll) {
14361        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14362    }
14363
14364    static class ItemMatcher {
14365        ArrayList<ComponentName> components;
14366        ArrayList<String> strings;
14367        ArrayList<Integer> objects;
14368        boolean all;
14369
14370        ItemMatcher() {
14371            all = true;
14372        }
14373
14374        void build(String name) {
14375            ComponentName componentName = ComponentName.unflattenFromString(name);
14376            if (componentName != null) {
14377                if (components == null) {
14378                    components = new ArrayList<ComponentName>();
14379                }
14380                components.add(componentName);
14381                all = false;
14382            } else {
14383                int objectId = 0;
14384                // Not a '/' separated full component name; maybe an object ID?
14385                try {
14386                    objectId = Integer.parseInt(name, 16);
14387                    if (objects == null) {
14388                        objects = new ArrayList<Integer>();
14389                    }
14390                    objects.add(objectId);
14391                    all = false;
14392                } catch (RuntimeException e) {
14393                    // Not an integer; just do string match.
14394                    if (strings == null) {
14395                        strings = new ArrayList<String>();
14396                    }
14397                    strings.add(name);
14398                    all = false;
14399                }
14400            }
14401        }
14402
14403        int build(String[] args, int opti) {
14404            for (; opti<args.length; opti++) {
14405                String name = args[opti];
14406                if ("--".equals(name)) {
14407                    return opti+1;
14408                }
14409                build(name);
14410            }
14411            return opti;
14412        }
14413
14414        boolean match(Object object, ComponentName comp) {
14415            if (all) {
14416                return true;
14417            }
14418            if (components != null) {
14419                for (int i=0; i<components.size(); i++) {
14420                    if (components.get(i).equals(comp)) {
14421                        return true;
14422                    }
14423                }
14424            }
14425            if (objects != null) {
14426                for (int i=0; i<objects.size(); i++) {
14427                    if (System.identityHashCode(object) == objects.get(i)) {
14428                        return true;
14429                    }
14430                }
14431            }
14432            if (strings != null) {
14433                String flat = comp.flattenToString();
14434                for (int i=0; i<strings.size(); i++) {
14435                    if (flat.contains(strings.get(i))) {
14436                        return true;
14437                    }
14438                }
14439            }
14440            return false;
14441        }
14442    }
14443
14444    /**
14445     * There are three things that cmd can be:
14446     *  - a flattened component name that matches an existing activity
14447     *  - the cmd arg isn't the flattened component name of an existing activity:
14448     *    dump all activity whose component contains the cmd as a substring
14449     *  - A hex number of the ActivityRecord object instance.
14450     */
14451    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14452            int opti, boolean dumpAll) {
14453        ArrayList<ActivityRecord> activities;
14454
14455        synchronized (this) {
14456            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14457        }
14458
14459        if (activities.size() <= 0) {
14460            return false;
14461        }
14462
14463        String[] newArgs = new String[args.length - opti];
14464        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14465
14466        TaskRecord lastTask = null;
14467        boolean needSep = false;
14468        for (int i=activities.size()-1; i>=0; i--) {
14469            ActivityRecord r = activities.get(i);
14470            if (needSep) {
14471                pw.println();
14472            }
14473            needSep = true;
14474            synchronized (this) {
14475                if (lastTask != r.task) {
14476                    lastTask = r.task;
14477                    pw.print("TASK "); pw.print(lastTask.affinity);
14478                            pw.print(" id="); pw.println(lastTask.taskId);
14479                    if (dumpAll) {
14480                        lastTask.dump(pw, "  ");
14481                    }
14482                }
14483            }
14484            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14485        }
14486        return true;
14487    }
14488
14489    /**
14490     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14491     * there is a thread associated with the activity.
14492     */
14493    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14494            final ActivityRecord r, String[] args, boolean dumpAll) {
14495        String innerPrefix = prefix + "  ";
14496        synchronized (this) {
14497            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14498                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14499                    pw.print(" pid=");
14500                    if (r.app != null) pw.println(r.app.pid);
14501                    else pw.println("(not running)");
14502            if (dumpAll) {
14503                r.dump(pw, innerPrefix);
14504            }
14505        }
14506        if (r.app != null && r.app.thread != null) {
14507            // flush anything that is already in the PrintWriter since the thread is going
14508            // to write to the file descriptor directly
14509            pw.flush();
14510            try {
14511                TransferPipe tp = new TransferPipe();
14512                try {
14513                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14514                            r.appToken, innerPrefix, args);
14515                    tp.go(fd);
14516                } finally {
14517                    tp.kill();
14518                }
14519            } catch (IOException e) {
14520                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14521            } catch (RemoteException e) {
14522                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14523            }
14524        }
14525    }
14526
14527    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14528            int opti, boolean dumpAll, String dumpPackage) {
14529        boolean needSep = false;
14530        boolean onlyHistory = false;
14531        boolean printedAnything = false;
14532
14533        if ("history".equals(dumpPackage)) {
14534            if (opti < args.length && "-s".equals(args[opti])) {
14535                dumpAll = false;
14536            }
14537            onlyHistory = true;
14538            dumpPackage = null;
14539        }
14540
14541        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14542        if (!onlyHistory && dumpAll) {
14543            if (mRegisteredReceivers.size() > 0) {
14544                boolean printed = false;
14545                Iterator it = mRegisteredReceivers.values().iterator();
14546                while (it.hasNext()) {
14547                    ReceiverList r = (ReceiverList)it.next();
14548                    if (dumpPackage != null && (r.app == null ||
14549                            !dumpPackage.equals(r.app.info.packageName))) {
14550                        continue;
14551                    }
14552                    if (!printed) {
14553                        pw.println("  Registered Receivers:");
14554                        needSep = true;
14555                        printed = true;
14556                        printedAnything = true;
14557                    }
14558                    pw.print("  * "); pw.println(r);
14559                    r.dump(pw, "    ");
14560                }
14561            }
14562
14563            if (mReceiverResolver.dump(pw, needSep ?
14564                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14565                    "    ", dumpPackage, false, false)) {
14566                needSep = true;
14567                printedAnything = true;
14568            }
14569        }
14570
14571        for (BroadcastQueue q : mBroadcastQueues) {
14572            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14573            printedAnything |= needSep;
14574        }
14575
14576        needSep = true;
14577
14578        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14579            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14580                if (needSep) {
14581                    pw.println();
14582                }
14583                needSep = true;
14584                printedAnything = true;
14585                pw.print("  Sticky broadcasts for user ");
14586                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14587                StringBuilder sb = new StringBuilder(128);
14588                for (Map.Entry<String, ArrayList<Intent>> ent
14589                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14590                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14591                    if (dumpAll) {
14592                        pw.println(":");
14593                        ArrayList<Intent> intents = ent.getValue();
14594                        final int N = intents.size();
14595                        for (int i=0; i<N; i++) {
14596                            sb.setLength(0);
14597                            sb.append("    Intent: ");
14598                            intents.get(i).toShortString(sb, false, true, false, false);
14599                            pw.println(sb.toString());
14600                            Bundle bundle = intents.get(i).getExtras();
14601                            if (bundle != null) {
14602                                pw.print("      ");
14603                                pw.println(bundle.toString());
14604                            }
14605                        }
14606                    } else {
14607                        pw.println("");
14608                    }
14609                }
14610            }
14611        }
14612
14613        if (!onlyHistory && dumpAll) {
14614            pw.println();
14615            for (BroadcastQueue queue : mBroadcastQueues) {
14616                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14617                        + queue.mBroadcastsScheduled);
14618            }
14619            pw.println("  mHandler:");
14620            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14621            needSep = true;
14622            printedAnything = true;
14623        }
14624
14625        if (!printedAnything) {
14626            pw.println("  (nothing)");
14627        }
14628    }
14629
14630    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14631            int opti, boolean dumpAll, String dumpPackage) {
14632        boolean needSep;
14633        boolean printedAnything = false;
14634
14635        ItemMatcher matcher = new ItemMatcher();
14636        matcher.build(args, opti);
14637
14638        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14639
14640        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14641        printedAnything |= needSep;
14642
14643        if (mLaunchingProviders.size() > 0) {
14644            boolean printed = false;
14645            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14646                ContentProviderRecord r = mLaunchingProviders.get(i);
14647                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14648                    continue;
14649                }
14650                if (!printed) {
14651                    if (needSep) pw.println();
14652                    needSep = true;
14653                    pw.println("  Launching content providers:");
14654                    printed = true;
14655                    printedAnything = true;
14656                }
14657                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14658                        pw.println(r);
14659            }
14660        }
14661
14662        if (!printedAnything) {
14663            pw.println("  (nothing)");
14664        }
14665    }
14666
14667    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14668            int opti, boolean dumpAll, String dumpPackage) {
14669        boolean needSep = false;
14670        boolean printedAnything = false;
14671
14672        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14673
14674        if (mGrantedUriPermissions.size() > 0) {
14675            boolean printed = false;
14676            int dumpUid = -2;
14677            if (dumpPackage != null) {
14678                try {
14679                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14680                            MATCH_UNINSTALLED_PACKAGES, 0);
14681                } catch (NameNotFoundException e) {
14682                    dumpUid = -1;
14683                }
14684            }
14685            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14686                int uid = mGrantedUriPermissions.keyAt(i);
14687                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14688                    continue;
14689                }
14690                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14691                if (!printed) {
14692                    if (needSep) pw.println();
14693                    needSep = true;
14694                    pw.println("  Granted Uri Permissions:");
14695                    printed = true;
14696                    printedAnything = true;
14697                }
14698                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14699                for (UriPermission perm : perms.values()) {
14700                    pw.print("    "); pw.println(perm);
14701                    if (dumpAll) {
14702                        perm.dump(pw, "      ");
14703                    }
14704                }
14705            }
14706        }
14707
14708        if (!printedAnything) {
14709            pw.println("  (nothing)");
14710        }
14711    }
14712
14713    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14714            int opti, boolean dumpAll, String dumpPackage) {
14715        boolean printed = false;
14716
14717        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14718
14719        if (mIntentSenderRecords.size() > 0) {
14720            Iterator<WeakReference<PendingIntentRecord>> it
14721                    = mIntentSenderRecords.values().iterator();
14722            while (it.hasNext()) {
14723                WeakReference<PendingIntentRecord> ref = it.next();
14724                PendingIntentRecord rec = ref != null ? ref.get(): null;
14725                if (dumpPackage != null && (rec == null
14726                        || !dumpPackage.equals(rec.key.packageName))) {
14727                    continue;
14728                }
14729                printed = true;
14730                if (rec != null) {
14731                    pw.print("  * "); pw.println(rec);
14732                    if (dumpAll) {
14733                        rec.dump(pw, "    ");
14734                    }
14735                } else {
14736                    pw.print("  * "); pw.println(ref);
14737                }
14738            }
14739        }
14740
14741        if (!printed) {
14742            pw.println("  (nothing)");
14743        }
14744    }
14745
14746    private static final int dumpProcessList(PrintWriter pw,
14747            ActivityManagerService service, List list,
14748            String prefix, String normalLabel, String persistentLabel,
14749            String dumpPackage) {
14750        int numPers = 0;
14751        final int N = list.size()-1;
14752        for (int i=N; i>=0; i--) {
14753            ProcessRecord r = (ProcessRecord)list.get(i);
14754            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14755                continue;
14756            }
14757            pw.println(String.format("%s%s #%2d: %s",
14758                    prefix, (r.persistent ? persistentLabel : normalLabel),
14759                    i, r.toString()));
14760            if (r.persistent) {
14761                numPers++;
14762            }
14763        }
14764        return numPers;
14765    }
14766
14767    private static final boolean dumpProcessOomList(PrintWriter pw,
14768            ActivityManagerService service, List<ProcessRecord> origList,
14769            String prefix, String normalLabel, String persistentLabel,
14770            boolean inclDetails, String dumpPackage) {
14771
14772        ArrayList<Pair<ProcessRecord, Integer>> list
14773                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14774        for (int i=0; i<origList.size(); i++) {
14775            ProcessRecord r = origList.get(i);
14776            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14777                continue;
14778            }
14779            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14780        }
14781
14782        if (list.size() <= 0) {
14783            return false;
14784        }
14785
14786        Comparator<Pair<ProcessRecord, Integer>> comparator
14787                = new Comparator<Pair<ProcessRecord, Integer>>() {
14788            @Override
14789            public int compare(Pair<ProcessRecord, Integer> object1,
14790                    Pair<ProcessRecord, Integer> object2) {
14791                if (object1.first.setAdj != object2.first.setAdj) {
14792                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14793                }
14794                if (object1.first.setProcState != object2.first.setProcState) {
14795                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14796                }
14797                if (object1.second.intValue() != object2.second.intValue()) {
14798                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14799                }
14800                return 0;
14801            }
14802        };
14803
14804        Collections.sort(list, comparator);
14805
14806        final long curRealtime = SystemClock.elapsedRealtime();
14807        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14808        final long curUptime = SystemClock.uptimeMillis();
14809        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14810
14811        for (int i=list.size()-1; i>=0; i--) {
14812            ProcessRecord r = list.get(i).first;
14813            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14814            char schedGroup;
14815            switch (r.setSchedGroup) {
14816                case ProcessList.SCHED_GROUP_BACKGROUND:
14817                    schedGroup = 'B';
14818                    break;
14819                case ProcessList.SCHED_GROUP_DEFAULT:
14820                    schedGroup = 'F';
14821                    break;
14822                case ProcessList.SCHED_GROUP_TOP_APP:
14823                    schedGroup = 'T';
14824                    break;
14825                default:
14826                    schedGroup = '?';
14827                    break;
14828            }
14829            char foreground;
14830            if (r.foregroundActivities) {
14831                foreground = 'A';
14832            } else if (r.foregroundServices) {
14833                foreground = 'S';
14834            } else {
14835                foreground = ' ';
14836            }
14837            String procState = ProcessList.makeProcStateString(r.curProcState);
14838            pw.print(prefix);
14839            pw.print(r.persistent ? persistentLabel : normalLabel);
14840            pw.print(" #");
14841            int num = (origList.size()-1)-list.get(i).second;
14842            if (num < 10) pw.print(' ');
14843            pw.print(num);
14844            pw.print(": ");
14845            pw.print(oomAdj);
14846            pw.print(' ');
14847            pw.print(schedGroup);
14848            pw.print('/');
14849            pw.print(foreground);
14850            pw.print('/');
14851            pw.print(procState);
14852            pw.print(" trm:");
14853            if (r.trimMemoryLevel < 10) pw.print(' ');
14854            pw.print(r.trimMemoryLevel);
14855            pw.print(' ');
14856            pw.print(r.toShortString());
14857            pw.print(" (");
14858            pw.print(r.adjType);
14859            pw.println(')');
14860            if (r.adjSource != null || r.adjTarget != null) {
14861                pw.print(prefix);
14862                pw.print("    ");
14863                if (r.adjTarget instanceof ComponentName) {
14864                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14865                } else if (r.adjTarget != null) {
14866                    pw.print(r.adjTarget.toString());
14867                } else {
14868                    pw.print("{null}");
14869                }
14870                pw.print("<=");
14871                if (r.adjSource instanceof ProcessRecord) {
14872                    pw.print("Proc{");
14873                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14874                    pw.println("}");
14875                } else if (r.adjSource != null) {
14876                    pw.println(r.adjSource.toString());
14877                } else {
14878                    pw.println("{null}");
14879                }
14880            }
14881            if (inclDetails) {
14882                pw.print(prefix);
14883                pw.print("    ");
14884                pw.print("oom: max="); pw.print(r.maxAdj);
14885                pw.print(" curRaw="); pw.print(r.curRawAdj);
14886                pw.print(" setRaw="); pw.print(r.setRawAdj);
14887                pw.print(" cur="); pw.print(r.curAdj);
14888                pw.print(" set="); pw.println(r.setAdj);
14889                pw.print(prefix);
14890                pw.print("    ");
14891                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14892                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14893                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14894                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14895                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14896                pw.println();
14897                pw.print(prefix);
14898                pw.print("    ");
14899                pw.print("cached="); pw.print(r.cached);
14900                pw.print(" empty="); pw.print(r.empty);
14901                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14902
14903                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14904                    if (r.lastWakeTime != 0) {
14905                        long wtime;
14906                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14907                        synchronized (stats) {
14908                            wtime = stats.getProcessWakeTime(r.info.uid,
14909                                    r.pid, curRealtime);
14910                        }
14911                        long timeUsed = wtime - r.lastWakeTime;
14912                        pw.print(prefix);
14913                        pw.print("    ");
14914                        pw.print("keep awake over ");
14915                        TimeUtils.formatDuration(realtimeSince, pw);
14916                        pw.print(" used ");
14917                        TimeUtils.formatDuration(timeUsed, pw);
14918                        pw.print(" (");
14919                        pw.print((timeUsed*100)/realtimeSince);
14920                        pw.println("%)");
14921                    }
14922                    if (r.lastCpuTime != 0) {
14923                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14924                        pw.print(prefix);
14925                        pw.print("    ");
14926                        pw.print("run cpu over ");
14927                        TimeUtils.formatDuration(uptimeSince, pw);
14928                        pw.print(" used ");
14929                        TimeUtils.formatDuration(timeUsed, pw);
14930                        pw.print(" (");
14931                        pw.print((timeUsed*100)/uptimeSince);
14932                        pw.println("%)");
14933                    }
14934                }
14935            }
14936        }
14937        return true;
14938    }
14939
14940    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14941            String[] args) {
14942        ArrayList<ProcessRecord> procs;
14943        synchronized (this) {
14944            if (args != null && args.length > start
14945                    && args[start].charAt(0) != '-') {
14946                procs = new ArrayList<ProcessRecord>();
14947                int pid = -1;
14948                try {
14949                    pid = Integer.parseInt(args[start]);
14950                } catch (NumberFormatException e) {
14951                }
14952                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14953                    ProcessRecord proc = mLruProcesses.get(i);
14954                    if (proc.pid == pid) {
14955                        procs.add(proc);
14956                    } else if (allPkgs && proc.pkgList != null
14957                            && proc.pkgList.containsKey(args[start])) {
14958                        procs.add(proc);
14959                    } else if (proc.processName.equals(args[start])) {
14960                        procs.add(proc);
14961                    }
14962                }
14963                if (procs.size() <= 0) {
14964                    return null;
14965                }
14966            } else {
14967                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14968            }
14969        }
14970        return procs;
14971    }
14972
14973    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14974            PrintWriter pw, String[] args) {
14975        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14976        if (procs == null) {
14977            pw.println("No process found for: " + args[0]);
14978            return;
14979        }
14980
14981        long uptime = SystemClock.uptimeMillis();
14982        long realtime = SystemClock.elapsedRealtime();
14983        pw.println("Applications Graphics Acceleration Info:");
14984        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14985
14986        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14987            ProcessRecord r = procs.get(i);
14988            if (r.thread != null) {
14989                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14990                pw.flush();
14991                try {
14992                    TransferPipe tp = new TransferPipe();
14993                    try {
14994                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14995                        tp.go(fd);
14996                    } finally {
14997                        tp.kill();
14998                    }
14999                } catch (IOException e) {
15000                    pw.println("Failure while dumping the app: " + r);
15001                    pw.flush();
15002                } catch (RemoteException e) {
15003                    pw.println("Got a RemoteException while dumping the app " + r);
15004                    pw.flush();
15005                }
15006            }
15007        }
15008    }
15009
15010    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15011        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15012        if (procs == null) {
15013            pw.println("No process found for: " + args[0]);
15014            return;
15015        }
15016
15017        pw.println("Applications Database Info:");
15018
15019        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15020            ProcessRecord r = procs.get(i);
15021            if (r.thread != null) {
15022                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15023                pw.flush();
15024                try {
15025                    TransferPipe tp = new TransferPipe();
15026                    try {
15027                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15028                        tp.go(fd);
15029                    } finally {
15030                        tp.kill();
15031                    }
15032                } catch (IOException e) {
15033                    pw.println("Failure while dumping the app: " + r);
15034                    pw.flush();
15035                } catch (RemoteException e) {
15036                    pw.println("Got a RemoteException while dumping the app " + r);
15037                    pw.flush();
15038                }
15039            }
15040        }
15041    }
15042
15043    final static class MemItem {
15044        final boolean isProc;
15045        final String label;
15046        final String shortLabel;
15047        final long pss;
15048        final long swapPss;
15049        final int id;
15050        final boolean hasActivities;
15051        ArrayList<MemItem> subitems;
15052
15053        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15054                boolean _hasActivities) {
15055            isProc = true;
15056            label = _label;
15057            shortLabel = _shortLabel;
15058            pss = _pss;
15059            swapPss = _swapPss;
15060            id = _id;
15061            hasActivities = _hasActivities;
15062        }
15063
15064        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15065            isProc = false;
15066            label = _label;
15067            shortLabel = _shortLabel;
15068            pss = _pss;
15069            swapPss = _swapPss;
15070            id = _id;
15071            hasActivities = false;
15072        }
15073    }
15074
15075    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15076            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15077        if (sort && !isCompact) {
15078            Collections.sort(items, new Comparator<MemItem>() {
15079                @Override
15080                public int compare(MemItem lhs, MemItem rhs) {
15081                    if (lhs.pss < rhs.pss) {
15082                        return 1;
15083                    } else if (lhs.pss > rhs.pss) {
15084                        return -1;
15085                    }
15086                    return 0;
15087                }
15088            });
15089        }
15090
15091        for (int i=0; i<items.size(); i++) {
15092            MemItem mi = items.get(i);
15093            if (!isCompact) {
15094                if (dumpSwapPss) {
15095                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15096                            mi.label, stringifyKBSize(mi.swapPss));
15097                } else {
15098                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15099                }
15100            } else if (mi.isProc) {
15101                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15102                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15103                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15104                pw.println(mi.hasActivities ? ",a" : ",e");
15105            } else {
15106                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15107                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15108            }
15109            if (mi.subitems != null) {
15110                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15111                        true, isCompact, dumpSwapPss);
15112            }
15113        }
15114    }
15115
15116    // These are in KB.
15117    static final long[] DUMP_MEM_BUCKETS = new long[] {
15118        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15119        120*1024, 160*1024, 200*1024,
15120        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15121        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15122    };
15123
15124    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15125            boolean stackLike) {
15126        int start = label.lastIndexOf('.');
15127        if (start >= 0) start++;
15128        else start = 0;
15129        int end = label.length();
15130        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15131            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15132                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15133                out.append(bucket);
15134                out.append(stackLike ? "MB." : "MB ");
15135                out.append(label, start, end);
15136                return;
15137            }
15138        }
15139        out.append(memKB/1024);
15140        out.append(stackLike ? "MB." : "MB ");
15141        out.append(label, start, end);
15142    }
15143
15144    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15145            ProcessList.NATIVE_ADJ,
15146            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15147            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15148            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15149            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15150            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15151            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15152    };
15153    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15154            "Native",
15155            "System", "Persistent", "Persistent Service", "Foreground",
15156            "Visible", "Perceptible",
15157            "Heavy Weight", "Backup",
15158            "A Services", "Home",
15159            "Previous", "B Services", "Cached"
15160    };
15161    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15162            "native",
15163            "sys", "pers", "persvc", "fore",
15164            "vis", "percept",
15165            "heavy", "backup",
15166            "servicea", "home",
15167            "prev", "serviceb", "cached"
15168    };
15169
15170    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15171            long realtime, boolean isCheckinRequest, boolean isCompact) {
15172        if (isCompact) {
15173            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15174        }
15175        if (isCheckinRequest || isCompact) {
15176            // short checkin version
15177            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15178        } else {
15179            pw.println("Applications Memory Usage (in Kilobytes):");
15180            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15181        }
15182    }
15183
15184    private static final int KSM_SHARED = 0;
15185    private static final int KSM_SHARING = 1;
15186    private static final int KSM_UNSHARED = 2;
15187    private static final int KSM_VOLATILE = 3;
15188
15189    private final long[] getKsmInfo() {
15190        long[] longOut = new long[4];
15191        final int[] SINGLE_LONG_FORMAT = new int[] {
15192            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15193        };
15194        long[] longTmp = new long[1];
15195        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15196                SINGLE_LONG_FORMAT, null, longTmp, null);
15197        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15198        longTmp[0] = 0;
15199        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15200                SINGLE_LONG_FORMAT, null, longTmp, null);
15201        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15202        longTmp[0] = 0;
15203        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15204                SINGLE_LONG_FORMAT, null, longTmp, null);
15205        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15206        longTmp[0] = 0;
15207        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15208                SINGLE_LONG_FORMAT, null, longTmp, null);
15209        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15210        return longOut;
15211    }
15212
15213    private static String stringifySize(long size, int order) {
15214        Locale locale = Locale.US;
15215        switch (order) {
15216            case 1:
15217                return String.format(locale, "%,13d", size);
15218            case 1024:
15219                return String.format(locale, "%,9dK", size / 1024);
15220            case 1024 * 1024:
15221                return String.format(locale, "%,5dM", size / 1024 / 1024);
15222            case 1024 * 1024 * 1024:
15223                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15224            default:
15225                throw new IllegalArgumentException("Invalid size order");
15226        }
15227    }
15228
15229    private static String stringifyKBSize(long size) {
15230        return stringifySize(size * 1024, 1024);
15231    }
15232
15233    // Update this version number in case you change the 'compact' format
15234    private static final int MEMINFO_COMPACT_VERSION = 1;
15235
15236    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15237            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15238        boolean dumpDetails = false;
15239        boolean dumpFullDetails = false;
15240        boolean dumpDalvik = false;
15241        boolean dumpSummaryOnly = false;
15242        boolean dumpUnreachable = false;
15243        boolean oomOnly = false;
15244        boolean isCompact = false;
15245        boolean localOnly = false;
15246        boolean packages = false;
15247        boolean isCheckinRequest = false;
15248        boolean dumpSwapPss = false;
15249
15250        int opti = 0;
15251        while (opti < args.length) {
15252            String opt = args[opti];
15253            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15254                break;
15255            }
15256            opti++;
15257            if ("-a".equals(opt)) {
15258                dumpDetails = true;
15259                dumpFullDetails = true;
15260                dumpDalvik = true;
15261                dumpSwapPss = true;
15262            } else if ("-d".equals(opt)) {
15263                dumpDalvik = true;
15264            } else if ("-c".equals(opt)) {
15265                isCompact = true;
15266            } else if ("-s".equals(opt)) {
15267                dumpDetails = true;
15268                dumpSummaryOnly = true;
15269            } else if ("-S".equals(opt)) {
15270                dumpSwapPss = true;
15271            } else if ("--unreachable".equals(opt)) {
15272                dumpUnreachable = true;
15273            } else if ("--oom".equals(opt)) {
15274                oomOnly = true;
15275            } else if ("--local".equals(opt)) {
15276                localOnly = true;
15277            } else if ("--package".equals(opt)) {
15278                packages = true;
15279            } else if ("--checkin".equals(opt)) {
15280                isCheckinRequest = true;
15281
15282            } else if ("-h".equals(opt)) {
15283                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15284                pw.println("  -a: include all available information for each process.");
15285                pw.println("  -d: include dalvik details.");
15286                pw.println("  -c: dump in a compact machine-parseable representation.");
15287                pw.println("  -s: dump only summary of application memory usage.");
15288                pw.println("  -S: dump also SwapPss.");
15289                pw.println("  --oom: only show processes organized by oom adj.");
15290                pw.println("  --local: only collect details locally, don't call process.");
15291                pw.println("  --package: interpret process arg as package, dumping all");
15292                pw.println("             processes that have loaded that package.");
15293                pw.println("  --checkin: dump data for a checkin");
15294                pw.println("If [process] is specified it can be the name or ");
15295                pw.println("pid of a specific process to dump.");
15296                return;
15297            } else {
15298                pw.println("Unknown argument: " + opt + "; use -h for help");
15299            }
15300        }
15301
15302        long uptime = SystemClock.uptimeMillis();
15303        long realtime = SystemClock.elapsedRealtime();
15304        final long[] tmpLong = new long[1];
15305
15306        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15307        if (procs == null) {
15308            // No Java processes.  Maybe they want to print a native process.
15309            if (args != null && args.length > opti
15310                    && args[opti].charAt(0) != '-') {
15311                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15312                        = new ArrayList<ProcessCpuTracker.Stats>();
15313                updateCpuStatsNow();
15314                int findPid = -1;
15315                try {
15316                    findPid = Integer.parseInt(args[opti]);
15317                } catch (NumberFormatException e) {
15318                }
15319                synchronized (mProcessCpuTracker) {
15320                    final int N = mProcessCpuTracker.countStats();
15321                    for (int i=0; i<N; i++) {
15322                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15323                        if (st.pid == findPid || (st.baseName != null
15324                                && st.baseName.equals(args[opti]))) {
15325                            nativeProcs.add(st);
15326                        }
15327                    }
15328                }
15329                if (nativeProcs.size() > 0) {
15330                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15331                            isCompact);
15332                    Debug.MemoryInfo mi = null;
15333                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15334                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15335                        final int pid = r.pid;
15336                        if (!isCheckinRequest && dumpDetails) {
15337                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15338                        }
15339                        if (mi == null) {
15340                            mi = new Debug.MemoryInfo();
15341                        }
15342                        if (dumpDetails || (!brief && !oomOnly)) {
15343                            Debug.getMemoryInfo(pid, mi);
15344                        } else {
15345                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15346                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15347                        }
15348                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15349                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15350                        if (isCheckinRequest) {
15351                            pw.println();
15352                        }
15353                    }
15354                    return;
15355                }
15356            }
15357            pw.println("No process found for: " + args[opti]);
15358            return;
15359        }
15360
15361        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15362            dumpDetails = true;
15363        }
15364
15365        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15366
15367        String[] innerArgs = new String[args.length-opti];
15368        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15369
15370        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15371        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15372        long nativePss = 0;
15373        long nativeSwapPss = 0;
15374        long dalvikPss = 0;
15375        long dalvikSwapPss = 0;
15376        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15377                EmptyArray.LONG;
15378        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15379                EmptyArray.LONG;
15380        long otherPss = 0;
15381        long otherSwapPss = 0;
15382        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15383        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15384
15385        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15386        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15387        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15388                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15389
15390        long totalPss = 0;
15391        long totalSwapPss = 0;
15392        long cachedPss = 0;
15393        long cachedSwapPss = 0;
15394        boolean hasSwapPss = false;
15395
15396        Debug.MemoryInfo mi = null;
15397        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15398            final ProcessRecord r = procs.get(i);
15399            final IApplicationThread thread;
15400            final int pid;
15401            final int oomAdj;
15402            final boolean hasActivities;
15403            synchronized (this) {
15404                thread = r.thread;
15405                pid = r.pid;
15406                oomAdj = r.getSetAdjWithServices();
15407                hasActivities = r.activities.size() > 0;
15408            }
15409            if (thread != null) {
15410                if (!isCheckinRequest && dumpDetails) {
15411                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15412                }
15413                if (mi == null) {
15414                    mi = new Debug.MemoryInfo();
15415                }
15416                if (dumpDetails || (!brief && !oomOnly)) {
15417                    Debug.getMemoryInfo(pid, mi);
15418                    hasSwapPss = mi.hasSwappedOutPss;
15419                } else {
15420                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15421                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15422                }
15423                if (dumpDetails) {
15424                    if (localOnly) {
15425                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15426                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15427                        if (isCheckinRequest) {
15428                            pw.println();
15429                        }
15430                    } else {
15431                        try {
15432                            pw.flush();
15433                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15434                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15435                        } catch (RemoteException e) {
15436                            if (!isCheckinRequest) {
15437                                pw.println("Got RemoteException!");
15438                                pw.flush();
15439                            }
15440                        }
15441                    }
15442                }
15443
15444                final long myTotalPss = mi.getTotalPss();
15445                final long myTotalUss = mi.getTotalUss();
15446                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15447
15448                synchronized (this) {
15449                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15450                        // Record this for posterity if the process has been stable.
15451                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15452                    }
15453                }
15454
15455                if (!isCheckinRequest && mi != null) {
15456                    totalPss += myTotalPss;
15457                    totalSwapPss += myTotalSwapPss;
15458                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15459                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15460                            myTotalSwapPss, pid, hasActivities);
15461                    procMems.add(pssItem);
15462                    procMemsMap.put(pid, pssItem);
15463
15464                    nativePss += mi.nativePss;
15465                    nativeSwapPss += mi.nativeSwappedOutPss;
15466                    dalvikPss += mi.dalvikPss;
15467                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15468                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15469                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15470                        dalvikSubitemSwapPss[j] +=
15471                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15472                    }
15473                    otherPss += mi.otherPss;
15474                    otherSwapPss += mi.otherSwappedOutPss;
15475                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15476                        long mem = mi.getOtherPss(j);
15477                        miscPss[j] += mem;
15478                        otherPss -= mem;
15479                        mem = mi.getOtherSwappedOutPss(j);
15480                        miscSwapPss[j] += mem;
15481                        otherSwapPss -= mem;
15482                    }
15483
15484                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15485                        cachedPss += myTotalPss;
15486                        cachedSwapPss += myTotalSwapPss;
15487                    }
15488
15489                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15490                        if (oomIndex == (oomPss.length - 1)
15491                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15492                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15493                            oomPss[oomIndex] += myTotalPss;
15494                            oomSwapPss[oomIndex] += myTotalSwapPss;
15495                            if (oomProcs[oomIndex] == null) {
15496                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15497                            }
15498                            oomProcs[oomIndex].add(pssItem);
15499                            break;
15500                        }
15501                    }
15502                }
15503            }
15504        }
15505
15506        long nativeProcTotalPss = 0;
15507
15508        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15509            // If we are showing aggregations, also look for native processes to
15510            // include so that our aggregations are more accurate.
15511            updateCpuStatsNow();
15512            mi = null;
15513            synchronized (mProcessCpuTracker) {
15514                final int N = mProcessCpuTracker.countStats();
15515                for (int i=0; i<N; i++) {
15516                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15517                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15518                        if (mi == null) {
15519                            mi = new Debug.MemoryInfo();
15520                        }
15521                        if (!brief && !oomOnly) {
15522                            Debug.getMemoryInfo(st.pid, mi);
15523                        } else {
15524                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15525                            mi.nativePrivateDirty = (int)tmpLong[0];
15526                        }
15527
15528                        final long myTotalPss = mi.getTotalPss();
15529                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15530                        totalPss += myTotalPss;
15531                        nativeProcTotalPss += myTotalPss;
15532
15533                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15534                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15535                        procMems.add(pssItem);
15536
15537                        nativePss += mi.nativePss;
15538                        nativeSwapPss += mi.nativeSwappedOutPss;
15539                        dalvikPss += mi.dalvikPss;
15540                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15541                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15542                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15543                            dalvikSubitemSwapPss[j] +=
15544                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15545                        }
15546                        otherPss += mi.otherPss;
15547                        otherSwapPss += mi.otherSwappedOutPss;
15548                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15549                            long mem = mi.getOtherPss(j);
15550                            miscPss[j] += mem;
15551                            otherPss -= mem;
15552                            mem = mi.getOtherSwappedOutPss(j);
15553                            miscSwapPss[j] += mem;
15554                            otherSwapPss -= mem;
15555                        }
15556                        oomPss[0] += myTotalPss;
15557                        oomSwapPss[0] += myTotalSwapPss;
15558                        if (oomProcs[0] == null) {
15559                            oomProcs[0] = new ArrayList<MemItem>();
15560                        }
15561                        oomProcs[0].add(pssItem);
15562                    }
15563                }
15564            }
15565
15566            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15567
15568            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15569            final MemItem dalvikItem =
15570                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15571            if (dalvikSubitemPss.length > 0) {
15572                dalvikItem.subitems = new ArrayList<MemItem>();
15573                for (int j=0; j<dalvikSubitemPss.length; j++) {
15574                    final String name = Debug.MemoryInfo.getOtherLabel(
15575                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15576                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15577                                    dalvikSubitemSwapPss[j], j));
15578                }
15579            }
15580            catMems.add(dalvikItem);
15581            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15582            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15583                String label = Debug.MemoryInfo.getOtherLabel(j);
15584                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15585            }
15586
15587            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15588            for (int j=0; j<oomPss.length; j++) {
15589                if (oomPss[j] != 0) {
15590                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15591                            : DUMP_MEM_OOM_LABEL[j];
15592                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15593                            DUMP_MEM_OOM_ADJ[j]);
15594                    item.subitems = oomProcs[j];
15595                    oomMems.add(item);
15596                }
15597            }
15598
15599            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15600            if (!brief && !oomOnly && !isCompact) {
15601                pw.println();
15602                pw.println("Total PSS by process:");
15603                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15604                pw.println();
15605            }
15606            if (!isCompact) {
15607                pw.println("Total PSS by OOM adjustment:");
15608            }
15609            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15610            if (!brief && !oomOnly) {
15611                PrintWriter out = categoryPw != null ? categoryPw : pw;
15612                if (!isCompact) {
15613                    out.println();
15614                    out.println("Total PSS by category:");
15615                }
15616                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15617            }
15618            if (!isCompact) {
15619                pw.println();
15620            }
15621            MemInfoReader memInfo = new MemInfoReader();
15622            memInfo.readMemInfo();
15623            if (nativeProcTotalPss > 0) {
15624                synchronized (this) {
15625                    final long cachedKb = memInfo.getCachedSizeKb();
15626                    final long freeKb = memInfo.getFreeSizeKb();
15627                    final long zramKb = memInfo.getZramTotalSizeKb();
15628                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15629                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15630                            kernelKb*1024, nativeProcTotalPss*1024);
15631                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15632                            nativeProcTotalPss);
15633                }
15634            }
15635            if (!brief) {
15636                if (!isCompact) {
15637                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15638                    pw.print(" (status ");
15639                    switch (mLastMemoryLevel) {
15640                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15641                            pw.println("normal)");
15642                            break;
15643                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15644                            pw.println("moderate)");
15645                            break;
15646                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15647                            pw.println("low)");
15648                            break;
15649                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15650                            pw.println("critical)");
15651                            break;
15652                        default:
15653                            pw.print(mLastMemoryLevel);
15654                            pw.println(")");
15655                            break;
15656                    }
15657                    pw.print(" Free RAM: ");
15658                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15659                            + memInfo.getFreeSizeKb()));
15660                    pw.print(" (");
15661                    pw.print(stringifyKBSize(cachedPss));
15662                    pw.print(" cached pss + ");
15663                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15664                    pw.print(" cached kernel + ");
15665                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15666                    pw.println(" free)");
15667                } else {
15668                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15669                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15670                            + memInfo.getFreeSizeKb()); pw.print(",");
15671                    pw.println(totalPss - cachedPss);
15672                }
15673            }
15674            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15675                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15676                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15677            if (!isCompact) {
15678                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15679                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15680                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15681                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15682                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15683            } else {
15684                pw.print("lostram,"); pw.println(lostRAM);
15685            }
15686            if (!brief) {
15687                if (memInfo.getZramTotalSizeKb() != 0) {
15688                    if (!isCompact) {
15689                        pw.print("     ZRAM: ");
15690                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15691                                pw.print(" physical used for ");
15692                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15693                                        - memInfo.getSwapFreeSizeKb()));
15694                                pw.print(" in swap (");
15695                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15696                                pw.println(" total swap)");
15697                    } else {
15698                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15699                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15700                                pw.println(memInfo.getSwapFreeSizeKb());
15701                    }
15702                }
15703                final long[] ksm = getKsmInfo();
15704                if (!isCompact) {
15705                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15706                            || ksm[KSM_VOLATILE] != 0) {
15707                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15708                                pw.print(" saved from shared ");
15709                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15710                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15711                                pw.print(" unshared; ");
15712                                pw.print(stringifyKBSize(
15713                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15714                    }
15715                    pw.print("   Tuning: ");
15716                    pw.print(ActivityManager.staticGetMemoryClass());
15717                    pw.print(" (large ");
15718                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15719                    pw.print("), oom ");
15720                    pw.print(stringifySize(
15721                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15722                    pw.print(", restore limit ");
15723                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15724                    if (ActivityManager.isLowRamDeviceStatic()) {
15725                        pw.print(" (low-ram)");
15726                    }
15727                    if (ActivityManager.isHighEndGfx()) {
15728                        pw.print(" (high-end-gfx)");
15729                    }
15730                    pw.println();
15731                } else {
15732                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15733                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15734                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15735                    pw.print("tuning,");
15736                    pw.print(ActivityManager.staticGetMemoryClass());
15737                    pw.print(',');
15738                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15739                    pw.print(',');
15740                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15741                    if (ActivityManager.isLowRamDeviceStatic()) {
15742                        pw.print(",low-ram");
15743                    }
15744                    if (ActivityManager.isHighEndGfx()) {
15745                        pw.print(",high-end-gfx");
15746                    }
15747                    pw.println();
15748                }
15749            }
15750        }
15751    }
15752
15753    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15754            long memtrack, String name) {
15755        sb.append("  ");
15756        sb.append(ProcessList.makeOomAdjString(oomAdj));
15757        sb.append(' ');
15758        sb.append(ProcessList.makeProcStateString(procState));
15759        sb.append(' ');
15760        ProcessList.appendRamKb(sb, pss);
15761        sb.append(": ");
15762        sb.append(name);
15763        if (memtrack > 0) {
15764            sb.append(" (");
15765            sb.append(stringifyKBSize(memtrack));
15766            sb.append(" memtrack)");
15767        }
15768    }
15769
15770    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15771        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15772        sb.append(" (pid ");
15773        sb.append(mi.pid);
15774        sb.append(") ");
15775        sb.append(mi.adjType);
15776        sb.append('\n');
15777        if (mi.adjReason != null) {
15778            sb.append("                      ");
15779            sb.append(mi.adjReason);
15780            sb.append('\n');
15781        }
15782    }
15783
15784    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15785        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15786        for (int i=0, N=memInfos.size(); i<N; i++) {
15787            ProcessMemInfo mi = memInfos.get(i);
15788            infoMap.put(mi.pid, mi);
15789        }
15790        updateCpuStatsNow();
15791        long[] memtrackTmp = new long[1];
15792        synchronized (mProcessCpuTracker) {
15793            final int N = mProcessCpuTracker.countStats();
15794            for (int i=0; i<N; i++) {
15795                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15796                if (st.vsize > 0) {
15797                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15798                    if (pss > 0) {
15799                        if (infoMap.indexOfKey(st.pid) < 0) {
15800                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15801                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15802                            mi.pss = pss;
15803                            mi.memtrack = memtrackTmp[0];
15804                            memInfos.add(mi);
15805                        }
15806                    }
15807                }
15808            }
15809        }
15810
15811        long totalPss = 0;
15812        long totalMemtrack = 0;
15813        for (int i=0, N=memInfos.size(); i<N; i++) {
15814            ProcessMemInfo mi = memInfos.get(i);
15815            if (mi.pss == 0) {
15816                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15817                mi.memtrack = memtrackTmp[0];
15818            }
15819            totalPss += mi.pss;
15820            totalMemtrack += mi.memtrack;
15821        }
15822        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15823            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15824                if (lhs.oomAdj != rhs.oomAdj) {
15825                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15826                }
15827                if (lhs.pss != rhs.pss) {
15828                    return lhs.pss < rhs.pss ? 1 : -1;
15829                }
15830                return 0;
15831            }
15832        });
15833
15834        StringBuilder tag = new StringBuilder(128);
15835        StringBuilder stack = new StringBuilder(128);
15836        tag.append("Low on memory -- ");
15837        appendMemBucket(tag, totalPss, "total", false);
15838        appendMemBucket(stack, totalPss, "total", true);
15839
15840        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15841        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15842        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15843
15844        boolean firstLine = true;
15845        int lastOomAdj = Integer.MIN_VALUE;
15846        long extraNativeRam = 0;
15847        long extraNativeMemtrack = 0;
15848        long cachedPss = 0;
15849        for (int i=0, N=memInfos.size(); i<N; i++) {
15850            ProcessMemInfo mi = memInfos.get(i);
15851
15852            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15853                cachedPss += mi.pss;
15854            }
15855
15856            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15857                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15858                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15859                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15860                if (lastOomAdj != mi.oomAdj) {
15861                    lastOomAdj = mi.oomAdj;
15862                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15863                        tag.append(" / ");
15864                    }
15865                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15866                        if (firstLine) {
15867                            stack.append(":");
15868                            firstLine = false;
15869                        }
15870                        stack.append("\n\t at ");
15871                    } else {
15872                        stack.append("$");
15873                    }
15874                } else {
15875                    tag.append(" ");
15876                    stack.append("$");
15877                }
15878                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15879                    appendMemBucket(tag, mi.pss, mi.name, false);
15880                }
15881                appendMemBucket(stack, mi.pss, mi.name, true);
15882                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15883                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15884                    stack.append("(");
15885                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15886                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15887                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15888                            stack.append(":");
15889                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15890                        }
15891                    }
15892                    stack.append(")");
15893                }
15894            }
15895
15896            appendMemInfo(fullNativeBuilder, mi);
15897            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15898                // The short form only has native processes that are >= 512K.
15899                if (mi.pss >= 512) {
15900                    appendMemInfo(shortNativeBuilder, mi);
15901                } else {
15902                    extraNativeRam += mi.pss;
15903                    extraNativeMemtrack += mi.memtrack;
15904                }
15905            } else {
15906                // Short form has all other details, but if we have collected RAM
15907                // from smaller native processes let's dump a summary of that.
15908                if (extraNativeRam > 0) {
15909                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15910                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15911                    shortNativeBuilder.append('\n');
15912                    extraNativeRam = 0;
15913                }
15914                appendMemInfo(fullJavaBuilder, mi);
15915            }
15916        }
15917
15918        fullJavaBuilder.append("           ");
15919        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15920        fullJavaBuilder.append(": TOTAL");
15921        if (totalMemtrack > 0) {
15922            fullJavaBuilder.append(" (");
15923            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15924            fullJavaBuilder.append(" memtrack)");
15925        } else {
15926        }
15927        fullJavaBuilder.append("\n");
15928
15929        MemInfoReader memInfo = new MemInfoReader();
15930        memInfo.readMemInfo();
15931        final long[] infos = memInfo.getRawInfo();
15932
15933        StringBuilder memInfoBuilder = new StringBuilder(1024);
15934        Debug.getMemInfo(infos);
15935        memInfoBuilder.append("  MemInfo: ");
15936        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15937        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15938        memInfoBuilder.append(stringifyKBSize(
15939                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15940        memInfoBuilder.append(stringifyKBSize(
15941                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15942        memInfoBuilder.append(stringifyKBSize(
15943                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15944        memInfoBuilder.append("           ");
15945        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15946        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15947        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15948        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15949        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15950            memInfoBuilder.append("  ZRAM: ");
15951            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15952            memInfoBuilder.append(" RAM, ");
15953            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15954            memInfoBuilder.append(" swap total, ");
15955            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15956            memInfoBuilder.append(" swap free\n");
15957        }
15958        final long[] ksm = getKsmInfo();
15959        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15960                || ksm[KSM_VOLATILE] != 0) {
15961            memInfoBuilder.append("  KSM: ");
15962            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15963            memInfoBuilder.append(" saved from shared ");
15964            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15965            memInfoBuilder.append("\n       ");
15966            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15967            memInfoBuilder.append(" unshared; ");
15968            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15969            memInfoBuilder.append(" volatile\n");
15970        }
15971        memInfoBuilder.append("  Free RAM: ");
15972        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15973                + memInfo.getFreeSizeKb()));
15974        memInfoBuilder.append("\n");
15975        memInfoBuilder.append("  Used RAM: ");
15976        memInfoBuilder.append(stringifyKBSize(
15977                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15978        memInfoBuilder.append("\n");
15979        memInfoBuilder.append("  Lost RAM: ");
15980        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15981                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15982                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
15983        memInfoBuilder.append("\n");
15984        Slog.i(TAG, "Low on memory:");
15985        Slog.i(TAG, shortNativeBuilder.toString());
15986        Slog.i(TAG, fullJavaBuilder.toString());
15987        Slog.i(TAG, memInfoBuilder.toString());
15988
15989        StringBuilder dropBuilder = new StringBuilder(1024);
15990        /*
15991        StringWriter oomSw = new StringWriter();
15992        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15993        StringWriter catSw = new StringWriter();
15994        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15995        String[] emptyArgs = new String[] { };
15996        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15997        oomPw.flush();
15998        String oomString = oomSw.toString();
15999        */
16000        dropBuilder.append("Low on memory:");
16001        dropBuilder.append(stack);
16002        dropBuilder.append('\n');
16003        dropBuilder.append(fullNativeBuilder);
16004        dropBuilder.append(fullJavaBuilder);
16005        dropBuilder.append('\n');
16006        dropBuilder.append(memInfoBuilder);
16007        dropBuilder.append('\n');
16008        /*
16009        dropBuilder.append(oomString);
16010        dropBuilder.append('\n');
16011        */
16012        StringWriter catSw = new StringWriter();
16013        synchronized (ActivityManagerService.this) {
16014            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16015            String[] emptyArgs = new String[] { };
16016            catPw.println();
16017            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16018            catPw.println();
16019            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16020                    false, false, null);
16021            catPw.println();
16022            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16023            catPw.flush();
16024        }
16025        dropBuilder.append(catSw.toString());
16026        addErrorToDropBox("lowmem", null, "system_server", null,
16027                null, tag.toString(), dropBuilder.toString(), null, null);
16028        //Slog.i(TAG, "Sent to dropbox:");
16029        //Slog.i(TAG, dropBuilder.toString());
16030        synchronized (ActivityManagerService.this) {
16031            long now = SystemClock.uptimeMillis();
16032            if (mLastMemUsageReportTime < now) {
16033                mLastMemUsageReportTime = now;
16034            }
16035        }
16036    }
16037
16038    /**
16039     * Searches array of arguments for the specified string
16040     * @param args array of argument strings
16041     * @param value value to search for
16042     * @return true if the value is contained in the array
16043     */
16044    private static boolean scanArgs(String[] args, String value) {
16045        if (args != null) {
16046            for (String arg : args) {
16047                if (value.equals(arg)) {
16048                    return true;
16049                }
16050            }
16051        }
16052        return false;
16053    }
16054
16055    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16056            ContentProviderRecord cpr, boolean always) {
16057        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16058
16059        if (!inLaunching || always) {
16060            synchronized (cpr) {
16061                cpr.launchingApp = null;
16062                cpr.notifyAll();
16063            }
16064            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16065            String names[] = cpr.info.authority.split(";");
16066            for (int j = 0; j < names.length; j++) {
16067                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16068            }
16069        }
16070
16071        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16072            ContentProviderConnection conn = cpr.connections.get(i);
16073            if (conn.waiting) {
16074                // If this connection is waiting for the provider, then we don't
16075                // need to mess with its process unless we are always removing
16076                // or for some reason the provider is not currently launching.
16077                if (inLaunching && !always) {
16078                    continue;
16079                }
16080            }
16081            ProcessRecord capp = conn.client;
16082            conn.dead = true;
16083            if (conn.stableCount > 0) {
16084                if (!capp.persistent && capp.thread != null
16085                        && capp.pid != 0
16086                        && capp.pid != MY_PID) {
16087                    capp.kill("depends on provider "
16088                            + cpr.name.flattenToShortString()
16089                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16090                }
16091            } else if (capp.thread != null && conn.provider.provider != null) {
16092                try {
16093                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16094                } catch (RemoteException e) {
16095                }
16096                // In the protocol here, we don't expect the client to correctly
16097                // clean up this connection, we'll just remove it.
16098                cpr.connections.remove(i);
16099                if (conn.client.conProviders.remove(conn)) {
16100                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16101                }
16102            }
16103        }
16104
16105        if (inLaunching && always) {
16106            mLaunchingProviders.remove(cpr);
16107        }
16108        return inLaunching;
16109    }
16110
16111    /**
16112     * Main code for cleaning up a process when it has gone away.  This is
16113     * called both as a result of the process dying, or directly when stopping
16114     * a process when running in single process mode.
16115     *
16116     * @return Returns true if the given process has been restarted, so the
16117     * app that was passed in must remain on the process lists.
16118     */
16119    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16120            boolean restarting, boolean allowRestart, int index) {
16121        if (index >= 0) {
16122            removeLruProcessLocked(app);
16123            ProcessList.remove(app.pid);
16124        }
16125
16126        mProcessesToGc.remove(app);
16127        mPendingPssProcesses.remove(app);
16128
16129        // Dismiss any open dialogs.
16130        if (app.crashDialog != null && !app.forceCrashReport) {
16131            app.crashDialog.dismiss();
16132            app.crashDialog = null;
16133        }
16134        if (app.anrDialog != null) {
16135            app.anrDialog.dismiss();
16136            app.anrDialog = null;
16137        }
16138        if (app.waitDialog != null) {
16139            app.waitDialog.dismiss();
16140            app.waitDialog = null;
16141        }
16142
16143        app.crashing = false;
16144        app.notResponding = false;
16145
16146        app.resetPackageList(mProcessStats);
16147        app.unlinkDeathRecipient();
16148        app.makeInactive(mProcessStats);
16149        app.waitingToKill = null;
16150        app.forcingToForeground = null;
16151        updateProcessForegroundLocked(app, false, false);
16152        app.foregroundActivities = false;
16153        app.hasShownUi = false;
16154        app.treatLikeActivity = false;
16155        app.hasAboveClient = false;
16156        app.hasClientActivities = false;
16157
16158        mServices.killServicesLocked(app, allowRestart);
16159
16160        boolean restart = false;
16161
16162        // Remove published content providers.
16163        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16164            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16165            final boolean always = app.bad || !allowRestart;
16166            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16167            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16168                // We left the provider in the launching list, need to
16169                // restart it.
16170                restart = true;
16171            }
16172
16173            cpr.provider = null;
16174            cpr.proc = null;
16175        }
16176        app.pubProviders.clear();
16177
16178        // Take care of any launching providers waiting for this process.
16179        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16180            restart = true;
16181        }
16182
16183        // Unregister from connected content providers.
16184        if (!app.conProviders.isEmpty()) {
16185            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16186                ContentProviderConnection conn = app.conProviders.get(i);
16187                conn.provider.connections.remove(conn);
16188                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16189                        conn.provider.name);
16190            }
16191            app.conProviders.clear();
16192        }
16193
16194        // At this point there may be remaining entries in mLaunchingProviders
16195        // where we were the only one waiting, so they are no longer of use.
16196        // Look for these and clean up if found.
16197        // XXX Commented out for now.  Trying to figure out a way to reproduce
16198        // the actual situation to identify what is actually going on.
16199        if (false) {
16200            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16201                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16202                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16203                    synchronized (cpr) {
16204                        cpr.launchingApp = null;
16205                        cpr.notifyAll();
16206                    }
16207                }
16208            }
16209        }
16210
16211        skipCurrentReceiverLocked(app);
16212
16213        // Unregister any receivers.
16214        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16215            removeReceiverLocked(app.receivers.valueAt(i));
16216        }
16217        app.receivers.clear();
16218
16219        // If the app is undergoing backup, tell the backup manager about it
16220        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16221            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16222                    + mBackupTarget.appInfo + " died during backup");
16223            try {
16224                IBackupManager bm = IBackupManager.Stub.asInterface(
16225                        ServiceManager.getService(Context.BACKUP_SERVICE));
16226                bm.agentDisconnected(app.info.packageName);
16227            } catch (RemoteException e) {
16228                // can't happen; backup manager is local
16229            }
16230        }
16231
16232        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16233            ProcessChangeItem item = mPendingProcessChanges.get(i);
16234            if (item.pid == app.pid) {
16235                mPendingProcessChanges.remove(i);
16236                mAvailProcessChanges.add(item);
16237            }
16238        }
16239        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16240                null).sendToTarget();
16241
16242        // If the caller is restarting this app, then leave it in its
16243        // current lists and let the caller take care of it.
16244        if (restarting) {
16245            return false;
16246        }
16247
16248        if (!app.persistent || app.isolated) {
16249            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16250                    "Removing non-persistent process during cleanup: " + app);
16251            removeProcessNameLocked(app.processName, app.uid);
16252            if (mHeavyWeightProcess == app) {
16253                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16254                        mHeavyWeightProcess.userId, 0));
16255                mHeavyWeightProcess = null;
16256            }
16257        } else if (!app.removed) {
16258            // This app is persistent, so we need to keep its record around.
16259            // If it is not already on the pending app list, add it there
16260            // and start a new process for it.
16261            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16262                mPersistentStartingProcesses.add(app);
16263                restart = true;
16264            }
16265        }
16266        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16267                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16268        mProcessesOnHold.remove(app);
16269
16270        if (app == mHomeProcess) {
16271            mHomeProcess = null;
16272        }
16273        if (app == mPreviousProcess) {
16274            mPreviousProcess = null;
16275        }
16276
16277        if (restart && !app.isolated) {
16278            // We have components that still need to be running in the
16279            // process, so re-launch it.
16280            if (index < 0) {
16281                ProcessList.remove(app.pid);
16282            }
16283            addProcessNameLocked(app);
16284            startProcessLocked(app, "restart", app.processName);
16285            return true;
16286        } else if (app.pid > 0 && app.pid != MY_PID) {
16287            // Goodbye!
16288            boolean removed;
16289            synchronized (mPidsSelfLocked) {
16290                mPidsSelfLocked.remove(app.pid);
16291                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16292            }
16293            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16294            if (app.isolated) {
16295                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16296            }
16297            app.setPid(0);
16298        }
16299        return false;
16300    }
16301
16302    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16303        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16304            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16305            if (cpr.launchingApp == app) {
16306                return true;
16307            }
16308        }
16309        return false;
16310    }
16311
16312    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16313        // Look through the content providers we are waiting to have launched,
16314        // and if any run in this process then either schedule a restart of
16315        // the process or kill the client waiting for it if this process has
16316        // gone bad.
16317        boolean restart = false;
16318        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16319            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16320            if (cpr.launchingApp == app) {
16321                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16322                    restart = true;
16323                } else {
16324                    removeDyingProviderLocked(app, cpr, true);
16325                }
16326            }
16327        }
16328        return restart;
16329    }
16330
16331    // =========================================================
16332    // SERVICES
16333    // =========================================================
16334
16335    @Override
16336    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16337            int flags) {
16338        enforceNotIsolatedCaller("getServices");
16339        synchronized (this) {
16340            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16341        }
16342    }
16343
16344    @Override
16345    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16346        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16347        synchronized (this) {
16348            return mServices.getRunningServiceControlPanelLocked(name);
16349        }
16350    }
16351
16352    @Override
16353    public ComponentName startService(IApplicationThread caller, Intent service,
16354            String resolvedType, String callingPackage, int userId)
16355            throws TransactionTooLargeException {
16356        enforceNotIsolatedCaller("startService");
16357        // Refuse possible leaked file descriptors
16358        if (service != null && service.hasFileDescriptors() == true) {
16359            throw new IllegalArgumentException("File descriptors passed in Intent");
16360        }
16361
16362        if (callingPackage == null) {
16363            throw new IllegalArgumentException("callingPackage cannot be null");
16364        }
16365
16366        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16367                "startService: " + service + " type=" + resolvedType);
16368        synchronized(this) {
16369            final int callingPid = Binder.getCallingPid();
16370            final int callingUid = Binder.getCallingUid();
16371            final long origId = Binder.clearCallingIdentity();
16372            ComponentName res = mServices.startServiceLocked(caller, service,
16373                    resolvedType, callingPid, callingUid, callingPackage, userId);
16374            Binder.restoreCallingIdentity(origId);
16375            return res;
16376        }
16377    }
16378
16379    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16380            String callingPackage, int userId)
16381            throws TransactionTooLargeException {
16382        synchronized(this) {
16383            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16384                    "startServiceInPackage: " + service + " type=" + resolvedType);
16385            final long origId = Binder.clearCallingIdentity();
16386            ComponentName res = mServices.startServiceLocked(null, service,
16387                    resolvedType, -1, uid, callingPackage, userId);
16388            Binder.restoreCallingIdentity(origId);
16389            return res;
16390        }
16391    }
16392
16393    @Override
16394    public int stopService(IApplicationThread caller, Intent service,
16395            String resolvedType, int userId) {
16396        enforceNotIsolatedCaller("stopService");
16397        // Refuse possible leaked file descriptors
16398        if (service != null && service.hasFileDescriptors() == true) {
16399            throw new IllegalArgumentException("File descriptors passed in Intent");
16400        }
16401
16402        synchronized(this) {
16403            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16404        }
16405    }
16406
16407    @Override
16408    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16409        enforceNotIsolatedCaller("peekService");
16410        // Refuse possible leaked file descriptors
16411        if (service != null && service.hasFileDescriptors() == true) {
16412            throw new IllegalArgumentException("File descriptors passed in Intent");
16413        }
16414
16415        if (callingPackage == null) {
16416            throw new IllegalArgumentException("callingPackage cannot be null");
16417        }
16418
16419        synchronized(this) {
16420            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16421        }
16422    }
16423
16424    @Override
16425    public boolean stopServiceToken(ComponentName className, IBinder token,
16426            int startId) {
16427        synchronized(this) {
16428            return mServices.stopServiceTokenLocked(className, token, startId);
16429        }
16430    }
16431
16432    @Override
16433    public void setServiceForeground(ComponentName className, IBinder token,
16434            int id, Notification notification, boolean removeNotification) {
16435        synchronized(this) {
16436            mServices.setServiceForegroundLocked(className, token, id, notification,
16437                    removeNotification);
16438        }
16439    }
16440
16441    @Override
16442    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16443            boolean requireFull, String name, String callerPackage) {
16444        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16445                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16446    }
16447
16448    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16449            String className, int flags) {
16450        boolean result = false;
16451        // For apps that don't have pre-defined UIDs, check for permission
16452        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16453            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16454                if (ActivityManager.checkUidPermission(
16455                        INTERACT_ACROSS_USERS,
16456                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16457                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16458                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16459                            + " requests FLAG_SINGLE_USER, but app does not hold "
16460                            + INTERACT_ACROSS_USERS;
16461                    Slog.w(TAG, msg);
16462                    throw new SecurityException(msg);
16463                }
16464                // Permission passed
16465                result = true;
16466            }
16467        } else if ("system".equals(componentProcessName)) {
16468            result = true;
16469        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16470            // Phone app and persistent apps are allowed to export singleuser providers.
16471            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16472                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16473        }
16474        if (DEBUG_MU) Slog.v(TAG_MU,
16475                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16476                + Integer.toHexString(flags) + ") = " + result);
16477        return result;
16478    }
16479
16480    /**
16481     * Checks to see if the caller is in the same app as the singleton
16482     * component, or the component is in a special app. It allows special apps
16483     * to export singleton components but prevents exporting singleton
16484     * components for regular apps.
16485     */
16486    boolean isValidSingletonCall(int callingUid, int componentUid) {
16487        int componentAppId = UserHandle.getAppId(componentUid);
16488        return UserHandle.isSameApp(callingUid, componentUid)
16489                || componentAppId == Process.SYSTEM_UID
16490                || componentAppId == Process.PHONE_UID
16491                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16492                        == PackageManager.PERMISSION_GRANTED;
16493    }
16494
16495    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16496            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16497            int userId) throws TransactionTooLargeException {
16498        enforceNotIsolatedCaller("bindService");
16499
16500        // Refuse possible leaked file descriptors
16501        if (service != null && service.hasFileDescriptors() == true) {
16502            throw new IllegalArgumentException("File descriptors passed in Intent");
16503        }
16504
16505        if (callingPackage == null) {
16506            throw new IllegalArgumentException("callingPackage cannot be null");
16507        }
16508
16509        synchronized(this) {
16510            return mServices.bindServiceLocked(caller, token, service,
16511                    resolvedType, connection, flags, callingPackage, userId);
16512        }
16513    }
16514
16515    public boolean unbindService(IServiceConnection connection) {
16516        synchronized (this) {
16517            return mServices.unbindServiceLocked(connection);
16518        }
16519    }
16520
16521    public void publishService(IBinder token, Intent intent, IBinder service) {
16522        // Refuse possible leaked file descriptors
16523        if (intent != null && intent.hasFileDescriptors() == true) {
16524            throw new IllegalArgumentException("File descriptors passed in Intent");
16525        }
16526
16527        synchronized(this) {
16528            if (!(token instanceof ServiceRecord)) {
16529                throw new IllegalArgumentException("Invalid service token");
16530            }
16531            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16532        }
16533    }
16534
16535    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16536        // Refuse possible leaked file descriptors
16537        if (intent != null && intent.hasFileDescriptors() == true) {
16538            throw new IllegalArgumentException("File descriptors passed in Intent");
16539        }
16540
16541        synchronized(this) {
16542            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16543        }
16544    }
16545
16546    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16547        synchronized(this) {
16548            if (!(token instanceof ServiceRecord)) {
16549                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16550                throw new IllegalArgumentException("Invalid service token");
16551            }
16552            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16553        }
16554    }
16555
16556    // =========================================================
16557    // BACKUP AND RESTORE
16558    // =========================================================
16559
16560    // Cause the target app to be launched if necessary and its backup agent
16561    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16562    // activity manager to announce its creation.
16563    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16564        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16565                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16566        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16567
16568        synchronized(this) {
16569            // !!! TODO: currently no check here that we're already bound
16570            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16571            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16572            synchronized (stats) {
16573                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16574            }
16575
16576            // Backup agent is now in use, its package can't be stopped.
16577            try {
16578                AppGlobals.getPackageManager().setPackageStoppedState(
16579                        app.packageName, false, UserHandle.getUserId(app.uid));
16580            } catch (RemoteException e) {
16581            } catch (IllegalArgumentException e) {
16582                Slog.w(TAG, "Failed trying to unstop package "
16583                        + app.packageName + ": " + e);
16584            }
16585
16586            BackupRecord r = new BackupRecord(ss, app, backupMode);
16587            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16588                    ? new ComponentName(app.packageName, app.backupAgentName)
16589                    : new ComponentName("android", "FullBackupAgent");
16590            // startProcessLocked() returns existing proc's record if it's already running
16591            ProcessRecord proc = startProcessLocked(app.processName, app,
16592                    false, 0, "backup", hostingName, false, false, false);
16593            if (proc == null) {
16594                Slog.e(TAG, "Unable to start backup agent process " + r);
16595                return false;
16596            }
16597
16598            r.app = proc;
16599            mBackupTarget = r;
16600            mBackupAppName = app.packageName;
16601
16602            // Try not to kill the process during backup
16603            updateOomAdjLocked(proc);
16604
16605            // If the process is already attached, schedule the creation of the backup agent now.
16606            // If it is not yet live, this will be done when it attaches to the framework.
16607            if (proc.thread != null) {
16608                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16609                try {
16610                    proc.thread.scheduleCreateBackupAgent(app,
16611                            compatibilityInfoForPackageLocked(app), backupMode);
16612                } catch (RemoteException e) {
16613                    // Will time out on the backup manager side
16614                }
16615            } else {
16616                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16617            }
16618            // Invariants: at this point, the target app process exists and the application
16619            // is either already running or in the process of coming up.  mBackupTarget and
16620            // mBackupAppName describe the app, so that when it binds back to the AM we
16621            // know that it's scheduled for a backup-agent operation.
16622        }
16623
16624        return true;
16625    }
16626
16627    @Override
16628    public void clearPendingBackup() {
16629        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16630        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16631
16632        synchronized (this) {
16633            mBackupTarget = null;
16634            mBackupAppName = null;
16635        }
16636    }
16637
16638    // A backup agent has just come up
16639    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16640        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16641                + " = " + agent);
16642
16643        synchronized(this) {
16644            if (!agentPackageName.equals(mBackupAppName)) {
16645                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16646                return;
16647            }
16648        }
16649
16650        long oldIdent = Binder.clearCallingIdentity();
16651        try {
16652            IBackupManager bm = IBackupManager.Stub.asInterface(
16653                    ServiceManager.getService(Context.BACKUP_SERVICE));
16654            bm.agentConnected(agentPackageName, agent);
16655        } catch (RemoteException e) {
16656            // can't happen; the backup manager service is local
16657        } catch (Exception e) {
16658            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16659            e.printStackTrace();
16660        } finally {
16661            Binder.restoreCallingIdentity(oldIdent);
16662        }
16663    }
16664
16665    // done with this agent
16666    public void unbindBackupAgent(ApplicationInfo appInfo) {
16667        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16668        if (appInfo == null) {
16669            Slog.w(TAG, "unbind backup agent for null app");
16670            return;
16671        }
16672
16673        synchronized(this) {
16674            try {
16675                if (mBackupAppName == null) {
16676                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16677                    return;
16678                }
16679
16680                if (!mBackupAppName.equals(appInfo.packageName)) {
16681                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16682                    return;
16683                }
16684
16685                // Not backing this app up any more; reset its OOM adjustment
16686                final ProcessRecord proc = mBackupTarget.app;
16687                updateOomAdjLocked(proc);
16688
16689                // If the app crashed during backup, 'thread' will be null here
16690                if (proc.thread != null) {
16691                    try {
16692                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16693                                compatibilityInfoForPackageLocked(appInfo));
16694                    } catch (Exception e) {
16695                        Slog.e(TAG, "Exception when unbinding backup agent:");
16696                        e.printStackTrace();
16697                    }
16698                }
16699            } finally {
16700                mBackupTarget = null;
16701                mBackupAppName = null;
16702            }
16703        }
16704    }
16705    // =========================================================
16706    // BROADCASTS
16707    // =========================================================
16708
16709    boolean isPendingBroadcastProcessLocked(int pid) {
16710        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16711                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16712    }
16713
16714    void skipPendingBroadcastLocked(int pid) {
16715            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16716            for (BroadcastQueue queue : mBroadcastQueues) {
16717                queue.skipPendingBroadcastLocked(pid);
16718            }
16719    }
16720
16721    // The app just attached; send any pending broadcasts that it should receive
16722    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16723        boolean didSomething = false;
16724        for (BroadcastQueue queue : mBroadcastQueues) {
16725            didSomething |= queue.sendPendingBroadcastsLocked(app);
16726        }
16727        return didSomething;
16728    }
16729
16730    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16731            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16732        enforceNotIsolatedCaller("registerReceiver");
16733        ArrayList<Intent> stickyIntents = null;
16734        ProcessRecord callerApp = null;
16735        int callingUid;
16736        int callingPid;
16737        synchronized(this) {
16738            if (caller != null) {
16739                callerApp = getRecordForAppLocked(caller);
16740                if (callerApp == null) {
16741                    throw new SecurityException(
16742                            "Unable to find app for caller " + caller
16743                            + " (pid=" + Binder.getCallingPid()
16744                            + ") when registering receiver " + receiver);
16745                }
16746                if (callerApp.info.uid != Process.SYSTEM_UID &&
16747                        !callerApp.pkgList.containsKey(callerPackage) &&
16748                        !"android".equals(callerPackage)) {
16749                    throw new SecurityException("Given caller package " + callerPackage
16750                            + " is not running in process " + callerApp);
16751                }
16752                callingUid = callerApp.info.uid;
16753                callingPid = callerApp.pid;
16754            } else {
16755                callerPackage = null;
16756                callingUid = Binder.getCallingUid();
16757                callingPid = Binder.getCallingPid();
16758            }
16759
16760            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16761                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16762
16763            Iterator<String> actions = filter.actionsIterator();
16764            if (actions == null) {
16765                ArrayList<String> noAction = new ArrayList<String>(1);
16766                noAction.add(null);
16767                actions = noAction.iterator();
16768            }
16769
16770            // Collect stickies of users
16771            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16772            while (actions.hasNext()) {
16773                String action = actions.next();
16774                for (int id : userIds) {
16775                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16776                    if (stickies != null) {
16777                        ArrayList<Intent> intents = stickies.get(action);
16778                        if (intents != null) {
16779                            if (stickyIntents == null) {
16780                                stickyIntents = new ArrayList<Intent>();
16781                            }
16782                            stickyIntents.addAll(intents);
16783                        }
16784                    }
16785                }
16786            }
16787        }
16788
16789        ArrayList<Intent> allSticky = null;
16790        if (stickyIntents != null) {
16791            final ContentResolver resolver = mContext.getContentResolver();
16792            // Look for any matching sticky broadcasts...
16793            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16794                Intent intent = stickyIntents.get(i);
16795                // If intent has scheme "content", it will need to acccess
16796                // provider that needs to lock mProviderMap in ActivityThread
16797                // and also it may need to wait application response, so we
16798                // cannot lock ActivityManagerService here.
16799                if (filter.match(resolver, intent, true, TAG) >= 0) {
16800                    if (allSticky == null) {
16801                        allSticky = new ArrayList<Intent>();
16802                    }
16803                    allSticky.add(intent);
16804                }
16805            }
16806        }
16807
16808        // The first sticky in the list is returned directly back to the client.
16809        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16810        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16811        if (receiver == null) {
16812            return sticky;
16813        }
16814
16815        synchronized (this) {
16816            if (callerApp != null && (callerApp.thread == null
16817                    || callerApp.thread.asBinder() != caller.asBinder())) {
16818                // Original caller already died
16819                return null;
16820            }
16821            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16822            if (rl == null) {
16823                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16824                        userId, receiver);
16825                if (rl.app != null) {
16826                    rl.app.receivers.add(rl);
16827                } else {
16828                    try {
16829                        receiver.asBinder().linkToDeath(rl, 0);
16830                    } catch (RemoteException e) {
16831                        return sticky;
16832                    }
16833                    rl.linkedToDeath = true;
16834                }
16835                mRegisteredReceivers.put(receiver.asBinder(), rl);
16836            } else if (rl.uid != callingUid) {
16837                throw new IllegalArgumentException(
16838                        "Receiver requested to register for uid " + callingUid
16839                        + " was previously registered for uid " + rl.uid);
16840            } else if (rl.pid != callingPid) {
16841                throw new IllegalArgumentException(
16842                        "Receiver requested to register for pid " + callingPid
16843                        + " was previously registered for pid " + rl.pid);
16844            } else if (rl.userId != userId) {
16845                throw new IllegalArgumentException(
16846                        "Receiver requested to register for user " + userId
16847                        + " was previously registered for user " + rl.userId);
16848            }
16849            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16850                    permission, callingUid, userId);
16851            rl.add(bf);
16852            if (!bf.debugCheck()) {
16853                Slog.w(TAG, "==> For Dynamic broadcast");
16854            }
16855            mReceiverResolver.addFilter(bf);
16856
16857            // Enqueue broadcasts for all existing stickies that match
16858            // this filter.
16859            if (allSticky != null) {
16860                ArrayList receivers = new ArrayList();
16861                receivers.add(bf);
16862
16863                final int stickyCount = allSticky.size();
16864                for (int i = 0; i < stickyCount; i++) {
16865                    Intent intent = allSticky.get(i);
16866                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16867                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16868                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16869                            null, 0, null, null, false, true, true, -1);
16870                    queue.enqueueParallelBroadcastLocked(r);
16871                    queue.scheduleBroadcastsLocked();
16872                }
16873            }
16874
16875            return sticky;
16876        }
16877    }
16878
16879    public void unregisterReceiver(IIntentReceiver receiver) {
16880        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16881
16882        final long origId = Binder.clearCallingIdentity();
16883        try {
16884            boolean doTrim = false;
16885
16886            synchronized(this) {
16887                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16888                if (rl != null) {
16889                    final BroadcastRecord r = rl.curBroadcast;
16890                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16891                        final boolean doNext = r.queue.finishReceiverLocked(
16892                                r, r.resultCode, r.resultData, r.resultExtras,
16893                                r.resultAbort, false);
16894                        if (doNext) {
16895                            doTrim = true;
16896                            r.queue.processNextBroadcast(false);
16897                        }
16898                    }
16899
16900                    if (rl.app != null) {
16901                        rl.app.receivers.remove(rl);
16902                    }
16903                    removeReceiverLocked(rl);
16904                    if (rl.linkedToDeath) {
16905                        rl.linkedToDeath = false;
16906                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16907                    }
16908                }
16909            }
16910
16911            // If we actually concluded any broadcasts, we might now be able
16912            // to trim the recipients' apps from our working set
16913            if (doTrim) {
16914                trimApplications();
16915                return;
16916            }
16917
16918        } finally {
16919            Binder.restoreCallingIdentity(origId);
16920        }
16921    }
16922
16923    void removeReceiverLocked(ReceiverList rl) {
16924        mRegisteredReceivers.remove(rl.receiver.asBinder());
16925        for (int i = rl.size() - 1; i >= 0; i--) {
16926            mReceiverResolver.removeFilter(rl.get(i));
16927        }
16928    }
16929
16930    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16931        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16932            ProcessRecord r = mLruProcesses.get(i);
16933            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16934                try {
16935                    r.thread.dispatchPackageBroadcast(cmd, packages);
16936                } catch (RemoteException ex) {
16937                }
16938            }
16939        }
16940    }
16941
16942    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16943            int callingUid, int[] users) {
16944        // TODO: come back and remove this assumption to triage all broadcasts
16945        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16946
16947        List<ResolveInfo> receivers = null;
16948        try {
16949            HashSet<ComponentName> singleUserReceivers = null;
16950            boolean scannedFirstReceivers = false;
16951            for (int user : users) {
16952                // Skip users that have Shell restrictions, with exception of always permitted
16953                // Shell broadcasts
16954                if (callingUid == Process.SHELL_UID
16955                        && mUserController.hasUserRestriction(
16956                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
16957                        && !isPermittedShellBroadcast(intent)) {
16958                    continue;
16959                }
16960                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16961                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
16962                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16963                    // If this is not the system user, we need to check for
16964                    // any receivers that should be filtered out.
16965                    for (int i=0; i<newReceivers.size(); i++) {
16966                        ResolveInfo ri = newReceivers.get(i);
16967                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16968                            newReceivers.remove(i);
16969                            i--;
16970                        }
16971                    }
16972                }
16973                if (newReceivers != null && newReceivers.size() == 0) {
16974                    newReceivers = null;
16975                }
16976                if (receivers == null) {
16977                    receivers = newReceivers;
16978                } else if (newReceivers != null) {
16979                    // We need to concatenate the additional receivers
16980                    // found with what we have do far.  This would be easy,
16981                    // but we also need to de-dup any receivers that are
16982                    // singleUser.
16983                    if (!scannedFirstReceivers) {
16984                        // Collect any single user receivers we had already retrieved.
16985                        scannedFirstReceivers = true;
16986                        for (int i=0; i<receivers.size(); i++) {
16987                            ResolveInfo ri = receivers.get(i);
16988                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16989                                ComponentName cn = new ComponentName(
16990                                        ri.activityInfo.packageName, ri.activityInfo.name);
16991                                if (singleUserReceivers == null) {
16992                                    singleUserReceivers = new HashSet<ComponentName>();
16993                                }
16994                                singleUserReceivers.add(cn);
16995                            }
16996                        }
16997                    }
16998                    // Add the new results to the existing results, tracking
16999                    // and de-dupping single user receivers.
17000                    for (int i=0; i<newReceivers.size(); i++) {
17001                        ResolveInfo ri = newReceivers.get(i);
17002                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17003                            ComponentName cn = new ComponentName(
17004                                    ri.activityInfo.packageName, ri.activityInfo.name);
17005                            if (singleUserReceivers == null) {
17006                                singleUserReceivers = new HashSet<ComponentName>();
17007                            }
17008                            if (!singleUserReceivers.contains(cn)) {
17009                                singleUserReceivers.add(cn);
17010                                receivers.add(ri);
17011                            }
17012                        } else {
17013                            receivers.add(ri);
17014                        }
17015                    }
17016                }
17017            }
17018        } catch (RemoteException ex) {
17019            // pm is in same process, this will never happen.
17020        }
17021        return receivers;
17022    }
17023
17024    private boolean isPermittedShellBroadcast(Intent intent) {
17025        // remote bugreport should always be allowed to be taken
17026        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17027    }
17028
17029    final int broadcastIntentLocked(ProcessRecord callerApp,
17030            String callerPackage, Intent intent, String resolvedType,
17031            IIntentReceiver resultTo, int resultCode, String resultData,
17032            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17033            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17034        intent = new Intent(intent);
17035
17036        // By default broadcasts do not go to stopped apps.
17037        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17038
17039        // If we have not finished booting, don't allow this to launch new processes.
17040        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17041            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17042        }
17043
17044        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17045                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17046                + " ordered=" + ordered + " userid=" + userId);
17047        if ((resultTo != null) && !ordered) {
17048            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17049        }
17050
17051        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17052                ALLOW_NON_FULL, "broadcast", callerPackage);
17053
17054        // Make sure that the user who is receiving this broadcast is running.
17055        // If not, we will just skip it. Make an exception for shutdown broadcasts
17056        // and upgrade steps.
17057
17058        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17059            if ((callingUid != Process.SYSTEM_UID
17060                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17061                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17062                Slog.w(TAG, "Skipping broadcast of " + intent
17063                        + ": user " + userId + " is stopped");
17064                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17065            }
17066        }
17067
17068        BroadcastOptions brOptions = null;
17069        if (bOptions != null) {
17070            brOptions = new BroadcastOptions(bOptions);
17071            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17072                // See if the caller is allowed to do this.  Note we are checking against
17073                // the actual real caller (not whoever provided the operation as say a
17074                // PendingIntent), because that who is actually supplied the arguments.
17075                if (checkComponentPermission(
17076                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17077                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17078                        != PackageManager.PERMISSION_GRANTED) {
17079                    String msg = "Permission Denial: " + intent.getAction()
17080                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17081                            + ", uid=" + callingUid + ")"
17082                            + " requires "
17083                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17084                    Slog.w(TAG, msg);
17085                    throw new SecurityException(msg);
17086                }
17087            }
17088        }
17089
17090        // Verify that protected broadcasts are only being sent by system code,
17091        // and that system code is only sending protected broadcasts.
17092        final String action = intent.getAction();
17093        final boolean isProtectedBroadcast;
17094        try {
17095            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17096        } catch (RemoteException e) {
17097            Slog.w(TAG, "Remote exception", e);
17098            return ActivityManager.BROADCAST_SUCCESS;
17099        }
17100
17101        final boolean isCallerSystem;
17102        switch (UserHandle.getAppId(callingUid)) {
17103            case Process.ROOT_UID:
17104            case Process.SYSTEM_UID:
17105            case Process.PHONE_UID:
17106            case Process.BLUETOOTH_UID:
17107            case Process.NFC_UID:
17108                isCallerSystem = true;
17109                break;
17110            default:
17111                isCallerSystem = (callerApp != null) && callerApp.persistent;
17112                break;
17113        }
17114
17115        if (isCallerSystem) {
17116            if (isProtectedBroadcast
17117                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17118                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17119                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17120                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17121                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17122                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17123                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17124                // Broadcast is either protected, or it's a public action that
17125                // we've relaxed, so it's fine for system internals to send.
17126            } else {
17127                // The vast majority of broadcasts sent from system internals
17128                // should be protected to avoid security holes, so yell loudly
17129                // to ensure we examine these cases.
17130                Log.wtf(TAG, "Sending non-protected broadcast " + action
17131                        + " from system", new Throwable());
17132            }
17133
17134        } else {
17135            if (isProtectedBroadcast) {
17136                String msg = "Permission Denial: not allowed to send broadcast "
17137                        + action + " from pid="
17138                        + callingPid + ", uid=" + callingUid;
17139                Slog.w(TAG, msg);
17140                throw new SecurityException(msg);
17141
17142            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17143                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17144                // Special case for compatibility: we don't want apps to send this,
17145                // but historically it has not been protected and apps may be using it
17146                // to poke their own app widget.  So, instead of making it protected,
17147                // just limit it to the caller.
17148                if (callerPackage == null) {
17149                    String msg = "Permission Denial: not allowed to send broadcast "
17150                            + action + " from unknown caller.";
17151                    Slog.w(TAG, msg);
17152                    throw new SecurityException(msg);
17153                } else if (intent.getComponent() != null) {
17154                    // They are good enough to send to an explicit component...  verify
17155                    // it is being sent to the calling app.
17156                    if (!intent.getComponent().getPackageName().equals(
17157                            callerPackage)) {
17158                        String msg = "Permission Denial: not allowed to send broadcast "
17159                                + action + " to "
17160                                + intent.getComponent().getPackageName() + " from "
17161                                + callerPackage;
17162                        Slog.w(TAG, msg);
17163                        throw new SecurityException(msg);
17164                    }
17165                } else {
17166                    // Limit broadcast to their own package.
17167                    intent.setPackage(callerPackage);
17168                }
17169            }
17170        }
17171
17172        if (action != null) {
17173            switch (action) {
17174                case Intent.ACTION_UID_REMOVED:
17175                case Intent.ACTION_PACKAGE_REMOVED:
17176                case Intent.ACTION_PACKAGE_CHANGED:
17177                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17178                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17179                case Intent.ACTION_PACKAGES_SUSPENDED:
17180                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17181                    // Handle special intents: if this broadcast is from the package
17182                    // manager about a package being removed, we need to remove all of
17183                    // its activities from the history stack.
17184                    if (checkComponentPermission(
17185                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17186                            callingPid, callingUid, -1, true)
17187                            != PackageManager.PERMISSION_GRANTED) {
17188                        String msg = "Permission Denial: " + intent.getAction()
17189                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17190                                + ", uid=" + callingUid + ")"
17191                                + " requires "
17192                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17193                        Slog.w(TAG, msg);
17194                        throw new SecurityException(msg);
17195                    }
17196                    switch (action) {
17197                        case Intent.ACTION_UID_REMOVED:
17198                            final Bundle intentExtras = intent.getExtras();
17199                            final int uid = intentExtras != null
17200                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17201                            if (uid >= 0) {
17202                                mBatteryStatsService.removeUid(uid);
17203                                mAppOpsService.uidRemoved(uid);
17204                            }
17205                            break;
17206                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17207                            // If resources are unavailable just force stop all those packages
17208                            // and flush the attribute cache as well.
17209                            String list[] =
17210                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17211                            if (list != null && list.length > 0) {
17212                                for (int i = 0; i < list.length; i++) {
17213                                    forceStopPackageLocked(list[i], -1, false, true, true,
17214                                            false, false, userId, "storage unmount");
17215                                }
17216                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17217                                sendPackageBroadcastLocked(
17218                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17219                                        userId);
17220                            }
17221                            break;
17222                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17223                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17224                            break;
17225                        case Intent.ACTION_PACKAGE_REMOVED:
17226                        case Intent.ACTION_PACKAGE_CHANGED:
17227                            Uri data = intent.getData();
17228                            String ssp;
17229                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17230                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17231                                final boolean replacing =
17232                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17233                                final boolean killProcess =
17234                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17235                                final boolean fullUninstall = removed && !replacing;
17236                                if (killProcess) {
17237                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17238                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17239                                            false, true, true, false, fullUninstall, userId,
17240                                            removed ? "pkg removed" : "pkg changed");
17241                                }
17242                                if (removed) {
17243                                    final int cmd = killProcess
17244                                            ? IApplicationThread.PACKAGE_REMOVED
17245                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17246                                    sendPackageBroadcastLocked(cmd,
17247                                            new String[] {ssp}, userId);
17248                                    if (fullUninstall) {
17249                                        mAppOpsService.packageRemoved(
17250                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17251
17252                                        // Remove all permissions granted from/to this package
17253                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17254
17255                                        removeTasksByPackageNameLocked(ssp, userId);
17256                                        mBatteryStatsService.notePackageUninstalled(ssp);
17257                                    }
17258                                } else {
17259                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17260                                            intent.getStringArrayExtra(
17261                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17262                                }
17263                            }
17264                            break;
17265                        case Intent.ACTION_PACKAGES_SUSPENDED:
17266                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17267                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17268                                    intent.getAction());
17269                            final String[] packageNames = intent.getStringArrayExtra(
17270                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17271                            final int userHandle = intent.getIntExtra(
17272                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17273
17274                            synchronized(ActivityManagerService.this) {
17275                                mRecentTasks.onPackagesSuspendedChanged(
17276                                        packageNames, suspended, userHandle);
17277                            }
17278                            break;
17279                    }
17280                    break;
17281                case Intent.ACTION_PACKAGE_REPLACED:
17282                {
17283                    final Uri data = intent.getData();
17284                    final String ssp;
17285                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17286                        final ApplicationInfo aInfo =
17287                                getPackageManagerInternalLocked().getApplicationInfo(
17288                                        ssp,
17289                                        userId);
17290                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17291                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17292                                new String[] {ssp}, userId);
17293                    }
17294                    break;
17295                }
17296                case Intent.ACTION_PACKAGE_ADDED:
17297                {
17298                    // Special case for adding a package: by default turn on compatibility mode.
17299                    Uri data = intent.getData();
17300                    String ssp;
17301                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17302                        final boolean replacing =
17303                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17304                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17305
17306                        try {
17307                            ApplicationInfo ai = AppGlobals.getPackageManager().
17308                                    getApplicationInfo(ssp, 0, 0);
17309                            mBatteryStatsService.notePackageInstalled(ssp,
17310                                    ai != null ? ai.versionCode : 0);
17311                        } catch (RemoteException e) {
17312                        }
17313                    }
17314                    break;
17315                }
17316                case Intent.ACTION_TIMEZONE_CHANGED:
17317                    // If this is the time zone changed action, queue up a message that will reset
17318                    // the timezone of all currently running processes. This message will get
17319                    // queued up before the broadcast happens.
17320                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17321                    break;
17322                case Intent.ACTION_TIME_CHANGED:
17323                    // If the user set the time, let all running processes know.
17324                    final int is24Hour =
17325                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17326                                    : 0;
17327                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17328                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17329                    synchronized (stats) {
17330                        stats.noteCurrentTimeChangedLocked();
17331                    }
17332                    break;
17333                case Intent.ACTION_CLEAR_DNS_CACHE:
17334                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17335                    break;
17336                case Proxy.PROXY_CHANGE_ACTION:
17337                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17338                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17339                    break;
17340                case android.hardware.Camera.ACTION_NEW_PICTURE:
17341                case android.hardware.Camera.ACTION_NEW_VIDEO:
17342                    // These broadcasts are no longer allowed by the system, since they can
17343                    // cause significant thrashing at a crictical point (using the camera).
17344                    // Apps should use JobScehduler to monitor for media provider changes.
17345                    Slog.w(TAG, action + " no longer allowed; dropping from "
17346                            + UserHandle.formatUid(callingUid));
17347                    // Lie; we don't want to crash the app.
17348                    return ActivityManager.BROADCAST_SUCCESS;
17349            }
17350        }
17351
17352        // Add to the sticky list if requested.
17353        if (sticky) {
17354            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17355                    callingPid, callingUid)
17356                    != PackageManager.PERMISSION_GRANTED) {
17357                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17358                        + callingPid + ", uid=" + callingUid
17359                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17360                Slog.w(TAG, msg);
17361                throw new SecurityException(msg);
17362            }
17363            if (requiredPermissions != null && requiredPermissions.length > 0) {
17364                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17365                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17366                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17367            }
17368            if (intent.getComponent() != null) {
17369                throw new SecurityException(
17370                        "Sticky broadcasts can't target a specific component");
17371            }
17372            // We use userId directly here, since the "all" target is maintained
17373            // as a separate set of sticky broadcasts.
17374            if (userId != UserHandle.USER_ALL) {
17375                // But first, if this is not a broadcast to all users, then
17376                // make sure it doesn't conflict with an existing broadcast to
17377                // all users.
17378                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17379                        UserHandle.USER_ALL);
17380                if (stickies != null) {
17381                    ArrayList<Intent> list = stickies.get(intent.getAction());
17382                    if (list != null) {
17383                        int N = list.size();
17384                        int i;
17385                        for (i=0; i<N; i++) {
17386                            if (intent.filterEquals(list.get(i))) {
17387                                throw new IllegalArgumentException(
17388                                        "Sticky broadcast " + intent + " for user "
17389                                        + userId + " conflicts with existing global broadcast");
17390                            }
17391                        }
17392                    }
17393                }
17394            }
17395            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17396            if (stickies == null) {
17397                stickies = new ArrayMap<>();
17398                mStickyBroadcasts.put(userId, stickies);
17399            }
17400            ArrayList<Intent> list = stickies.get(intent.getAction());
17401            if (list == null) {
17402                list = new ArrayList<>();
17403                stickies.put(intent.getAction(), list);
17404            }
17405            final int stickiesCount = list.size();
17406            int i;
17407            for (i = 0; i < stickiesCount; i++) {
17408                if (intent.filterEquals(list.get(i))) {
17409                    // This sticky already exists, replace it.
17410                    list.set(i, new Intent(intent));
17411                    break;
17412                }
17413            }
17414            if (i >= stickiesCount) {
17415                list.add(new Intent(intent));
17416            }
17417        }
17418
17419        int[] users;
17420        if (userId == UserHandle.USER_ALL) {
17421            // Caller wants broadcast to go to all started users.
17422            users = mUserController.getStartedUserArrayLocked();
17423        } else {
17424            // Caller wants broadcast to go to one specific user.
17425            users = new int[] {userId};
17426        }
17427
17428        // Figure out who all will receive this broadcast.
17429        List receivers = null;
17430        List<BroadcastFilter> registeredReceivers = null;
17431        // Need to resolve the intent to interested receivers...
17432        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17433                 == 0) {
17434            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17435        }
17436        if (intent.getComponent() == null) {
17437            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17438                // Query one target user at a time, excluding shell-restricted users
17439                for (int i = 0; i < users.length; i++) {
17440                    if (mUserController.hasUserRestriction(
17441                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17442                        continue;
17443                    }
17444                    List<BroadcastFilter> registeredReceiversForUser =
17445                            mReceiverResolver.queryIntent(intent,
17446                                    resolvedType, false, users[i]);
17447                    if (registeredReceivers == null) {
17448                        registeredReceivers = registeredReceiversForUser;
17449                    } else if (registeredReceiversForUser != null) {
17450                        registeredReceivers.addAll(registeredReceiversForUser);
17451                    }
17452                }
17453            } else {
17454                registeredReceivers = mReceiverResolver.queryIntent(intent,
17455                        resolvedType, false, userId);
17456            }
17457        }
17458
17459        final boolean replacePending =
17460                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17461
17462        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17463                + " replacePending=" + replacePending);
17464
17465        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17466        if (!ordered && NR > 0) {
17467            // If we are not serializing this broadcast, then send the
17468            // registered receivers separately so they don't wait for the
17469            // components to be launched.
17470            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17471            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17472                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17473                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17474                    resultExtras, ordered, sticky, false, userId);
17475            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17476            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17477            if (!replaced) {
17478                queue.enqueueParallelBroadcastLocked(r);
17479                queue.scheduleBroadcastsLocked();
17480            }
17481            registeredReceivers = null;
17482            NR = 0;
17483        }
17484
17485        // Merge into one list.
17486        int ir = 0;
17487        if (receivers != null) {
17488            // A special case for PACKAGE_ADDED: do not allow the package
17489            // being added to see this broadcast.  This prevents them from
17490            // using this as a back door to get run as soon as they are
17491            // installed.  Maybe in the future we want to have a special install
17492            // broadcast or such for apps, but we'd like to deliberately make
17493            // this decision.
17494            String skipPackages[] = null;
17495            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17496                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17497                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17498                Uri data = intent.getData();
17499                if (data != null) {
17500                    String pkgName = data.getSchemeSpecificPart();
17501                    if (pkgName != null) {
17502                        skipPackages = new String[] { pkgName };
17503                    }
17504                }
17505            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17506                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17507            }
17508            if (skipPackages != null && (skipPackages.length > 0)) {
17509                for (String skipPackage : skipPackages) {
17510                    if (skipPackage != null) {
17511                        int NT = receivers.size();
17512                        for (int it=0; it<NT; it++) {
17513                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17514                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17515                                receivers.remove(it);
17516                                it--;
17517                                NT--;
17518                            }
17519                        }
17520                    }
17521                }
17522            }
17523
17524            int NT = receivers != null ? receivers.size() : 0;
17525            int it = 0;
17526            ResolveInfo curt = null;
17527            BroadcastFilter curr = null;
17528            while (it < NT && ir < NR) {
17529                if (curt == null) {
17530                    curt = (ResolveInfo)receivers.get(it);
17531                }
17532                if (curr == null) {
17533                    curr = registeredReceivers.get(ir);
17534                }
17535                if (curr.getPriority() >= curt.priority) {
17536                    // Insert this broadcast record into the final list.
17537                    receivers.add(it, curr);
17538                    ir++;
17539                    curr = null;
17540                    it++;
17541                    NT++;
17542                } else {
17543                    // Skip to the next ResolveInfo in the final list.
17544                    it++;
17545                    curt = null;
17546                }
17547            }
17548        }
17549        while (ir < NR) {
17550            if (receivers == null) {
17551                receivers = new ArrayList();
17552            }
17553            receivers.add(registeredReceivers.get(ir));
17554            ir++;
17555        }
17556
17557        if ((receivers != null && receivers.size() > 0)
17558                || resultTo != null) {
17559            BroadcastQueue queue = broadcastQueueForIntent(intent);
17560            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17561                    callerPackage, callingPid, callingUid, resolvedType,
17562                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17563                    resultData, resultExtras, ordered, sticky, false, userId);
17564
17565            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17566                    + ": prev had " + queue.mOrderedBroadcasts.size());
17567            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17568                    "Enqueueing broadcast " + r.intent.getAction());
17569
17570            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17571            if (!replaced) {
17572                queue.enqueueOrderedBroadcastLocked(r);
17573                queue.scheduleBroadcastsLocked();
17574            }
17575        }
17576
17577        return ActivityManager.BROADCAST_SUCCESS;
17578    }
17579
17580    final Intent verifyBroadcastLocked(Intent intent) {
17581        // Refuse possible leaked file descriptors
17582        if (intent != null && intent.hasFileDescriptors() == true) {
17583            throw new IllegalArgumentException("File descriptors passed in Intent");
17584        }
17585
17586        int flags = intent.getFlags();
17587
17588        if (!mProcessesReady) {
17589            // if the caller really truly claims to know what they're doing, go
17590            // ahead and allow the broadcast without launching any receivers
17591            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17592                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17593            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17594                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17595                        + " before boot completion");
17596                throw new IllegalStateException("Cannot broadcast before boot completed");
17597            }
17598        }
17599
17600        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17601            throw new IllegalArgumentException(
17602                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17603        }
17604
17605        return intent;
17606    }
17607
17608    public final int broadcastIntent(IApplicationThread caller,
17609            Intent intent, String resolvedType, IIntentReceiver resultTo,
17610            int resultCode, String resultData, Bundle resultExtras,
17611            String[] requiredPermissions, int appOp, Bundle bOptions,
17612            boolean serialized, boolean sticky, int userId) {
17613        enforceNotIsolatedCaller("broadcastIntent");
17614        synchronized(this) {
17615            intent = verifyBroadcastLocked(intent);
17616
17617            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17618            final int callingPid = Binder.getCallingPid();
17619            final int callingUid = Binder.getCallingUid();
17620            final long origId = Binder.clearCallingIdentity();
17621            int res = broadcastIntentLocked(callerApp,
17622                    callerApp != null ? callerApp.info.packageName : null,
17623                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17624                    requiredPermissions, appOp, null, serialized, sticky,
17625                    callingPid, callingUid, userId);
17626            Binder.restoreCallingIdentity(origId);
17627            return res;
17628        }
17629    }
17630
17631
17632    int broadcastIntentInPackage(String packageName, int uid,
17633            Intent intent, String resolvedType, IIntentReceiver resultTo,
17634            int resultCode, String resultData, Bundle resultExtras,
17635            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17636            int userId) {
17637        synchronized(this) {
17638            intent = verifyBroadcastLocked(intent);
17639
17640            final long origId = Binder.clearCallingIdentity();
17641            String[] requiredPermissions = requiredPermission == null ? null
17642                    : new String[] {requiredPermission};
17643            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17644                    resultTo, resultCode, resultData, resultExtras,
17645                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17646                    sticky, -1, uid, userId);
17647            Binder.restoreCallingIdentity(origId);
17648            return res;
17649        }
17650    }
17651
17652    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17653        // Refuse possible leaked file descriptors
17654        if (intent != null && intent.hasFileDescriptors() == true) {
17655            throw new IllegalArgumentException("File descriptors passed in Intent");
17656        }
17657
17658        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17659                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17660
17661        synchronized(this) {
17662            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17663                    != PackageManager.PERMISSION_GRANTED) {
17664                String msg = "Permission Denial: unbroadcastIntent() from pid="
17665                        + Binder.getCallingPid()
17666                        + ", uid=" + Binder.getCallingUid()
17667                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17668                Slog.w(TAG, msg);
17669                throw new SecurityException(msg);
17670            }
17671            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17672            if (stickies != null) {
17673                ArrayList<Intent> list = stickies.get(intent.getAction());
17674                if (list != null) {
17675                    int N = list.size();
17676                    int i;
17677                    for (i=0; i<N; i++) {
17678                        if (intent.filterEquals(list.get(i))) {
17679                            list.remove(i);
17680                            break;
17681                        }
17682                    }
17683                    if (list.size() <= 0) {
17684                        stickies.remove(intent.getAction());
17685                    }
17686                }
17687                if (stickies.size() <= 0) {
17688                    mStickyBroadcasts.remove(userId);
17689                }
17690            }
17691        }
17692    }
17693
17694    void backgroundServicesFinishedLocked(int userId) {
17695        for (BroadcastQueue queue : mBroadcastQueues) {
17696            queue.backgroundServicesFinishedLocked(userId);
17697        }
17698    }
17699
17700    public void finishReceiver(IBinder who, int resultCode, String resultData,
17701            Bundle resultExtras, boolean resultAbort, int flags) {
17702        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17703
17704        // Refuse possible leaked file descriptors
17705        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17706            throw new IllegalArgumentException("File descriptors passed in Bundle");
17707        }
17708
17709        final long origId = Binder.clearCallingIdentity();
17710        try {
17711            boolean doNext = false;
17712            BroadcastRecord r;
17713
17714            synchronized(this) {
17715                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17716                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17717                r = queue.getMatchingOrderedReceiver(who);
17718                if (r != null) {
17719                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17720                        resultData, resultExtras, resultAbort, true);
17721                }
17722            }
17723
17724            if (doNext) {
17725                r.queue.processNextBroadcast(false);
17726            }
17727            trimApplications();
17728        } finally {
17729            Binder.restoreCallingIdentity(origId);
17730        }
17731    }
17732
17733    // =========================================================
17734    // INSTRUMENTATION
17735    // =========================================================
17736
17737    public boolean startInstrumentation(ComponentName className,
17738            String profileFile, int flags, Bundle arguments,
17739            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17740            int userId, String abiOverride) {
17741        enforceNotIsolatedCaller("startInstrumentation");
17742        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17743                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17744        // Refuse possible leaked file descriptors
17745        if (arguments != null && arguments.hasFileDescriptors()) {
17746            throw new IllegalArgumentException("File descriptors passed in Bundle");
17747        }
17748
17749        synchronized(this) {
17750            InstrumentationInfo ii = null;
17751            ApplicationInfo ai = null;
17752            try {
17753                ii = mContext.getPackageManager().getInstrumentationInfo(
17754                    className, STOCK_PM_FLAGS);
17755                ai = AppGlobals.getPackageManager().getApplicationInfo(
17756                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17757            } catch (PackageManager.NameNotFoundException e) {
17758            } catch (RemoteException e) {
17759            }
17760            if (ii == null) {
17761                reportStartInstrumentationFailureLocked(watcher, className,
17762                        "Unable to find instrumentation info for: " + className);
17763                return false;
17764            }
17765            if (ai == null) {
17766                reportStartInstrumentationFailureLocked(watcher, className,
17767                        "Unable to find instrumentation target package: " + ii.targetPackage);
17768                return false;
17769            }
17770            if (!ai.hasCode()) {
17771                reportStartInstrumentationFailureLocked(watcher, className,
17772                        "Instrumentation target has no code: " + ii.targetPackage);
17773                return false;
17774            }
17775
17776            int match = mContext.getPackageManager().checkSignatures(
17777                    ii.targetPackage, ii.packageName);
17778            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17779                String msg = "Permission Denial: starting instrumentation "
17780                        + className + " from pid="
17781                        + Binder.getCallingPid()
17782                        + ", uid=" + Binder.getCallingPid()
17783                        + " not allowed because package " + ii.packageName
17784                        + " does not have a signature matching the target "
17785                        + ii.targetPackage;
17786                reportStartInstrumentationFailureLocked(watcher, className, msg);
17787                throw new SecurityException(msg);
17788            }
17789
17790            final long origId = Binder.clearCallingIdentity();
17791            // Instrumentation can kill and relaunch even persistent processes
17792            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17793                    "start instr");
17794            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17795            app.instrumentationClass = className;
17796            app.instrumentationInfo = ai;
17797            app.instrumentationProfileFile = profileFile;
17798            app.instrumentationArguments = arguments;
17799            app.instrumentationWatcher = watcher;
17800            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17801            app.instrumentationResultClass = className;
17802            Binder.restoreCallingIdentity(origId);
17803        }
17804
17805        return true;
17806    }
17807
17808    /**
17809     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17810     * error to the logs, but if somebody is watching, send the report there too.  This enables
17811     * the "am" command to report errors with more information.
17812     *
17813     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17814     * @param cn The component name of the instrumentation.
17815     * @param report The error report.
17816     */
17817    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17818            ComponentName cn, String report) {
17819        Slog.w(TAG, report);
17820        if (watcher != null) {
17821            Bundle results = new Bundle();
17822            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17823            results.putString("Error", report);
17824            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17825        }
17826    }
17827
17828    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17829        if (app.instrumentationWatcher != null) {
17830            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17831                    app.instrumentationClass, resultCode, results);
17832        }
17833
17834        // Can't call out of the system process with a lock held, so post a message.
17835        if (app.instrumentationUiAutomationConnection != null) {
17836            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17837                    app.instrumentationUiAutomationConnection).sendToTarget();
17838        }
17839
17840        app.instrumentationWatcher = null;
17841        app.instrumentationUiAutomationConnection = null;
17842        app.instrumentationClass = null;
17843        app.instrumentationInfo = null;
17844        app.instrumentationProfileFile = null;
17845        app.instrumentationArguments = null;
17846
17847        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17848                "finished inst");
17849    }
17850
17851    public void finishInstrumentation(IApplicationThread target,
17852            int resultCode, Bundle results) {
17853        int userId = UserHandle.getCallingUserId();
17854        // Refuse possible leaked file descriptors
17855        if (results != null && results.hasFileDescriptors()) {
17856            throw new IllegalArgumentException("File descriptors passed in Intent");
17857        }
17858
17859        synchronized(this) {
17860            ProcessRecord app = getRecordForAppLocked(target);
17861            if (app == null) {
17862                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17863                return;
17864            }
17865            final long origId = Binder.clearCallingIdentity();
17866            finishInstrumentationLocked(app, resultCode, results);
17867            Binder.restoreCallingIdentity(origId);
17868        }
17869    }
17870
17871    // =========================================================
17872    // CONFIGURATION
17873    // =========================================================
17874
17875    public ConfigurationInfo getDeviceConfigurationInfo() {
17876        ConfigurationInfo config = new ConfigurationInfo();
17877        synchronized (this) {
17878            config.reqTouchScreen = mConfiguration.touchscreen;
17879            config.reqKeyboardType = mConfiguration.keyboard;
17880            config.reqNavigation = mConfiguration.navigation;
17881            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17882                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17883                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17884            }
17885            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17886                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17887                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17888            }
17889            config.reqGlEsVersion = GL_ES_VERSION;
17890        }
17891        return config;
17892    }
17893
17894    ActivityStack getFocusedStack() {
17895        return mStackSupervisor.getFocusedStack();
17896    }
17897
17898    @Override
17899    public int getFocusedStackId() throws RemoteException {
17900        ActivityStack focusedStack = getFocusedStack();
17901        if (focusedStack != null) {
17902            return focusedStack.getStackId();
17903        }
17904        return -1;
17905    }
17906
17907    public Configuration getConfiguration() {
17908        Configuration ci;
17909        synchronized(this) {
17910            ci = new Configuration(mConfiguration);
17911            ci.userSetLocale = false;
17912        }
17913        return ci;
17914    }
17915
17916    @Override
17917    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17918        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17919        synchronized (this) {
17920            mSuppressResizeConfigChanges = suppress;
17921        }
17922    }
17923
17924    @Override
17925    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17926        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17927        if (fromStackId == HOME_STACK_ID) {
17928            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17929        }
17930        synchronized (this) {
17931            final long origId = Binder.clearCallingIdentity();
17932            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
17933            if (stack != null) {
17934                mWindowManager.deferSurfaceLayout();
17935                try {
17936                    if (fromStackId == DOCKED_STACK_ID) {
17937
17938                        // We are moving all tasks from the docked stack to the fullscreen stack,
17939                        // which is dismissing the docked stack, so resize all other stacks to
17940                        // fullscreen here already so we don't end up with resize trashing.
17941                        for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
17942                            if (StackId.isResizeableByDockedStack(i)) {
17943                                ActivityStack otherStack = mStackSupervisor.getStack(i);
17944                                if (otherStack != null) {
17945                                    mStackSupervisor.resizeStackLocked(i,
17946                                            null, null, null, PRESERVE_WINDOWS,
17947                                            true /* allowResizeInDockedMode */);
17948                                }
17949                            }
17950                        }
17951                    }
17952                    final ArrayList<TaskRecord> tasks = stack.getAllTasks();
17953                    final int size = tasks.size();
17954                    if (onTop) {
17955                        for (int i = 0; i < size; i++) {
17956                            mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
17957                                    FULLSCREEN_WORKSPACE_STACK_ID, onTop, !FORCE_FOCUS,
17958                                    "moveTasksToFullscreenStack", ANIMATE);
17959                        }
17960                    } else {
17961                        for (int i = size - 1; i >= 0; i--) {
17962                            mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
17963                                    FULLSCREEN_WORKSPACE_STACK_ID, 0);
17964                        }
17965                    }
17966                } finally {
17967                    mWindowManager.continueSurfaceLayout();
17968                }
17969
17970            }
17971            Binder.restoreCallingIdentity(origId);
17972        }
17973    }
17974
17975    @Override
17976    public void updatePersistentConfiguration(Configuration values) {
17977        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17978                "updateConfiguration()");
17979        enforceWriteSettingsPermission("updateConfiguration()");
17980        if (values == null) {
17981            throw new NullPointerException("Configuration must not be null");
17982        }
17983
17984        int userId = UserHandle.getCallingUserId();
17985
17986        synchronized(this) {
17987            final long origId = Binder.clearCallingIdentity();
17988            updateConfigurationLocked(values, null, false, true, userId);
17989            Binder.restoreCallingIdentity(origId);
17990        }
17991    }
17992
17993    private void updateFontScaleIfNeeded() {
17994        final int currentUserId;
17995        synchronized(this) {
17996            currentUserId = mUserController.getCurrentUserIdLocked();
17997        }
17998        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
17999                FONT_SCALE, 1.0f, currentUserId);
18000        if (mConfiguration.fontScale != scaleFactor) {
18001            final Configuration configuration = mWindowManager.computeNewConfiguration();
18002            configuration.fontScale = scaleFactor;
18003            updatePersistentConfiguration(configuration);
18004        }
18005    }
18006
18007    private void enforceWriteSettingsPermission(String func) {
18008        int uid = Binder.getCallingUid();
18009        if (uid == Process.ROOT_UID) {
18010            return;
18011        }
18012
18013        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18014                Settings.getPackageNameForUid(mContext, uid), false)) {
18015            return;
18016        }
18017
18018        String msg = "Permission Denial: " + func + " from pid="
18019                + Binder.getCallingPid()
18020                + ", uid=" + uid
18021                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18022        Slog.w(TAG, msg);
18023        throw new SecurityException(msg);
18024    }
18025
18026    public void updateConfiguration(Configuration values) {
18027        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18028                "updateConfiguration()");
18029
18030        synchronized(this) {
18031            if (values == null && mWindowManager != null) {
18032                // sentinel: fetch the current configuration from the window manager
18033                values = mWindowManager.computeNewConfiguration();
18034            }
18035
18036            if (mWindowManager != null) {
18037                mProcessList.applyDisplaySize(mWindowManager);
18038            }
18039
18040            final long origId = Binder.clearCallingIdentity();
18041            if (values != null) {
18042                Settings.System.clearConfiguration(values);
18043            }
18044            updateConfigurationLocked(values, null, false);
18045            Binder.restoreCallingIdentity(origId);
18046        }
18047    }
18048
18049    void updateUserConfigurationLocked() {
18050        Configuration configuration = new Configuration(mConfiguration);
18051        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18052                mUserController.getCurrentUserIdLocked());
18053        updateConfigurationLocked(configuration, null, false);
18054    }
18055
18056    boolean updateConfigurationLocked(Configuration values,
18057            ActivityRecord starting, boolean initLocale) {
18058        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18059        return updateConfigurationLocked(values, starting, initLocale, false,
18060                UserHandle.USER_NULL);
18061    }
18062
18063    // To cache the list of supported system locales
18064    private String[] mSupportedSystemLocales = null;
18065
18066    /**
18067     * Do either or both things: (1) change the current configuration, and (2)
18068     * make sure the given activity is running with the (now) current
18069     * configuration.  Returns true if the activity has been left running, or
18070     * false if <var>starting</var> is being destroyed to match the new
18071     * configuration.
18072     *
18073     * @param userId is only used when persistent parameter is set to true to persist configuration
18074     *               for that particular user
18075     */
18076    private boolean updateConfigurationLocked(Configuration values,
18077            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18078        int changes = 0;
18079
18080        if (mWindowManager != null) {
18081            mWindowManager.deferSurfaceLayout();
18082        }
18083        if (values != null) {
18084            Configuration newConfig = new Configuration(mConfiguration);
18085            changes = newConfig.updateFrom(values);
18086            if (changes != 0) {
18087                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18088                        "Updating configuration to: " + values);
18089
18090                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18091
18092                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18093                    final Locale locale;
18094                    if (values.getLocales().size() == 1) {
18095                        // This is an optimization to avoid the JNI call when the result of
18096                        // getFirstMatch() does not depend on the supported locales.
18097                        locale = values.getLocales().get(0);
18098                    } else {
18099                        if (mSupportedSystemLocales == null) {
18100                            mSupportedSystemLocales =
18101                                    Resources.getSystem().getAssets().getLocales();
18102                        }
18103                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18104                    }
18105                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18106                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18107                            locale));
18108                }
18109
18110                mConfigurationSeq++;
18111                if (mConfigurationSeq <= 0) {
18112                    mConfigurationSeq = 1;
18113                }
18114                newConfig.seq = mConfigurationSeq;
18115                mConfiguration = newConfig;
18116                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18117                mUsageStatsService.reportConfigurationChange(newConfig,
18118                        mUserController.getCurrentUserIdLocked());
18119                //mUsageStatsService.noteStartConfig(newConfig);
18120
18121                final Configuration configCopy = new Configuration(mConfiguration);
18122
18123                // TODO: If our config changes, should we auto dismiss any currently
18124                // showing dialogs?
18125                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18126
18127                AttributeCache ac = AttributeCache.instance();
18128                if (ac != null) {
18129                    ac.updateConfiguration(configCopy);
18130                }
18131
18132                // Make sure all resources in our process are updated
18133                // right now, so that anyone who is going to retrieve
18134                // resource values after we return will be sure to get
18135                // the new ones.  This is especially important during
18136                // boot, where the first config change needs to guarantee
18137                // all resources have that config before following boot
18138                // code is executed.
18139                mSystemThread.applyConfigurationToResources(configCopy);
18140
18141                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18142                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18143                    msg.obj = new Configuration(configCopy);
18144                    msg.arg1 = userId;
18145                    mHandler.sendMessage(msg);
18146                }
18147
18148                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18149                if (isDensityChange) {
18150                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18151                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18152                }
18153
18154                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18155                    ProcessRecord app = mLruProcesses.get(i);
18156                    try {
18157                        if (app.thread != null) {
18158                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18159                                    + app.processName + " new config " + mConfiguration);
18160                            app.thread.scheduleConfigurationChanged(configCopy);
18161                        }
18162                    } catch (Exception e) {
18163                    }
18164                }
18165                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18166                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18167                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18168                        | Intent.FLAG_RECEIVER_FOREGROUND);
18169                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18170                        null, AppOpsManager.OP_NONE, null, false, false,
18171                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18172                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18173                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18174                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18175                    if (!mProcessesReady) {
18176                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18177                    }
18178                    broadcastIntentLocked(null, null, intent,
18179                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18180                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18181                }
18182            }
18183            // Update the configuration with WM first and check if any of the stacks need to be
18184            // resized due to the configuration change. If so, resize the stacks now and do any
18185            // relaunches if necessary. This way we don't need to relaunch again below in
18186            // ensureActivityConfigurationLocked().
18187            if (mWindowManager != null) {
18188                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18189                if (resizedStacks != null) {
18190                    for (int stackId : resizedStacks) {
18191                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18192                        mStackSupervisor.resizeStackLocked(
18193                                stackId, newBounds, null, null, false, false);
18194                    }
18195                }
18196            }
18197        }
18198
18199        boolean kept = true;
18200        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18201        // mainStack is null during startup.
18202        if (mainStack != null) {
18203            if (changes != 0 && starting == null) {
18204                // If the configuration changed, and the caller is not already
18205                // in the process of starting an activity, then find the top
18206                // activity to check if its configuration needs to change.
18207                starting = mainStack.topRunningActivityLocked();
18208            }
18209
18210            if (starting != null) {
18211                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18212                // And we need to make sure at this point that all other activities
18213                // are made visible with the correct configuration.
18214                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18215                        !PRESERVE_WINDOWS);
18216            }
18217        }
18218        if (mWindowManager != null) {
18219            mWindowManager.continueSurfaceLayout();
18220        }
18221        return kept;
18222    }
18223
18224    /**
18225     * Decide based on the configuration whether we should shouw the ANR,
18226     * crash, etc dialogs.  The idea is that if there is no affordnace to
18227     * press the on-screen buttons, we shouldn't show the dialog.
18228     *
18229     * A thought: SystemUI might also want to get told about this, the Power
18230     * dialog / global actions also might want different behaviors.
18231     */
18232    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18233        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18234                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18235                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18236        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18237                                    == Configuration.UI_MODE_TYPE_CAR);
18238        return inputMethodExists && uiIsNotCarType && !inVrMode;
18239    }
18240
18241    @Override
18242    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18243        synchronized (this) {
18244            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18245            if (srec != null) {
18246                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18247            }
18248        }
18249        return false;
18250    }
18251
18252    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18253            Intent resultData) {
18254
18255        synchronized (this) {
18256            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18257            if (r != null) {
18258                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18259            }
18260            return false;
18261        }
18262    }
18263
18264    public int getLaunchedFromUid(IBinder activityToken) {
18265        ActivityRecord srec;
18266        synchronized (this) {
18267            srec = ActivityRecord.forTokenLocked(activityToken);
18268        }
18269        if (srec == null) {
18270            return -1;
18271        }
18272        return srec.launchedFromUid;
18273    }
18274
18275    public String getLaunchedFromPackage(IBinder activityToken) {
18276        ActivityRecord srec;
18277        synchronized (this) {
18278            srec = ActivityRecord.forTokenLocked(activityToken);
18279        }
18280        if (srec == null) {
18281            return null;
18282        }
18283        return srec.launchedFromPackage;
18284    }
18285
18286    // =========================================================
18287    // LIFETIME MANAGEMENT
18288    // =========================================================
18289
18290    // Returns which broadcast queue the app is the current [or imminent] receiver
18291    // on, or 'null' if the app is not an active broadcast recipient.
18292    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18293        BroadcastRecord r = app.curReceiver;
18294        if (r != null) {
18295            return r.queue;
18296        }
18297
18298        // It's not the current receiver, but it might be starting up to become one
18299        synchronized (this) {
18300            for (BroadcastQueue queue : mBroadcastQueues) {
18301                r = queue.mPendingBroadcast;
18302                if (r != null && r.curApp == app) {
18303                    // found it; report which queue it's in
18304                    return queue;
18305                }
18306            }
18307        }
18308
18309        return null;
18310    }
18311
18312    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18313            int targetUid, ComponentName targetComponent, String targetProcess) {
18314        if (!mTrackingAssociations) {
18315            return null;
18316        }
18317        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18318                = mAssociations.get(targetUid);
18319        if (components == null) {
18320            components = new ArrayMap<>();
18321            mAssociations.put(targetUid, components);
18322        }
18323        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18324        if (sourceUids == null) {
18325            sourceUids = new SparseArray<>();
18326            components.put(targetComponent, sourceUids);
18327        }
18328        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18329        if (sourceProcesses == null) {
18330            sourceProcesses = new ArrayMap<>();
18331            sourceUids.put(sourceUid, sourceProcesses);
18332        }
18333        Association ass = sourceProcesses.get(sourceProcess);
18334        if (ass == null) {
18335            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18336                    targetProcess);
18337            sourceProcesses.put(sourceProcess, ass);
18338        }
18339        ass.mCount++;
18340        ass.mNesting++;
18341        if (ass.mNesting == 1) {
18342            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18343            ass.mLastState = sourceState;
18344        }
18345        return ass;
18346    }
18347
18348    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18349            ComponentName targetComponent) {
18350        if (!mTrackingAssociations) {
18351            return;
18352        }
18353        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18354                = mAssociations.get(targetUid);
18355        if (components == null) {
18356            return;
18357        }
18358        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18359        if (sourceUids == null) {
18360            return;
18361        }
18362        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18363        if (sourceProcesses == null) {
18364            return;
18365        }
18366        Association ass = sourceProcesses.get(sourceProcess);
18367        if (ass == null || ass.mNesting <= 0) {
18368            return;
18369        }
18370        ass.mNesting--;
18371        if (ass.mNesting == 0) {
18372            long uptime = SystemClock.uptimeMillis();
18373            ass.mTime += uptime - ass.mStartTime;
18374            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18375                    += uptime - ass.mLastStateUptime;
18376            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18377        }
18378    }
18379
18380    private void noteUidProcessState(final int uid, final int state) {
18381        mBatteryStatsService.noteUidProcessState(uid, state);
18382        if (mTrackingAssociations) {
18383            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18384                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18385                        = mAssociations.valueAt(i1);
18386                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18387                    SparseArray<ArrayMap<String, Association>> sourceUids
18388                            = targetComponents.valueAt(i2);
18389                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18390                    if (sourceProcesses != null) {
18391                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18392                            Association ass = sourceProcesses.valueAt(i4);
18393                            if (ass.mNesting >= 1) {
18394                                // currently associated
18395                                long uptime = SystemClock.uptimeMillis();
18396                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18397                                        += uptime - ass.mLastStateUptime;
18398                                ass.mLastState = state;
18399                                ass.mLastStateUptime = uptime;
18400                            }
18401                        }
18402                    }
18403                }
18404            }
18405        }
18406    }
18407
18408    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18409            boolean doingAll, long now) {
18410        if (mAdjSeq == app.adjSeq) {
18411            // This adjustment has already been computed.
18412            return app.curRawAdj;
18413        }
18414
18415        if (app.thread == null) {
18416            app.adjSeq = mAdjSeq;
18417            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18418            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18419            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18420        }
18421
18422        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18423        app.adjSource = null;
18424        app.adjTarget = null;
18425        app.empty = false;
18426        app.cached = false;
18427
18428        final int activitiesSize = app.activities.size();
18429
18430        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18431            // The max adjustment doesn't allow this app to be anything
18432            // below foreground, so it is not worth doing work for it.
18433            app.adjType = "fixed";
18434            app.adjSeq = mAdjSeq;
18435            app.curRawAdj = app.maxAdj;
18436            app.foregroundActivities = false;
18437            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18438            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18439            // System processes can do UI, and when they do we want to have
18440            // them trim their memory after the user leaves the UI.  To
18441            // facilitate this, here we need to determine whether or not it
18442            // is currently showing UI.
18443            app.systemNoUi = true;
18444            if (app == TOP_APP) {
18445                app.systemNoUi = false;
18446            } else if (activitiesSize > 0) {
18447                for (int j = 0; j < activitiesSize; j++) {
18448                    final ActivityRecord r = app.activities.get(j);
18449                    if (r.visible) {
18450                        app.systemNoUi = false;
18451                    }
18452                }
18453            }
18454            if (!app.systemNoUi) {
18455                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18456            }
18457            return (app.curAdj=app.maxAdj);
18458        }
18459
18460        app.systemNoUi = false;
18461
18462        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18463
18464        // Determine the importance of the process, starting with most
18465        // important to least, and assign an appropriate OOM adjustment.
18466        int adj;
18467        int schedGroup;
18468        int procState;
18469        boolean foregroundActivities = false;
18470        BroadcastQueue queue;
18471        if (app == TOP_APP) {
18472            // The last app on the list is the foreground app.
18473            adj = ProcessList.FOREGROUND_APP_ADJ;
18474            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18475            app.adjType = "top-activity";
18476            foregroundActivities = true;
18477            procState = PROCESS_STATE_CUR_TOP;
18478        } else if (app.instrumentationClass != null) {
18479            // Don't want to kill running instrumentation.
18480            adj = ProcessList.FOREGROUND_APP_ADJ;
18481            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18482            app.adjType = "instrumentation";
18483            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18484        } else if ((queue = isReceivingBroadcast(app)) != null) {
18485            // An app that is currently receiving a broadcast also
18486            // counts as being in the foreground for OOM killer purposes.
18487            // It's placed in a sched group based on the nature of the
18488            // broadcast as reflected by which queue it's active in.
18489            adj = ProcessList.FOREGROUND_APP_ADJ;
18490            schedGroup = (queue == mFgBroadcastQueue)
18491                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18492            app.adjType = "broadcast";
18493            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18494        } else if (app.executingServices.size() > 0) {
18495            // An app that is currently executing a service callback also
18496            // counts as being in the foreground.
18497            adj = ProcessList.FOREGROUND_APP_ADJ;
18498            schedGroup = app.execServicesFg ?
18499                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18500            app.adjType = "exec-service";
18501            procState = ActivityManager.PROCESS_STATE_SERVICE;
18502            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18503        } else {
18504            // As far as we know the process is empty.  We may change our mind later.
18505            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18506            // At this point we don't actually know the adjustment.  Use the cached adj
18507            // value that the caller wants us to.
18508            adj = cachedAdj;
18509            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18510            app.cached = true;
18511            app.empty = true;
18512            app.adjType = "cch-empty";
18513        }
18514
18515        // Examine all activities if not already foreground.
18516        if (!foregroundActivities && activitiesSize > 0) {
18517            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18518            for (int j = 0; j < activitiesSize; j++) {
18519                final ActivityRecord r = app.activities.get(j);
18520                if (r.app != app) {
18521                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18522                            + " instead of expected " + app);
18523                    if (r.app == null || (r.app.uid == app.uid)) {
18524                        // Only fix things up when they look sane
18525                        r.app = app;
18526                    } else {
18527                        continue;
18528                    }
18529                }
18530                if (r.visible) {
18531                    // App has a visible activity; only upgrade adjustment.
18532                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18533                        adj = ProcessList.VISIBLE_APP_ADJ;
18534                        app.adjType = "visible";
18535                    }
18536                    if (procState > PROCESS_STATE_CUR_TOP) {
18537                        procState = PROCESS_STATE_CUR_TOP;
18538                    }
18539                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18540                    app.cached = false;
18541                    app.empty = false;
18542                    foregroundActivities = true;
18543                    if (r.task != null && minLayer > 0) {
18544                        final int layer = r.task.mLayerRank;
18545                        if (layer >= 0 && minLayer > layer) {
18546                            minLayer = layer;
18547                        }
18548                    }
18549                    break;
18550                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18551                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18552                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18553                        app.adjType = "pausing";
18554                    }
18555                    if (procState > PROCESS_STATE_CUR_TOP) {
18556                        procState = PROCESS_STATE_CUR_TOP;
18557                    }
18558                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18559                    app.cached = false;
18560                    app.empty = false;
18561                    foregroundActivities = true;
18562                } else if (r.state == ActivityState.STOPPING) {
18563                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18564                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18565                        app.adjType = "stopping";
18566                    }
18567                    // For the process state, we will at this point consider the
18568                    // process to be cached.  It will be cached either as an activity
18569                    // or empty depending on whether the activity is finishing.  We do
18570                    // this so that we can treat the process as cached for purposes of
18571                    // memory trimming (determing current memory level, trim command to
18572                    // send to process) since there can be an arbitrary number of stopping
18573                    // processes and they should soon all go into the cached state.
18574                    if (!r.finishing) {
18575                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18576                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18577                        }
18578                    }
18579                    app.cached = false;
18580                    app.empty = false;
18581                    foregroundActivities = true;
18582                } else {
18583                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18584                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18585                        app.adjType = "cch-act";
18586                    }
18587                }
18588            }
18589            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18590                adj += minLayer;
18591            }
18592        }
18593
18594        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18595                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18596            if (app.foregroundServices) {
18597                // The user is aware of this app, so make it visible.
18598                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18599                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18600                app.cached = false;
18601                app.adjType = "fg-service";
18602                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18603            } else if (app.forcingToForeground != null) {
18604                // The user is aware of this app, so make it visible.
18605                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18606                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18607                app.cached = false;
18608                app.adjType = "force-fg";
18609                app.adjSource = app.forcingToForeground;
18610                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18611            }
18612        }
18613
18614        if (app == mHeavyWeightProcess) {
18615            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18616                // We don't want to kill the current heavy-weight process.
18617                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18618                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18619                app.cached = false;
18620                app.adjType = "heavy";
18621            }
18622            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18623                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18624            }
18625        }
18626
18627        if (app == mHomeProcess) {
18628            if (adj > ProcessList.HOME_APP_ADJ) {
18629                // This process is hosting what we currently consider to be the
18630                // home app, so we don't want to let it go into the background.
18631                adj = ProcessList.HOME_APP_ADJ;
18632                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18633                app.cached = false;
18634                app.adjType = "home";
18635            }
18636            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18637                procState = ActivityManager.PROCESS_STATE_HOME;
18638            }
18639        }
18640
18641        if (app == mPreviousProcess && app.activities.size() > 0) {
18642            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18643                // This was the previous process that showed UI to the user.
18644                // We want to try to keep it around more aggressively, to give
18645                // a good experience around switching between two apps.
18646                adj = ProcessList.PREVIOUS_APP_ADJ;
18647                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18648                app.cached = false;
18649                app.adjType = "previous";
18650            }
18651            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18652                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18653            }
18654        }
18655
18656        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18657                + " reason=" + app.adjType);
18658
18659        // By default, we use the computed adjustment.  It may be changed if
18660        // there are applications dependent on our services or providers, but
18661        // this gives us a baseline and makes sure we don't get into an
18662        // infinite recursion.
18663        app.adjSeq = mAdjSeq;
18664        app.curRawAdj = adj;
18665        app.hasStartedServices = false;
18666
18667        if (mBackupTarget != null && app == mBackupTarget.app) {
18668            // If possible we want to avoid killing apps while they're being backed up
18669            if (adj > ProcessList.BACKUP_APP_ADJ) {
18670                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18671                adj = ProcessList.BACKUP_APP_ADJ;
18672                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18673                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18674                }
18675                app.adjType = "backup";
18676                app.cached = false;
18677            }
18678            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18679                procState = ActivityManager.PROCESS_STATE_BACKUP;
18680            }
18681        }
18682
18683        boolean mayBeTop = false;
18684
18685        for (int is = app.services.size()-1;
18686                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18687                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18688                        || procState > ActivityManager.PROCESS_STATE_TOP);
18689                is--) {
18690            ServiceRecord s = app.services.valueAt(is);
18691            if (s.startRequested) {
18692                app.hasStartedServices = true;
18693                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18694                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18695                }
18696                if (app.hasShownUi && app != mHomeProcess) {
18697                    // If this process has shown some UI, let it immediately
18698                    // go to the LRU list because it may be pretty heavy with
18699                    // UI stuff.  We'll tag it with a label just to help
18700                    // debug and understand what is going on.
18701                    if (adj > ProcessList.SERVICE_ADJ) {
18702                        app.adjType = "cch-started-ui-services";
18703                    }
18704                } else {
18705                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18706                        // This service has seen some activity within
18707                        // recent memory, so we will keep its process ahead
18708                        // of the background processes.
18709                        if (adj > ProcessList.SERVICE_ADJ) {
18710                            adj = ProcessList.SERVICE_ADJ;
18711                            app.adjType = "started-services";
18712                            app.cached = false;
18713                        }
18714                    }
18715                    // If we have let the service slide into the background
18716                    // state, still have some text describing what it is doing
18717                    // even though the service no longer has an impact.
18718                    if (adj > ProcessList.SERVICE_ADJ) {
18719                        app.adjType = "cch-started-services";
18720                    }
18721                }
18722            }
18723            for (int conni = s.connections.size()-1;
18724                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18725                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18726                            || procState > ActivityManager.PROCESS_STATE_TOP);
18727                    conni--) {
18728                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18729                for (int i = 0;
18730                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18731                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18732                                || procState > ActivityManager.PROCESS_STATE_TOP);
18733                        i++) {
18734                    // XXX should compute this based on the max of
18735                    // all connected clients.
18736                    ConnectionRecord cr = clist.get(i);
18737                    if (cr.binding.client == app) {
18738                        // Binding to ourself is not interesting.
18739                        continue;
18740                    }
18741                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18742                        ProcessRecord client = cr.binding.client;
18743                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18744                                TOP_APP, doingAll, now);
18745                        int clientProcState = client.curProcState;
18746                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18747                            // If the other app is cached for any reason, for purposes here
18748                            // we are going to consider it empty.  The specific cached state
18749                            // doesn't propagate except under certain conditions.
18750                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18751                        }
18752                        String adjType = null;
18753                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18754                            // Not doing bind OOM management, so treat
18755                            // this guy more like a started service.
18756                            if (app.hasShownUi && app != mHomeProcess) {
18757                                // If this process has shown some UI, let it immediately
18758                                // go to the LRU list because it may be pretty heavy with
18759                                // UI stuff.  We'll tag it with a label just to help
18760                                // debug and understand what is going on.
18761                                if (adj > clientAdj) {
18762                                    adjType = "cch-bound-ui-services";
18763                                }
18764                                app.cached = false;
18765                                clientAdj = adj;
18766                                clientProcState = procState;
18767                            } else {
18768                                if (now >= (s.lastActivity
18769                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18770                                    // This service has not seen activity within
18771                                    // recent memory, so allow it to drop to the
18772                                    // LRU list if there is no other reason to keep
18773                                    // it around.  We'll also tag it with a label just
18774                                    // to help debug and undertand what is going on.
18775                                    if (adj > clientAdj) {
18776                                        adjType = "cch-bound-services";
18777                                    }
18778                                    clientAdj = adj;
18779                                }
18780                            }
18781                        }
18782                        if (adj > clientAdj) {
18783                            // If this process has recently shown UI, and
18784                            // the process that is binding to it is less
18785                            // important than being visible, then we don't
18786                            // care about the binding as much as we care
18787                            // about letting this process get into the LRU
18788                            // list to be killed and restarted if needed for
18789                            // memory.
18790                            if (app.hasShownUi && app != mHomeProcess
18791                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18792                                adjType = "cch-bound-ui-services";
18793                            } else {
18794                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18795                                        |Context.BIND_IMPORTANT)) != 0) {
18796                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18797                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18798                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18799                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18800                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18801                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18802                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18803                                    adj = clientAdj;
18804                                } else {
18805                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18806                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18807                                    }
18808                                }
18809                                if (!client.cached) {
18810                                    app.cached = false;
18811                                }
18812                                adjType = "service";
18813                            }
18814                        }
18815                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18816                            // This will treat important bound services identically to
18817                            // the top app, which may behave differently than generic
18818                            // foreground work.
18819                            if (client.curSchedGroup > schedGroup) {
18820                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18821                                    schedGroup = client.curSchedGroup;
18822                                } else {
18823                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18824                                }
18825                            }
18826                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18827                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18828                                    // Special handling of clients who are in the top state.
18829                                    // We *may* want to consider this process to be in the
18830                                    // top state as well, but only if there is not another
18831                                    // reason for it to be running.  Being on the top is a
18832                                    // special state, meaning you are specifically running
18833                                    // for the current top app.  If the process is already
18834                                    // running in the background for some other reason, it
18835                                    // is more important to continue considering it to be
18836                                    // in the background state.
18837                                    mayBeTop = true;
18838                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18839                                } else {
18840                                    // Special handling for above-top states (persistent
18841                                    // processes).  These should not bring the current process
18842                                    // into the top state, since they are not on top.  Instead
18843                                    // give them the best state after that.
18844                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18845                                        clientProcState =
18846                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18847                                    } else if (mWakefulness
18848                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18849                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18850                                                    != 0) {
18851                                        clientProcState =
18852                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18853                                    } else {
18854                                        clientProcState =
18855                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18856                                    }
18857                                }
18858                            }
18859                        } else {
18860                            if (clientProcState <
18861                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18862                                clientProcState =
18863                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18864                            }
18865                        }
18866                        if (procState > clientProcState) {
18867                            procState = clientProcState;
18868                        }
18869                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18870                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18871                            app.pendingUiClean = true;
18872                        }
18873                        if (adjType != null) {
18874                            app.adjType = adjType;
18875                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18876                                    .REASON_SERVICE_IN_USE;
18877                            app.adjSource = cr.binding.client;
18878                            app.adjSourceProcState = clientProcState;
18879                            app.adjTarget = s.name;
18880                        }
18881                    }
18882                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18883                        app.treatLikeActivity = true;
18884                    }
18885                    final ActivityRecord a = cr.activity;
18886                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18887                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18888                            (a.visible || a.state == ActivityState.RESUMED ||
18889                             a.state == ActivityState.PAUSING)) {
18890                            adj = ProcessList.FOREGROUND_APP_ADJ;
18891                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18892                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18893                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18894                                } else {
18895                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18896                                }
18897                            }
18898                            app.cached = false;
18899                            app.adjType = "service";
18900                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18901                                    .REASON_SERVICE_IN_USE;
18902                            app.adjSource = a;
18903                            app.adjSourceProcState = procState;
18904                            app.adjTarget = s.name;
18905                        }
18906                    }
18907                }
18908            }
18909        }
18910
18911        for (int provi = app.pubProviders.size()-1;
18912                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18913                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18914                        || procState > ActivityManager.PROCESS_STATE_TOP);
18915                provi--) {
18916            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18917            for (int i = cpr.connections.size()-1;
18918                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18919                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18920                            || procState > ActivityManager.PROCESS_STATE_TOP);
18921                    i--) {
18922                ContentProviderConnection conn = cpr.connections.get(i);
18923                ProcessRecord client = conn.client;
18924                if (client == app) {
18925                    // Being our own client is not interesting.
18926                    continue;
18927                }
18928                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18929                int clientProcState = client.curProcState;
18930                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18931                    // If the other app is cached for any reason, for purposes here
18932                    // we are going to consider it empty.
18933                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18934                }
18935                if (adj > clientAdj) {
18936                    if (app.hasShownUi && app != mHomeProcess
18937                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18938                        app.adjType = "cch-ui-provider";
18939                    } else {
18940                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18941                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18942                        app.adjType = "provider";
18943                    }
18944                    app.cached &= client.cached;
18945                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18946                            .REASON_PROVIDER_IN_USE;
18947                    app.adjSource = client;
18948                    app.adjSourceProcState = clientProcState;
18949                    app.adjTarget = cpr.name;
18950                }
18951                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18952                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18953                        // Special handling of clients who are in the top state.
18954                        // We *may* want to consider this process to be in the
18955                        // top state as well, but only if there is not another
18956                        // reason for it to be running.  Being on the top is a
18957                        // special state, meaning you are specifically running
18958                        // for the current top app.  If the process is already
18959                        // running in the background for some other reason, it
18960                        // is more important to continue considering it to be
18961                        // in the background state.
18962                        mayBeTop = true;
18963                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18964                    } else {
18965                        // Special handling for above-top states (persistent
18966                        // processes).  These should not bring the current process
18967                        // into the top state, since they are not on top.  Instead
18968                        // give them the best state after that.
18969                        clientProcState =
18970                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18971                    }
18972                }
18973                if (procState > clientProcState) {
18974                    procState = clientProcState;
18975                }
18976                if (client.curSchedGroup > schedGroup) {
18977                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18978                }
18979            }
18980            // If the provider has external (non-framework) process
18981            // dependencies, ensure that its adjustment is at least
18982            // FOREGROUND_APP_ADJ.
18983            if (cpr.hasExternalProcessHandles()) {
18984                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18985                    adj = ProcessList.FOREGROUND_APP_ADJ;
18986                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18987                    app.cached = false;
18988                    app.adjType = "provider";
18989                    app.adjTarget = cpr.name;
18990                }
18991                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18992                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18993                }
18994            }
18995        }
18996
18997        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18998            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18999                adj = ProcessList.PREVIOUS_APP_ADJ;
19000                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19001                app.cached = false;
19002                app.adjType = "provider";
19003            }
19004            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19005                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19006            }
19007        }
19008
19009        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19010            // A client of one of our services or providers is in the top state.  We
19011            // *may* want to be in the top state, but not if we are already running in
19012            // the background for some other reason.  For the decision here, we are going
19013            // to pick out a few specific states that we want to remain in when a client
19014            // is top (states that tend to be longer-term) and otherwise allow it to go
19015            // to the top state.
19016            switch (procState) {
19017                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19018                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19019                case ActivityManager.PROCESS_STATE_SERVICE:
19020                    // These all are longer-term states, so pull them up to the top
19021                    // of the background states, but not all the way to the top state.
19022                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19023                    break;
19024                default:
19025                    // Otherwise, top is a better choice, so take it.
19026                    procState = ActivityManager.PROCESS_STATE_TOP;
19027                    break;
19028            }
19029        }
19030
19031        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19032            if (app.hasClientActivities) {
19033                // This is a cached process, but with client activities.  Mark it so.
19034                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19035                app.adjType = "cch-client-act";
19036            } else if (app.treatLikeActivity) {
19037                // This is a cached process, but somebody wants us to treat it like it has
19038                // an activity, okay!
19039                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19040                app.adjType = "cch-as-act";
19041            }
19042        }
19043
19044        if (adj == ProcessList.SERVICE_ADJ) {
19045            if (doingAll) {
19046                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19047                mNewNumServiceProcs++;
19048                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19049                if (!app.serviceb) {
19050                    // This service isn't far enough down on the LRU list to
19051                    // normally be a B service, but if we are low on RAM and it
19052                    // is large we want to force it down since we would prefer to
19053                    // keep launcher over it.
19054                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19055                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19056                        app.serviceHighRam = true;
19057                        app.serviceb = true;
19058                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19059                    } else {
19060                        mNewNumAServiceProcs++;
19061                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19062                    }
19063                } else {
19064                    app.serviceHighRam = false;
19065                }
19066            }
19067            if (app.serviceb) {
19068                adj = ProcessList.SERVICE_B_ADJ;
19069            }
19070        }
19071
19072        app.curRawAdj = adj;
19073
19074        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19075        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19076        if (adj > app.maxAdj) {
19077            adj = app.maxAdj;
19078            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19079                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19080            }
19081        }
19082
19083        // Do final modification to adj.  Everything we do between here and applying
19084        // the final setAdj must be done in this function, because we will also use
19085        // it when computing the final cached adj later.  Note that we don't need to
19086        // worry about this for max adj above, since max adj will always be used to
19087        // keep it out of the cached vaues.
19088        app.curAdj = app.modifyRawOomAdj(adj);
19089        app.curSchedGroup = schedGroup;
19090        app.curProcState = procState;
19091        app.foregroundActivities = foregroundActivities;
19092
19093        return app.curRawAdj;
19094    }
19095
19096    /**
19097     * Record new PSS sample for a process.
19098     */
19099    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19100            long now) {
19101        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19102                swapPss * 1024);
19103        proc.lastPssTime = now;
19104        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19105        if (DEBUG_PSS) Slog.d(TAG_PSS,
19106                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19107                + " state=" + ProcessList.makeProcStateString(procState));
19108        if (proc.initialIdlePss == 0) {
19109            proc.initialIdlePss = pss;
19110        }
19111        proc.lastPss = pss;
19112        proc.lastSwapPss = swapPss;
19113        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19114            proc.lastCachedPss = pss;
19115            proc.lastCachedSwapPss = swapPss;
19116        }
19117
19118        final SparseArray<Pair<Long, String>> watchUids
19119                = mMemWatchProcesses.getMap().get(proc.processName);
19120        Long check = null;
19121        if (watchUids != null) {
19122            Pair<Long, String> val = watchUids.get(proc.uid);
19123            if (val == null) {
19124                val = watchUids.get(0);
19125            }
19126            if (val != null) {
19127                check = val.first;
19128            }
19129        }
19130        if (check != null) {
19131            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19132                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19133                if (!isDebuggable) {
19134                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19135                        isDebuggable = true;
19136                    }
19137                }
19138                if (isDebuggable) {
19139                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19140                    final ProcessRecord myProc = proc;
19141                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19142                    mMemWatchDumpProcName = proc.processName;
19143                    mMemWatchDumpFile = heapdumpFile.toString();
19144                    mMemWatchDumpPid = proc.pid;
19145                    mMemWatchDumpUid = proc.uid;
19146                    BackgroundThread.getHandler().post(new Runnable() {
19147                        @Override
19148                        public void run() {
19149                            revokeUriPermission(ActivityThread.currentActivityThread()
19150                                            .getApplicationThread(),
19151                                    DumpHeapActivity.JAVA_URI,
19152                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19153                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19154                                    UserHandle.myUserId());
19155                            ParcelFileDescriptor fd = null;
19156                            try {
19157                                heapdumpFile.delete();
19158                                fd = ParcelFileDescriptor.open(heapdumpFile,
19159                                        ParcelFileDescriptor.MODE_CREATE |
19160                                                ParcelFileDescriptor.MODE_TRUNCATE |
19161                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19162                                                ParcelFileDescriptor.MODE_APPEND);
19163                                IApplicationThread thread = myProc.thread;
19164                                if (thread != null) {
19165                                    try {
19166                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19167                                                "Requesting dump heap from "
19168                                                + myProc + " to " + heapdumpFile);
19169                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19170                                    } catch (RemoteException e) {
19171                                    }
19172                                }
19173                            } catch (FileNotFoundException e) {
19174                                e.printStackTrace();
19175                            } finally {
19176                                if (fd != null) {
19177                                    try {
19178                                        fd.close();
19179                                    } catch (IOException e) {
19180                                    }
19181                                }
19182                            }
19183                        }
19184                    });
19185                } else {
19186                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19187                            + ", but debugging not enabled");
19188                }
19189            }
19190        }
19191    }
19192
19193    /**
19194     * Schedule PSS collection of a process.
19195     */
19196    void requestPssLocked(ProcessRecord proc, int procState) {
19197        if (mPendingPssProcesses.contains(proc)) {
19198            return;
19199        }
19200        if (mPendingPssProcesses.size() == 0) {
19201            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19202        }
19203        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19204        proc.pssProcState = procState;
19205        mPendingPssProcesses.add(proc);
19206    }
19207
19208    /**
19209     * Schedule PSS collection of all processes.
19210     */
19211    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19212        if (!always) {
19213            if (now < (mLastFullPssTime +
19214                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19215                return;
19216            }
19217        }
19218        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19219        mLastFullPssTime = now;
19220        mFullPssPending = true;
19221        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19222        mPendingPssProcesses.clear();
19223        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19224            ProcessRecord app = mLruProcesses.get(i);
19225            if (app.thread == null
19226                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19227                continue;
19228            }
19229            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19230                app.pssProcState = app.setProcState;
19231                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19232                        mTestPssMode, isSleeping(), now);
19233                mPendingPssProcesses.add(app);
19234            }
19235        }
19236        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19237    }
19238
19239    public void setTestPssMode(boolean enabled) {
19240        synchronized (this) {
19241            mTestPssMode = enabled;
19242            if (enabled) {
19243                // Whenever we enable the mode, we want to take a snapshot all of current
19244                // process mem use.
19245                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19246            }
19247        }
19248    }
19249
19250    /**
19251     * Ask a given process to GC right now.
19252     */
19253    final void performAppGcLocked(ProcessRecord app) {
19254        try {
19255            app.lastRequestedGc = SystemClock.uptimeMillis();
19256            if (app.thread != null) {
19257                if (app.reportLowMemory) {
19258                    app.reportLowMemory = false;
19259                    app.thread.scheduleLowMemory();
19260                } else {
19261                    app.thread.processInBackground();
19262                }
19263            }
19264        } catch (Exception e) {
19265            // whatever.
19266        }
19267    }
19268
19269    /**
19270     * Returns true if things are idle enough to perform GCs.
19271     */
19272    private final boolean canGcNowLocked() {
19273        boolean processingBroadcasts = false;
19274        for (BroadcastQueue q : mBroadcastQueues) {
19275            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19276                processingBroadcasts = true;
19277            }
19278        }
19279        return !processingBroadcasts
19280                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19281    }
19282
19283    /**
19284     * Perform GCs on all processes that are waiting for it, but only
19285     * if things are idle.
19286     */
19287    final void performAppGcsLocked() {
19288        final int N = mProcessesToGc.size();
19289        if (N <= 0) {
19290            return;
19291        }
19292        if (canGcNowLocked()) {
19293            while (mProcessesToGc.size() > 0) {
19294                ProcessRecord proc = mProcessesToGc.remove(0);
19295                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19296                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19297                            <= SystemClock.uptimeMillis()) {
19298                        // To avoid spamming the system, we will GC processes one
19299                        // at a time, waiting a few seconds between each.
19300                        performAppGcLocked(proc);
19301                        scheduleAppGcsLocked();
19302                        return;
19303                    } else {
19304                        // It hasn't been long enough since we last GCed this
19305                        // process...  put it in the list to wait for its time.
19306                        addProcessToGcListLocked(proc);
19307                        break;
19308                    }
19309                }
19310            }
19311
19312            scheduleAppGcsLocked();
19313        }
19314    }
19315
19316    /**
19317     * If all looks good, perform GCs on all processes waiting for them.
19318     */
19319    final void performAppGcsIfAppropriateLocked() {
19320        if (canGcNowLocked()) {
19321            performAppGcsLocked();
19322            return;
19323        }
19324        // Still not idle, wait some more.
19325        scheduleAppGcsLocked();
19326    }
19327
19328    /**
19329     * Schedule the execution of all pending app GCs.
19330     */
19331    final void scheduleAppGcsLocked() {
19332        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19333
19334        if (mProcessesToGc.size() > 0) {
19335            // Schedule a GC for the time to the next process.
19336            ProcessRecord proc = mProcessesToGc.get(0);
19337            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19338
19339            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19340            long now = SystemClock.uptimeMillis();
19341            if (when < (now+GC_TIMEOUT)) {
19342                when = now + GC_TIMEOUT;
19343            }
19344            mHandler.sendMessageAtTime(msg, when);
19345        }
19346    }
19347
19348    /**
19349     * Add a process to the array of processes waiting to be GCed.  Keeps the
19350     * list in sorted order by the last GC time.  The process can't already be
19351     * on the list.
19352     */
19353    final void addProcessToGcListLocked(ProcessRecord proc) {
19354        boolean added = false;
19355        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19356            if (mProcessesToGc.get(i).lastRequestedGc <
19357                    proc.lastRequestedGc) {
19358                added = true;
19359                mProcessesToGc.add(i+1, proc);
19360                break;
19361            }
19362        }
19363        if (!added) {
19364            mProcessesToGc.add(0, proc);
19365        }
19366    }
19367
19368    /**
19369     * Set up to ask a process to GC itself.  This will either do it
19370     * immediately, or put it on the list of processes to gc the next
19371     * time things are idle.
19372     */
19373    final void scheduleAppGcLocked(ProcessRecord app) {
19374        long now = SystemClock.uptimeMillis();
19375        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19376            return;
19377        }
19378        if (!mProcessesToGc.contains(app)) {
19379            addProcessToGcListLocked(app);
19380            scheduleAppGcsLocked();
19381        }
19382    }
19383
19384    final void checkExcessivePowerUsageLocked(boolean doKills) {
19385        updateCpuStatsNow();
19386
19387        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19388        boolean doWakeKills = doKills;
19389        boolean doCpuKills = doKills;
19390        if (mLastPowerCheckRealtime == 0) {
19391            doWakeKills = false;
19392        }
19393        if (mLastPowerCheckUptime == 0) {
19394            doCpuKills = false;
19395        }
19396        if (stats.isScreenOn()) {
19397            doWakeKills = false;
19398        }
19399        final long curRealtime = SystemClock.elapsedRealtime();
19400        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19401        final long curUptime = SystemClock.uptimeMillis();
19402        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19403        mLastPowerCheckRealtime = curRealtime;
19404        mLastPowerCheckUptime = curUptime;
19405        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19406            doWakeKills = false;
19407        }
19408        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19409            doCpuKills = false;
19410        }
19411        int i = mLruProcesses.size();
19412        while (i > 0) {
19413            i--;
19414            ProcessRecord app = mLruProcesses.get(i);
19415            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19416                long wtime;
19417                synchronized (stats) {
19418                    wtime = stats.getProcessWakeTime(app.info.uid,
19419                            app.pid, curRealtime);
19420                }
19421                long wtimeUsed = wtime - app.lastWakeTime;
19422                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19423                if (DEBUG_POWER) {
19424                    StringBuilder sb = new StringBuilder(128);
19425                    sb.append("Wake for ");
19426                    app.toShortString(sb);
19427                    sb.append(": over ");
19428                    TimeUtils.formatDuration(realtimeSince, sb);
19429                    sb.append(" used ");
19430                    TimeUtils.formatDuration(wtimeUsed, sb);
19431                    sb.append(" (");
19432                    sb.append((wtimeUsed*100)/realtimeSince);
19433                    sb.append("%)");
19434                    Slog.i(TAG_POWER, sb.toString());
19435                    sb.setLength(0);
19436                    sb.append("CPU for ");
19437                    app.toShortString(sb);
19438                    sb.append(": over ");
19439                    TimeUtils.formatDuration(uptimeSince, sb);
19440                    sb.append(" used ");
19441                    TimeUtils.formatDuration(cputimeUsed, sb);
19442                    sb.append(" (");
19443                    sb.append((cputimeUsed*100)/uptimeSince);
19444                    sb.append("%)");
19445                    Slog.i(TAG_POWER, sb.toString());
19446                }
19447                // If a process has held a wake lock for more
19448                // than 50% of the time during this period,
19449                // that sounds bad.  Kill!
19450                if (doWakeKills && realtimeSince > 0
19451                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19452                    synchronized (stats) {
19453                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19454                                realtimeSince, wtimeUsed);
19455                    }
19456                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19457                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19458                } else if (doCpuKills && uptimeSince > 0
19459                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19460                    synchronized (stats) {
19461                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19462                                uptimeSince, cputimeUsed);
19463                    }
19464                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19465                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19466                } else {
19467                    app.lastWakeTime = wtime;
19468                    app.lastCpuTime = app.curCpuTime;
19469                }
19470            }
19471        }
19472    }
19473
19474    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19475            long nowElapsed) {
19476        boolean success = true;
19477
19478        if (app.curRawAdj != app.setRawAdj) {
19479            app.setRawAdj = app.curRawAdj;
19480        }
19481
19482        int changes = 0;
19483
19484        if (app.curAdj != app.setAdj) {
19485            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19486            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19487                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19488                    + app.adjType);
19489            app.setAdj = app.curAdj;
19490        }
19491
19492        if (app.setSchedGroup != app.curSchedGroup) {
19493            app.setSchedGroup = app.curSchedGroup;
19494            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19495                    "Setting sched group of " + app.processName
19496                    + " to " + app.curSchedGroup);
19497            if (app.waitingToKill != null && app.curReceiver == null
19498                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19499                app.kill(app.waitingToKill, true);
19500                success = false;
19501            } else {
19502                int processGroup;
19503                switch (app.curSchedGroup) {
19504                    case ProcessList.SCHED_GROUP_BACKGROUND:
19505                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19506                        break;
19507                    case ProcessList.SCHED_GROUP_TOP_APP:
19508                        processGroup = Process.THREAD_GROUP_TOP_APP;
19509                        break;
19510                    default:
19511                        processGroup = Process.THREAD_GROUP_DEFAULT;
19512                        break;
19513                }
19514                if (true) {
19515                    long oldId = Binder.clearCallingIdentity();
19516                    try {
19517                        Process.setProcessGroup(app.pid, processGroup);
19518                    } catch (Exception e) {
19519                        Slog.w(TAG, "Failed setting process group of " + app.pid
19520                                + " to " + app.curSchedGroup);
19521                        e.printStackTrace();
19522                    } finally {
19523                        Binder.restoreCallingIdentity(oldId);
19524                    }
19525                } else {
19526                    if (app.thread != null) {
19527                        try {
19528                            app.thread.setSchedulingGroup(processGroup);
19529                        } catch (RemoteException e) {
19530                        }
19531                    }
19532                }
19533            }
19534        }
19535        if (app.repForegroundActivities != app.foregroundActivities) {
19536            app.repForegroundActivities = app.foregroundActivities;
19537            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19538        }
19539        if (app.repProcState != app.curProcState) {
19540            app.repProcState = app.curProcState;
19541            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19542            if (app.thread != null) {
19543                try {
19544                    if (false) {
19545                        //RuntimeException h = new RuntimeException("here");
19546                        Slog.i(TAG, "Sending new process state " + app.repProcState
19547                                + " to " + app /*, h*/);
19548                    }
19549                    app.thread.setProcessState(app.repProcState);
19550                } catch (RemoteException e) {
19551                }
19552            }
19553        }
19554        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19555                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19556            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19557                // Experimental code to more aggressively collect pss while
19558                // running test...  the problem is that this tends to collect
19559                // the data right when a process is transitioning between process
19560                // states, which well tend to give noisy data.
19561                long start = SystemClock.uptimeMillis();
19562                long pss = Debug.getPss(app.pid, mTmpLong, null);
19563                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19564                mPendingPssProcesses.remove(app);
19565                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19566                        + " to " + app.curProcState + ": "
19567                        + (SystemClock.uptimeMillis()-start) + "ms");
19568            }
19569            app.lastStateTime = now;
19570            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19571                    mTestPssMode, isSleeping(), now);
19572            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19573                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19574                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19575                    + (app.nextPssTime-now) + ": " + app);
19576        } else {
19577            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19578                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19579                    mTestPssMode)))) {
19580                requestPssLocked(app, app.setProcState);
19581                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19582                        mTestPssMode, isSleeping(), now);
19583            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19584                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19585        }
19586        if (app.setProcState != app.curProcState) {
19587            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19588                    "Proc state change of " + app.processName
19589                            + " to " + app.curProcState);
19590            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19591            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19592            if (setImportant && !curImportant) {
19593                // This app is no longer something we consider important enough to allow to
19594                // use arbitrary amounts of battery power.  Note
19595                // its current wake lock time to later know to kill it if
19596                // it is not behaving well.
19597                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19598                synchronized (stats) {
19599                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19600                            app.pid, nowElapsed);
19601                }
19602                app.lastCpuTime = app.curCpuTime;
19603
19604            }
19605            // Inform UsageStats of important process state change
19606            // Must be called before updating setProcState
19607            maybeUpdateUsageStatsLocked(app, nowElapsed);
19608
19609            app.setProcState = app.curProcState;
19610            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19611                app.notCachedSinceIdle = false;
19612            }
19613            if (!doingAll) {
19614                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19615            } else {
19616                app.procStateChanged = true;
19617            }
19618        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19619                > USAGE_STATS_INTERACTION_INTERVAL) {
19620            // For apps that sit around for a long time in the interactive state, we need
19621            // to report this at least once a day so they don't go idle.
19622            maybeUpdateUsageStatsLocked(app, nowElapsed);
19623        }
19624
19625        if (changes != 0) {
19626            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19627                    "Changes in " + app + ": " + changes);
19628            int i = mPendingProcessChanges.size()-1;
19629            ProcessChangeItem item = null;
19630            while (i >= 0) {
19631                item = mPendingProcessChanges.get(i);
19632                if (item.pid == app.pid) {
19633                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19634                            "Re-using existing item: " + item);
19635                    break;
19636                }
19637                i--;
19638            }
19639            if (i < 0) {
19640                // No existing item in pending changes; need a new one.
19641                final int NA = mAvailProcessChanges.size();
19642                if (NA > 0) {
19643                    item = mAvailProcessChanges.remove(NA-1);
19644                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19645                            "Retrieving available item: " + item);
19646                } else {
19647                    item = new ProcessChangeItem();
19648                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19649                            "Allocating new item: " + item);
19650                }
19651                item.changes = 0;
19652                item.pid = app.pid;
19653                item.uid = app.info.uid;
19654                if (mPendingProcessChanges.size() == 0) {
19655                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19656                            "*** Enqueueing dispatch processes changed!");
19657                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19658                }
19659                mPendingProcessChanges.add(item);
19660            }
19661            item.changes |= changes;
19662            item.processState = app.repProcState;
19663            item.foregroundActivities = app.repForegroundActivities;
19664            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19665                    "Item " + Integer.toHexString(System.identityHashCode(item))
19666                    + " " + app.toShortString() + ": changes=" + item.changes
19667                    + " procState=" + item.processState
19668                    + " foreground=" + item.foregroundActivities
19669                    + " type=" + app.adjType + " source=" + app.adjSource
19670                    + " target=" + app.adjTarget);
19671        }
19672
19673        return success;
19674    }
19675
19676    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19677        final UidRecord.ChangeItem pendingChange;
19678        if (uidRec == null || uidRec.pendingChange == null) {
19679            if (mPendingUidChanges.size() == 0) {
19680                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19681                        "*** Enqueueing dispatch uid changed!");
19682                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19683            }
19684            final int NA = mAvailUidChanges.size();
19685            if (NA > 0) {
19686                pendingChange = mAvailUidChanges.remove(NA-1);
19687                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19688                        "Retrieving available item: " + pendingChange);
19689            } else {
19690                pendingChange = new UidRecord.ChangeItem();
19691                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19692                        "Allocating new item: " + pendingChange);
19693            }
19694            if (uidRec != null) {
19695                uidRec.pendingChange = pendingChange;
19696                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19697                    // If this uid is going away, and we haven't yet reported it is gone,
19698                    // then do so now.
19699                    change = UidRecord.CHANGE_GONE_IDLE;
19700                }
19701            } else if (uid < 0) {
19702                throw new IllegalArgumentException("No UidRecord or uid");
19703            }
19704            pendingChange.uidRecord = uidRec;
19705            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19706            mPendingUidChanges.add(pendingChange);
19707        } else {
19708            pendingChange = uidRec.pendingChange;
19709            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19710                change = UidRecord.CHANGE_GONE_IDLE;
19711            }
19712        }
19713        pendingChange.change = change;
19714        pendingChange.processState = uidRec != null
19715                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19716    }
19717
19718    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19719            String authority) {
19720        if (app == null) return;
19721        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19722            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19723            if (userState == null) return;
19724            final long now = SystemClock.elapsedRealtime();
19725            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19726            if (lastReported == null || lastReported < now - 60 * 1000L) {
19727                mUsageStatsService.reportContentProviderUsage(
19728                        authority, providerPkgName, app.userId);
19729                userState.mProviderLastReportedFg.put(authority, now);
19730            }
19731        }
19732    }
19733
19734    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19735        if (DEBUG_USAGE_STATS) {
19736            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19737                    + "] state changes: old = " + app.setProcState + ", new = "
19738                    + app.curProcState);
19739        }
19740        if (mUsageStatsService == null) {
19741            return;
19742        }
19743        boolean isInteraction;
19744        // To avoid some abuse patterns, we are going to be careful about what we consider
19745        // to be an app interaction.  Being the top activity doesn't count while the display
19746        // is sleeping, nor do short foreground services.
19747        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19748            isInteraction = true;
19749            app.fgInteractionTime = 0;
19750        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19751            if (app.fgInteractionTime == 0) {
19752                app.fgInteractionTime = nowElapsed;
19753                isInteraction = false;
19754            } else {
19755                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19756            }
19757        } else {
19758            isInteraction = app.curProcState
19759                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19760            app.fgInteractionTime = 0;
19761        }
19762        if (isInteraction && (!app.reportedInteraction
19763                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19764            app.interactionEventTime = nowElapsed;
19765            String[] packages = app.getPackageList();
19766            if (packages != null) {
19767                for (int i = 0; i < packages.length; i++) {
19768                    mUsageStatsService.reportEvent(packages[i], app.userId,
19769                            UsageEvents.Event.SYSTEM_INTERACTION);
19770                }
19771            }
19772        }
19773        app.reportedInteraction = isInteraction;
19774        if (!isInteraction) {
19775            app.interactionEventTime = 0;
19776        }
19777    }
19778
19779    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19780        if (proc.thread != null) {
19781            if (proc.baseProcessTracker != null) {
19782                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19783            }
19784        }
19785    }
19786
19787    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19788            ProcessRecord TOP_APP, boolean doingAll, long now) {
19789        if (app.thread == null) {
19790            return false;
19791        }
19792
19793        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19794
19795        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19796    }
19797
19798    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19799            boolean oomAdj) {
19800        if (isForeground != proc.foregroundServices) {
19801            proc.foregroundServices = isForeground;
19802            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19803                    proc.info.uid);
19804            if (isForeground) {
19805                if (curProcs == null) {
19806                    curProcs = new ArrayList<ProcessRecord>();
19807                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19808                }
19809                if (!curProcs.contains(proc)) {
19810                    curProcs.add(proc);
19811                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19812                            proc.info.packageName, proc.info.uid);
19813                }
19814            } else {
19815                if (curProcs != null) {
19816                    if (curProcs.remove(proc)) {
19817                        mBatteryStatsService.noteEvent(
19818                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19819                                proc.info.packageName, proc.info.uid);
19820                        if (curProcs.size() <= 0) {
19821                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19822                        }
19823                    }
19824                }
19825            }
19826            if (oomAdj) {
19827                updateOomAdjLocked();
19828            }
19829        }
19830    }
19831
19832    private final ActivityRecord resumedAppLocked() {
19833        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19834        String pkg;
19835        int uid;
19836        if (act != null) {
19837            pkg = act.packageName;
19838            uid = act.info.applicationInfo.uid;
19839        } else {
19840            pkg = null;
19841            uid = -1;
19842        }
19843        // Has the UID or resumed package name changed?
19844        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19845                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19846            if (mCurResumedPackage != null) {
19847                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19848                        mCurResumedPackage, mCurResumedUid);
19849            }
19850            mCurResumedPackage = pkg;
19851            mCurResumedUid = uid;
19852            if (mCurResumedPackage != null) {
19853                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19854                        mCurResumedPackage, mCurResumedUid);
19855            }
19856        }
19857        return act;
19858    }
19859
19860    final boolean updateOomAdjLocked(ProcessRecord app) {
19861        final ActivityRecord TOP_ACT = resumedAppLocked();
19862        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19863        final boolean wasCached = app.cached;
19864
19865        mAdjSeq++;
19866
19867        // This is the desired cached adjusment we want to tell it to use.
19868        // If our app is currently cached, we know it, and that is it.  Otherwise,
19869        // we don't know it yet, and it needs to now be cached we will then
19870        // need to do a complete oom adj.
19871        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19872                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19873        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19874                SystemClock.uptimeMillis());
19875        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19876            // Changed to/from cached state, so apps after it in the LRU
19877            // list may also be changed.
19878            updateOomAdjLocked();
19879        }
19880        return success;
19881    }
19882
19883    final void updateOomAdjLocked() {
19884        final ActivityRecord TOP_ACT = resumedAppLocked();
19885        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19886        final long now = SystemClock.uptimeMillis();
19887        final long nowElapsed = SystemClock.elapsedRealtime();
19888        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19889        final int N = mLruProcesses.size();
19890
19891        if (false) {
19892            RuntimeException e = new RuntimeException();
19893            e.fillInStackTrace();
19894            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19895        }
19896
19897        // Reset state in all uid records.
19898        for (int i=mActiveUids.size()-1; i>=0; i--) {
19899            final UidRecord uidRec = mActiveUids.valueAt(i);
19900            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19901                    "Starting update of " + uidRec);
19902            uidRec.reset();
19903        }
19904
19905        mStackSupervisor.rankTaskLayersIfNeeded();
19906
19907        mAdjSeq++;
19908        mNewNumServiceProcs = 0;
19909        mNewNumAServiceProcs = 0;
19910
19911        final int emptyProcessLimit;
19912        final int cachedProcessLimit;
19913        if (mProcessLimit <= 0) {
19914            emptyProcessLimit = cachedProcessLimit = 0;
19915        } else if (mProcessLimit == 1) {
19916            emptyProcessLimit = 1;
19917            cachedProcessLimit = 0;
19918        } else {
19919            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19920            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19921        }
19922
19923        // Let's determine how many processes we have running vs.
19924        // how many slots we have for background processes; we may want
19925        // to put multiple processes in a slot of there are enough of
19926        // them.
19927        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19928                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19929        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19930        if (numEmptyProcs > cachedProcessLimit) {
19931            // If there are more empty processes than our limit on cached
19932            // processes, then use the cached process limit for the factor.
19933            // This ensures that the really old empty processes get pushed
19934            // down to the bottom, so if we are running low on memory we will
19935            // have a better chance at keeping around more cached processes
19936            // instead of a gazillion empty processes.
19937            numEmptyProcs = cachedProcessLimit;
19938        }
19939        int emptyFactor = numEmptyProcs/numSlots;
19940        if (emptyFactor < 1) emptyFactor = 1;
19941        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19942        if (cachedFactor < 1) cachedFactor = 1;
19943        int stepCached = 0;
19944        int stepEmpty = 0;
19945        int numCached = 0;
19946        int numEmpty = 0;
19947        int numTrimming = 0;
19948
19949        mNumNonCachedProcs = 0;
19950        mNumCachedHiddenProcs = 0;
19951
19952        // First update the OOM adjustment for each of the
19953        // application processes based on their current state.
19954        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19955        int nextCachedAdj = curCachedAdj+1;
19956        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19957        int nextEmptyAdj = curEmptyAdj+2;
19958        for (int i=N-1; i>=0; i--) {
19959            ProcessRecord app = mLruProcesses.get(i);
19960            if (!app.killedByAm && app.thread != null) {
19961                app.procStateChanged = false;
19962                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19963
19964                // If we haven't yet assigned the final cached adj
19965                // to the process, do that now.
19966                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19967                    switch (app.curProcState) {
19968                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19969                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19970                            // This process is a cached process holding activities...
19971                            // assign it the next cached value for that type, and then
19972                            // step that cached level.
19973                            app.curRawAdj = curCachedAdj;
19974                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19975                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19976                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19977                                    + ")");
19978                            if (curCachedAdj != nextCachedAdj) {
19979                                stepCached++;
19980                                if (stepCached >= cachedFactor) {
19981                                    stepCached = 0;
19982                                    curCachedAdj = nextCachedAdj;
19983                                    nextCachedAdj += 2;
19984                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19985                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19986                                    }
19987                                }
19988                            }
19989                            break;
19990                        default:
19991                            // For everything else, assign next empty cached process
19992                            // level and bump that up.  Note that this means that
19993                            // long-running services that have dropped down to the
19994                            // cached level will be treated as empty (since their process
19995                            // state is still as a service), which is what we want.
19996                            app.curRawAdj = curEmptyAdj;
19997                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19998                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19999                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20000                                    + ")");
20001                            if (curEmptyAdj != nextEmptyAdj) {
20002                                stepEmpty++;
20003                                if (stepEmpty >= emptyFactor) {
20004                                    stepEmpty = 0;
20005                                    curEmptyAdj = nextEmptyAdj;
20006                                    nextEmptyAdj += 2;
20007                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20008                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20009                                    }
20010                                }
20011                            }
20012                            break;
20013                    }
20014                }
20015
20016                applyOomAdjLocked(app, true, now, nowElapsed);
20017
20018                // Count the number of process types.
20019                switch (app.curProcState) {
20020                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20021                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20022                        mNumCachedHiddenProcs++;
20023                        numCached++;
20024                        if (numCached > cachedProcessLimit) {
20025                            app.kill("cached #" + numCached, true);
20026                        }
20027                        break;
20028                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20029                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20030                                && app.lastActivityTime < oldTime) {
20031                            app.kill("empty for "
20032                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20033                                    / 1000) + "s", true);
20034                        } else {
20035                            numEmpty++;
20036                            if (numEmpty > emptyProcessLimit) {
20037                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
20038                            }
20039                        }
20040                        break;
20041                    default:
20042                        mNumNonCachedProcs++;
20043                        break;
20044                }
20045
20046                if (app.isolated && app.services.size() <= 0) {
20047                    // If this is an isolated process, and there are no
20048                    // services running in it, then the process is no longer
20049                    // needed.  We agressively kill these because we can by
20050                    // definition not re-use the same process again, and it is
20051                    // good to avoid having whatever code was running in them
20052                    // left sitting around after no longer needed.
20053                    app.kill("isolated not needed", true);
20054                } else {
20055                    // Keeping this process, update its uid.
20056                    final UidRecord uidRec = app.uidRecord;
20057                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20058                        uidRec.curProcState = app.curProcState;
20059                    }
20060                }
20061
20062                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20063                        && !app.killedByAm) {
20064                    numTrimming++;
20065                }
20066            }
20067        }
20068
20069        mNumServiceProcs = mNewNumServiceProcs;
20070
20071        // Now determine the memory trimming level of background processes.
20072        // Unfortunately we need to start at the back of the list to do this
20073        // properly.  We only do this if the number of background apps we
20074        // are managing to keep around is less than half the maximum we desire;
20075        // if we are keeping a good number around, we'll let them use whatever
20076        // memory they want.
20077        final int numCachedAndEmpty = numCached + numEmpty;
20078        int memFactor;
20079        if (numCached <= ProcessList.TRIM_CACHED_APPS
20080                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20081            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20082                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20083            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20084                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20085            } else {
20086                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20087            }
20088        } else {
20089            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20090        }
20091        // We always allow the memory level to go up (better).  We only allow it to go
20092        // down if we are in a state where that is allowed, *and* the total number of processes
20093        // has gone down since last time.
20094        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20095                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20096                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20097        if (memFactor > mLastMemoryLevel) {
20098            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20099                memFactor = mLastMemoryLevel;
20100                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20101            }
20102        }
20103        mLastMemoryLevel = memFactor;
20104        mLastNumProcesses = mLruProcesses.size();
20105        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20106        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20107        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20108            if (mLowRamStartTime == 0) {
20109                mLowRamStartTime = now;
20110            }
20111            int step = 0;
20112            int fgTrimLevel;
20113            switch (memFactor) {
20114                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20115                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20116                    break;
20117                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20118                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20119                    break;
20120                default:
20121                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20122                    break;
20123            }
20124            int factor = numTrimming/3;
20125            int minFactor = 2;
20126            if (mHomeProcess != null) minFactor++;
20127            if (mPreviousProcess != null) minFactor++;
20128            if (factor < minFactor) factor = minFactor;
20129            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20130            for (int i=N-1; i>=0; i--) {
20131                ProcessRecord app = mLruProcesses.get(i);
20132                if (allChanged || app.procStateChanged) {
20133                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20134                    app.procStateChanged = false;
20135                }
20136                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20137                        && !app.killedByAm) {
20138                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20139                        try {
20140                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20141                                    "Trimming memory of " + app.processName + " to " + curLevel);
20142                            app.thread.scheduleTrimMemory(curLevel);
20143                        } catch (RemoteException e) {
20144                        }
20145                        if (false) {
20146                            // For now we won't do this; our memory trimming seems
20147                            // to be good enough at this point that destroying
20148                            // activities causes more harm than good.
20149                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20150                                    && app != mHomeProcess && app != mPreviousProcess) {
20151                                // Need to do this on its own message because the stack may not
20152                                // be in a consistent state at this point.
20153                                // For these apps we will also finish their activities
20154                                // to help them free memory.
20155                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20156                            }
20157                        }
20158                    }
20159                    app.trimMemoryLevel = curLevel;
20160                    step++;
20161                    if (step >= factor) {
20162                        step = 0;
20163                        switch (curLevel) {
20164                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20165                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20166                                break;
20167                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20168                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20169                                break;
20170                        }
20171                    }
20172                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20173                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20174                            && app.thread != null) {
20175                        try {
20176                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20177                                    "Trimming memory of heavy-weight " + app.processName
20178                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20179                            app.thread.scheduleTrimMemory(
20180                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20181                        } catch (RemoteException e) {
20182                        }
20183                    }
20184                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20185                } else {
20186                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20187                            || app.systemNoUi) && app.pendingUiClean) {
20188                        // If this application is now in the background and it
20189                        // had done UI, then give it the special trim level to
20190                        // have it free UI resources.
20191                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20192                        if (app.trimMemoryLevel < level && app.thread != null) {
20193                            try {
20194                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20195                                        "Trimming memory of bg-ui " + app.processName
20196                                        + " to " + level);
20197                                app.thread.scheduleTrimMemory(level);
20198                            } catch (RemoteException e) {
20199                            }
20200                        }
20201                        app.pendingUiClean = false;
20202                    }
20203                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20204                        try {
20205                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20206                                    "Trimming memory of fg " + app.processName
20207                                    + " to " + fgTrimLevel);
20208                            app.thread.scheduleTrimMemory(fgTrimLevel);
20209                        } catch (RemoteException e) {
20210                        }
20211                    }
20212                    app.trimMemoryLevel = fgTrimLevel;
20213                }
20214            }
20215        } else {
20216            if (mLowRamStartTime != 0) {
20217                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20218                mLowRamStartTime = 0;
20219            }
20220            for (int i=N-1; i>=0; i--) {
20221                ProcessRecord app = mLruProcesses.get(i);
20222                if (allChanged || app.procStateChanged) {
20223                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20224                    app.procStateChanged = false;
20225                }
20226                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20227                        || app.systemNoUi) && app.pendingUiClean) {
20228                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20229                            && app.thread != null) {
20230                        try {
20231                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20232                                    "Trimming memory of ui hidden " + app.processName
20233                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20234                            app.thread.scheduleTrimMemory(
20235                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20236                        } catch (RemoteException e) {
20237                        }
20238                    }
20239                    app.pendingUiClean = false;
20240                }
20241                app.trimMemoryLevel = 0;
20242            }
20243        }
20244
20245        if (mAlwaysFinishActivities) {
20246            // Need to do this on its own message because the stack may not
20247            // be in a consistent state at this point.
20248            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20249        }
20250
20251        if (allChanged) {
20252            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20253        }
20254
20255        // Update from any uid changes.
20256        for (int i=mActiveUids.size()-1; i>=0; i--) {
20257            final UidRecord uidRec = mActiveUids.valueAt(i);
20258            int uidChange = UidRecord.CHANGE_PROCSTATE;
20259            if (uidRec.setProcState != uidRec.curProcState) {
20260                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20261                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20262                        + " to " + uidRec.curProcState);
20263                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20264                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20265                        uidRec.lastBackgroundTime = nowElapsed;
20266                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20267                            // Note: the background settle time is in elapsed realtime, while
20268                            // the handler time base is uptime.  All this means is that we may
20269                            // stop background uids later than we had intended, but that only
20270                            // happens because the device was sleeping so we are okay anyway.
20271                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20272                        }
20273                    }
20274                } else {
20275                    if (uidRec.idle) {
20276                        uidChange = UidRecord.CHANGE_ACTIVE;
20277                        uidRec.idle = false;
20278                    }
20279                    uidRec.lastBackgroundTime = 0;
20280                }
20281                uidRec.setProcState = uidRec.curProcState;
20282                enqueueUidChangeLocked(uidRec, -1, uidChange);
20283                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20284            }
20285        }
20286
20287        if (mProcessStats.shouldWriteNowLocked(now)) {
20288            mHandler.post(new Runnable() {
20289                @Override public void run() {
20290                    synchronized (ActivityManagerService.this) {
20291                        mProcessStats.writeStateAsyncLocked();
20292                    }
20293                }
20294            });
20295        }
20296
20297        if (DEBUG_OOM_ADJ) {
20298            final long duration = SystemClock.uptimeMillis() - now;
20299            if (false) {
20300                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20301                        new RuntimeException("here").fillInStackTrace());
20302            } else {
20303                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20304            }
20305        }
20306    }
20307
20308    final void idleUids() {
20309        synchronized (this) {
20310            final long nowElapsed = SystemClock.elapsedRealtime();
20311            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20312            long nextTime = 0;
20313            for (int i=mActiveUids.size()-1; i>=0; i--) {
20314                final UidRecord uidRec = mActiveUids.valueAt(i);
20315                final long bgTime = uidRec.lastBackgroundTime;
20316                if (bgTime > 0 && !uidRec.idle) {
20317                    if (bgTime <= maxBgTime) {
20318                        uidRec.idle = true;
20319                        doStopUidLocked(uidRec.uid, uidRec);
20320                    } else {
20321                        if (nextTime == 0 || nextTime > bgTime) {
20322                            nextTime = bgTime;
20323                        }
20324                    }
20325                }
20326            }
20327            if (nextTime > 0) {
20328                mHandler.removeMessages(IDLE_UIDS_MSG);
20329                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20330                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20331            }
20332        }
20333    }
20334
20335    final void runInBackgroundDisabled(int uid) {
20336        synchronized (this) {
20337            UidRecord uidRec = mActiveUids.get(uid);
20338            if (uidRec != null) {
20339                // This uid is actually running...  should it be considered background now?
20340                if (uidRec.idle) {
20341                    doStopUidLocked(uidRec.uid, uidRec);
20342                }
20343            } else {
20344                // This uid isn't actually running...  still send a report about it being "stopped".
20345                doStopUidLocked(uid, null);
20346            }
20347        }
20348    }
20349
20350    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20351        mServices.stopInBackgroundLocked(uid);
20352        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20353    }
20354
20355    final void trimApplications() {
20356        synchronized (this) {
20357            int i;
20358
20359            // First remove any unused application processes whose package
20360            // has been removed.
20361            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20362                final ProcessRecord app = mRemovedProcesses.get(i);
20363                if (app.activities.size() == 0
20364                        && app.curReceiver == null && app.services.size() == 0) {
20365                    Slog.i(
20366                        TAG, "Exiting empty application process "
20367                        + app.processName + " ("
20368                        + (app.thread != null ? app.thread.asBinder() : null)
20369                        + ")\n");
20370                    if (app.pid > 0 && app.pid != MY_PID) {
20371                        app.kill("empty", false);
20372                    } else {
20373                        try {
20374                            app.thread.scheduleExit();
20375                        } catch (Exception e) {
20376                            // Ignore exceptions.
20377                        }
20378                    }
20379                    cleanUpApplicationRecordLocked(app, false, true, -1);
20380                    mRemovedProcesses.remove(i);
20381
20382                    if (app.persistent) {
20383                        addAppLocked(app.info, false, null /* ABI override */);
20384                    }
20385                }
20386            }
20387
20388            // Now update the oom adj for all processes.
20389            updateOomAdjLocked();
20390        }
20391    }
20392
20393    /** This method sends the specified signal to each of the persistent apps */
20394    public void signalPersistentProcesses(int sig) throws RemoteException {
20395        if (sig != Process.SIGNAL_USR1) {
20396            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20397        }
20398
20399        synchronized (this) {
20400            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20401                    != PackageManager.PERMISSION_GRANTED) {
20402                throw new SecurityException("Requires permission "
20403                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20404            }
20405
20406            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20407                ProcessRecord r = mLruProcesses.get(i);
20408                if (r.thread != null && r.persistent) {
20409                    Process.sendSignal(r.pid, sig);
20410                }
20411            }
20412        }
20413    }
20414
20415    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20416        if (proc == null || proc == mProfileProc) {
20417            proc = mProfileProc;
20418            profileType = mProfileType;
20419            clearProfilerLocked();
20420        }
20421        if (proc == null) {
20422            return;
20423        }
20424        try {
20425            proc.thread.profilerControl(false, null, profileType);
20426        } catch (RemoteException e) {
20427            throw new IllegalStateException("Process disappeared");
20428        }
20429    }
20430
20431    private void clearProfilerLocked() {
20432        if (mProfileFd != null) {
20433            try {
20434                mProfileFd.close();
20435            } catch (IOException e) {
20436            }
20437        }
20438        mProfileApp = null;
20439        mProfileProc = null;
20440        mProfileFile = null;
20441        mProfileType = 0;
20442        mAutoStopProfiler = false;
20443        mSamplingInterval = 0;
20444    }
20445
20446    public boolean profileControl(String process, int userId, boolean start,
20447            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20448
20449        try {
20450            synchronized (this) {
20451                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20452                // its own permission.
20453                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20454                        != PackageManager.PERMISSION_GRANTED) {
20455                    throw new SecurityException("Requires permission "
20456                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20457                }
20458
20459                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20460                    throw new IllegalArgumentException("null profile info or fd");
20461                }
20462
20463                ProcessRecord proc = null;
20464                if (process != null) {
20465                    proc = findProcessLocked(process, userId, "profileControl");
20466                }
20467
20468                if (start && (proc == null || proc.thread == null)) {
20469                    throw new IllegalArgumentException("Unknown process: " + process);
20470                }
20471
20472                if (start) {
20473                    stopProfilerLocked(null, 0);
20474                    setProfileApp(proc.info, proc.processName, profilerInfo);
20475                    mProfileProc = proc;
20476                    mProfileType = profileType;
20477                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20478                    try {
20479                        fd = fd.dup();
20480                    } catch (IOException e) {
20481                        fd = null;
20482                    }
20483                    profilerInfo.profileFd = fd;
20484                    proc.thread.profilerControl(start, profilerInfo, profileType);
20485                    fd = null;
20486                    mProfileFd = null;
20487                } else {
20488                    stopProfilerLocked(proc, profileType);
20489                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20490                        try {
20491                            profilerInfo.profileFd.close();
20492                        } catch (IOException e) {
20493                        }
20494                    }
20495                }
20496
20497                return true;
20498            }
20499        } catch (RemoteException e) {
20500            throw new IllegalStateException("Process disappeared");
20501        } finally {
20502            if (profilerInfo != null && profilerInfo.profileFd != null) {
20503                try {
20504                    profilerInfo.profileFd.close();
20505                } catch (IOException e) {
20506                }
20507            }
20508        }
20509    }
20510
20511    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20512        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20513                userId, true, ALLOW_FULL_ONLY, callName, null);
20514        ProcessRecord proc = null;
20515        try {
20516            int pid = Integer.parseInt(process);
20517            synchronized (mPidsSelfLocked) {
20518                proc = mPidsSelfLocked.get(pid);
20519            }
20520        } catch (NumberFormatException e) {
20521        }
20522
20523        if (proc == null) {
20524            ArrayMap<String, SparseArray<ProcessRecord>> all
20525                    = mProcessNames.getMap();
20526            SparseArray<ProcessRecord> procs = all.get(process);
20527            if (procs != null && procs.size() > 0) {
20528                proc = procs.valueAt(0);
20529                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20530                    for (int i=1; i<procs.size(); i++) {
20531                        ProcessRecord thisProc = procs.valueAt(i);
20532                        if (thisProc.userId == userId) {
20533                            proc = thisProc;
20534                            break;
20535                        }
20536                    }
20537                }
20538            }
20539        }
20540
20541        return proc;
20542    }
20543
20544    public boolean dumpHeap(String process, int userId, boolean managed,
20545            String path, ParcelFileDescriptor fd) throws RemoteException {
20546
20547        try {
20548            synchronized (this) {
20549                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20550                // its own permission (same as profileControl).
20551                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20552                        != PackageManager.PERMISSION_GRANTED) {
20553                    throw new SecurityException("Requires permission "
20554                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20555                }
20556
20557                if (fd == null) {
20558                    throw new IllegalArgumentException("null fd");
20559                }
20560
20561                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20562                if (proc == null || proc.thread == null) {
20563                    throw new IllegalArgumentException("Unknown process: " + process);
20564                }
20565
20566                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20567                if (!isDebuggable) {
20568                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20569                        throw new SecurityException("Process not debuggable: " + proc);
20570                    }
20571                }
20572
20573                proc.thread.dumpHeap(managed, path, fd);
20574                fd = null;
20575                return true;
20576            }
20577        } catch (RemoteException e) {
20578            throw new IllegalStateException("Process disappeared");
20579        } finally {
20580            if (fd != null) {
20581                try {
20582                    fd.close();
20583                } catch (IOException e) {
20584                }
20585            }
20586        }
20587    }
20588
20589    @Override
20590    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20591            String reportPackage) {
20592        if (processName != null) {
20593            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20594                    "setDumpHeapDebugLimit()");
20595        } else {
20596            synchronized (mPidsSelfLocked) {
20597                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20598                if (proc == null) {
20599                    throw new SecurityException("No process found for calling pid "
20600                            + Binder.getCallingPid());
20601                }
20602                if (!Build.IS_DEBUGGABLE
20603                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20604                    throw new SecurityException("Not running a debuggable build");
20605                }
20606                processName = proc.processName;
20607                uid = proc.uid;
20608                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20609                    throw new SecurityException("Package " + reportPackage + " is not running in "
20610                            + proc);
20611                }
20612            }
20613        }
20614        synchronized (this) {
20615            if (maxMemSize > 0) {
20616                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20617            } else {
20618                if (uid != 0) {
20619                    mMemWatchProcesses.remove(processName, uid);
20620                } else {
20621                    mMemWatchProcesses.getMap().remove(processName);
20622                }
20623            }
20624        }
20625    }
20626
20627    @Override
20628    public void dumpHeapFinished(String path) {
20629        synchronized (this) {
20630            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20631                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20632                        + " does not match last pid " + mMemWatchDumpPid);
20633                return;
20634            }
20635            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20636                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20637                        + " does not match last path " + mMemWatchDumpFile);
20638                return;
20639            }
20640            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20641            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20642        }
20643    }
20644
20645    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20646    public void monitor() {
20647        synchronized (this) { }
20648    }
20649
20650    void onCoreSettingsChange(Bundle settings) {
20651        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20652            ProcessRecord processRecord = mLruProcesses.get(i);
20653            try {
20654                if (processRecord.thread != null) {
20655                    processRecord.thread.setCoreSettings(settings);
20656                }
20657            } catch (RemoteException re) {
20658                /* ignore */
20659            }
20660        }
20661    }
20662
20663    // Multi-user methods
20664
20665    /**
20666     * Start user, if its not already running, but don't bring it to foreground.
20667     */
20668    @Override
20669    public boolean startUserInBackground(final int userId) {
20670        return mUserController.startUser(userId, /* foreground */ false);
20671    }
20672
20673    @Override
20674    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20675        return mUserController.unlockUser(userId, token, secret, new ProgressReporter(0, listener));
20676    }
20677
20678    @Override
20679    public boolean switchUser(final int targetUserId) {
20680        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20681        UserInfo currentUserInfo;
20682        UserInfo targetUserInfo;
20683        synchronized (this) {
20684            int currentUserId = mUserController.getCurrentUserIdLocked();
20685            currentUserInfo = mUserController.getUserInfo(currentUserId);
20686            targetUserInfo = mUserController.getUserInfo(targetUserId);
20687            if (targetUserInfo == null) {
20688                Slog.w(TAG, "No user info for user #" + targetUserId);
20689                return false;
20690            }
20691            if (!targetUserInfo.supportsSwitchTo()) {
20692                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20693                return false;
20694            }
20695            if (targetUserInfo.isManagedProfile()) {
20696                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20697                return false;
20698            }
20699            mUserController.setTargetUserIdLocked(targetUserId);
20700        }
20701        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20702        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20703        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20704        return true;
20705    }
20706
20707    void scheduleStartProfilesLocked() {
20708        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20709            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20710                    DateUtils.SECOND_IN_MILLIS);
20711        }
20712    }
20713
20714    @Override
20715    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20716        return mUserController.stopUser(userId, force, callback);
20717    }
20718
20719    @Override
20720    public UserInfo getCurrentUser() {
20721        return mUserController.getCurrentUser();
20722    }
20723
20724    @Override
20725    public boolean isUserRunning(int userId, int flags) {
20726        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20727                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20728            String msg = "Permission Denial: isUserRunning() from pid="
20729                    + Binder.getCallingPid()
20730                    + ", uid=" + Binder.getCallingUid()
20731                    + " requires " + INTERACT_ACROSS_USERS;
20732            Slog.w(TAG, msg);
20733            throw new SecurityException(msg);
20734        }
20735        synchronized (this) {
20736            return mUserController.isUserRunningLocked(userId, flags);
20737        }
20738    }
20739
20740    @Override
20741    public int[] getRunningUserIds() {
20742        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20743                != PackageManager.PERMISSION_GRANTED) {
20744            String msg = "Permission Denial: isUserRunning() from pid="
20745                    + Binder.getCallingPid()
20746                    + ", uid=" + Binder.getCallingUid()
20747                    + " requires " + INTERACT_ACROSS_USERS;
20748            Slog.w(TAG, msg);
20749            throw new SecurityException(msg);
20750        }
20751        synchronized (this) {
20752            return mUserController.getStartedUserArrayLocked();
20753        }
20754    }
20755
20756    @Override
20757    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20758        mUserController.registerUserSwitchObserver(observer);
20759    }
20760
20761    @Override
20762    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20763        mUserController.unregisterUserSwitchObserver(observer);
20764    }
20765
20766    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20767        if (info == null) return null;
20768        ApplicationInfo newInfo = new ApplicationInfo(info);
20769        newInfo.initForUser(userId);
20770        return newInfo;
20771    }
20772
20773    public boolean isUserStopped(int userId) {
20774        synchronized (this) {
20775            return mUserController.getStartedUserStateLocked(userId) == null;
20776        }
20777    }
20778
20779    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20780        if (aInfo == null
20781                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20782            return aInfo;
20783        }
20784
20785        ActivityInfo info = new ActivityInfo(aInfo);
20786        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20787        return info;
20788    }
20789
20790    private boolean processSanityChecksLocked(ProcessRecord process) {
20791        if (process == null || process.thread == null) {
20792            return false;
20793        }
20794
20795        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20796        if (!isDebuggable) {
20797            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20798                return false;
20799            }
20800        }
20801
20802        return true;
20803    }
20804
20805    public boolean startBinderTracking() throws RemoteException {
20806        synchronized (this) {
20807            mBinderTransactionTrackingEnabled = true;
20808            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20809            // permission (same as profileControl).
20810            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20811                    != PackageManager.PERMISSION_GRANTED) {
20812                throw new SecurityException("Requires permission "
20813                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20814            }
20815
20816            for (int i = 0; i < mLruProcesses.size(); i++) {
20817                ProcessRecord process = mLruProcesses.get(i);
20818                if (!processSanityChecksLocked(process)) {
20819                    continue;
20820                }
20821                try {
20822                    process.thread.startBinderTracking();
20823                } catch (RemoteException e) {
20824                    Log.v(TAG, "Process disappared");
20825                }
20826            }
20827            return true;
20828        }
20829    }
20830
20831    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20832        try {
20833            synchronized (this) {
20834                mBinderTransactionTrackingEnabled = false;
20835                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20836                // permission (same as profileControl).
20837                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20838                        != PackageManager.PERMISSION_GRANTED) {
20839                    throw new SecurityException("Requires permission "
20840                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20841                }
20842
20843                if (fd == null) {
20844                    throw new IllegalArgumentException("null fd");
20845                }
20846
20847                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20848                pw.println("Binder transaction traces for all processes.\n");
20849                for (ProcessRecord process : mLruProcesses) {
20850                    if (!processSanityChecksLocked(process)) {
20851                        continue;
20852                    }
20853
20854                    pw.println("Traces for process: " + process.processName);
20855                    pw.flush();
20856                    try {
20857                        TransferPipe tp = new TransferPipe();
20858                        try {
20859                            process.thread.stopBinderTrackingAndDump(
20860                                    tp.getWriteFd().getFileDescriptor());
20861                            tp.go(fd.getFileDescriptor());
20862                        } finally {
20863                            tp.kill();
20864                        }
20865                    } catch (IOException e) {
20866                        pw.println("Failure while dumping IPC traces from " + process +
20867                                ".  Exception: " + e);
20868                        pw.flush();
20869                    } catch (RemoteException e) {
20870                        pw.println("Got a RemoteException while dumping IPC traces from " +
20871                                process + ".  Exception: " + e);
20872                        pw.flush();
20873                    }
20874                }
20875                fd = null;
20876                return true;
20877            }
20878        } finally {
20879            if (fd != null) {
20880                try {
20881                    fd.close();
20882                } catch (IOException e) {
20883                }
20884            }
20885        }
20886    }
20887
20888    private final class LocalService extends ActivityManagerInternal {
20889        @Override
20890        public void onWakefulnessChanged(int wakefulness) {
20891            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20892        }
20893
20894        @Override
20895        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20896                String processName, String abiOverride, int uid, Runnable crashHandler) {
20897            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20898                    processName, abiOverride, uid, crashHandler);
20899        }
20900
20901        @Override
20902        public SleepToken acquireSleepToken(String tag) {
20903            Preconditions.checkNotNull(tag);
20904
20905            synchronized (ActivityManagerService.this) {
20906                SleepTokenImpl token = new SleepTokenImpl(tag);
20907                mSleepTokens.add(token);
20908                updateSleepIfNeededLocked();
20909                return token;
20910            }
20911        }
20912
20913        @Override
20914        public ComponentName getHomeActivityForUser(int userId) {
20915            synchronized (ActivityManagerService.this) {
20916                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20917                return homeActivity == null ? null : homeActivity.realActivity;
20918            }
20919        }
20920
20921        @Override
20922        public void onUserRemoved(int userId) {
20923            synchronized (ActivityManagerService.this) {
20924                ActivityManagerService.this.onUserStoppedLocked(userId);
20925            }
20926        }
20927
20928        @Override
20929        public void onLocalVoiceInteractionStarted(IBinder activity,
20930                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20931            synchronized (ActivityManagerService.this) {
20932                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20933                        voiceSession, voiceInteractor);
20934            }
20935        }
20936
20937        @Override
20938        public void notifyStartingWindowDrawn() {
20939            synchronized (ActivityManagerService.this) {
20940                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20941            }
20942        }
20943
20944        @Override
20945        public void notifyAppTransitionStarting(int reason) {
20946            synchronized (ActivityManagerService.this) {
20947                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20948            }
20949        }
20950
20951        @Override
20952        public void notifyAppTransitionFinished() {
20953            synchronized (ActivityManagerService.this) {
20954                mStackSupervisor.notifyAppTransitionDone();
20955            }
20956        }
20957
20958        @Override
20959        public void notifyAppTransitionCancelled() {
20960            synchronized (ActivityManagerService.this) {
20961                mStackSupervisor.notifyAppTransitionDone();
20962            }
20963        }
20964    }
20965
20966    private final class SleepTokenImpl extends SleepToken {
20967        private final String mTag;
20968        private final long mAcquireTime;
20969
20970        public SleepTokenImpl(String tag) {
20971            mTag = tag;
20972            mAcquireTime = SystemClock.uptimeMillis();
20973        }
20974
20975        @Override
20976        public void release() {
20977            synchronized (ActivityManagerService.this) {
20978                if (mSleepTokens.remove(this)) {
20979                    updateSleepIfNeededLocked();
20980                }
20981            }
20982        }
20983
20984        @Override
20985        public String toString() {
20986            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20987        }
20988    }
20989
20990    /**
20991     * An implementation of IAppTask, that allows an app to manage its own tasks via
20992     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20993     * only the process that calls getAppTasks() can call the AppTask methods.
20994     */
20995    class AppTaskImpl extends IAppTask.Stub {
20996        private int mTaskId;
20997        private int mCallingUid;
20998
20999        public AppTaskImpl(int taskId, int callingUid) {
21000            mTaskId = taskId;
21001            mCallingUid = callingUid;
21002        }
21003
21004        private void checkCaller() {
21005            if (mCallingUid != Binder.getCallingUid()) {
21006                throw new SecurityException("Caller " + mCallingUid
21007                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21008            }
21009        }
21010
21011        @Override
21012        public void finishAndRemoveTask() {
21013            checkCaller();
21014
21015            synchronized (ActivityManagerService.this) {
21016                long origId = Binder.clearCallingIdentity();
21017                try {
21018                    // We remove the task from recents to preserve backwards
21019                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21020                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21021                    }
21022                } finally {
21023                    Binder.restoreCallingIdentity(origId);
21024                }
21025            }
21026        }
21027
21028        @Override
21029        public ActivityManager.RecentTaskInfo getTaskInfo() {
21030            checkCaller();
21031
21032            synchronized (ActivityManagerService.this) {
21033                long origId = Binder.clearCallingIdentity();
21034                try {
21035                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21036                    if (tr == null) {
21037                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21038                    }
21039                    return createRecentTaskInfoFromTaskRecord(tr);
21040                } finally {
21041                    Binder.restoreCallingIdentity(origId);
21042                }
21043            }
21044        }
21045
21046        @Override
21047        public void moveToFront() {
21048            checkCaller();
21049            // Will bring task to front if it already has a root activity.
21050            final long origId = Binder.clearCallingIdentity();
21051            try {
21052                synchronized (this) {
21053                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21054                }
21055            } finally {
21056                Binder.restoreCallingIdentity(origId);
21057            }
21058        }
21059
21060        @Override
21061        public int startActivity(IBinder whoThread, String callingPackage,
21062                Intent intent, String resolvedType, Bundle bOptions) {
21063            checkCaller();
21064
21065            int callingUser = UserHandle.getCallingUserId();
21066            TaskRecord tr;
21067            IApplicationThread appThread;
21068            synchronized (ActivityManagerService.this) {
21069                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21070                if (tr == null) {
21071                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21072                }
21073                appThread = ApplicationThreadNative.asInterface(whoThread);
21074                if (appThread == null) {
21075                    throw new IllegalArgumentException("Bad app thread " + appThread);
21076                }
21077            }
21078            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21079                    resolvedType, null, null, null, null, 0, 0, null, null,
21080                    null, bOptions, false, callingUser, null, tr);
21081        }
21082
21083        @Override
21084        public void setExcludeFromRecents(boolean exclude) {
21085            checkCaller();
21086
21087            synchronized (ActivityManagerService.this) {
21088                long origId = Binder.clearCallingIdentity();
21089                try {
21090                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21091                    if (tr == null) {
21092                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21093                    }
21094                    Intent intent = tr.getBaseIntent();
21095                    if (exclude) {
21096                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21097                    } else {
21098                        intent.setFlags(intent.getFlags()
21099                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21100                    }
21101                } finally {
21102                    Binder.restoreCallingIdentity(origId);
21103                }
21104            }
21105        }
21106    }
21107
21108    /**
21109     * Kill processes for the user with id userId and that depend on the package named packageName
21110     */
21111    @Override
21112    public void killPackageDependents(String packageName, int userId) {
21113        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21114        if (packageName == null) {
21115            throw new NullPointerException(
21116                    "Cannot kill the dependents of a package without its name.");
21117        }
21118
21119        long callingId = Binder.clearCallingIdentity();
21120        IPackageManager pm = AppGlobals.getPackageManager();
21121        int pkgUid = -1;
21122        try {
21123            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21124        } catch (RemoteException e) {
21125        }
21126        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21127            throw new IllegalArgumentException(
21128                    "Cannot kill dependents of non-existing package " + packageName);
21129        }
21130        try {
21131            synchronized(this) {
21132                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21133                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21134                        "dep: " + packageName);
21135            }
21136        } finally {
21137            Binder.restoreCallingIdentity(callingId);
21138        }
21139    }
21140}
21141