ActivityManagerService.java revision dd5222d3148600e63652f3a265b879d61adc31f6
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.google.android.collect.Lists;
20import com.google.android.collect.Maps;
21import com.android.internal.R;
22import com.android.internal.annotations.GuardedBy;
23import com.android.internal.app.AssistUtils;
24import com.android.internal.app.DumpHeapActivity;
25import com.android.internal.app.IAppOpsCallback;
26import com.android.internal.app.IAppOpsService;
27import com.android.internal.app.IVoiceInteractor;
28import com.android.internal.app.ProcessMap;
29import com.android.internal.app.SystemUserHomeActivity;
30import com.android.internal.app.procstats.ProcessStats;
31import com.android.internal.os.BackgroundThread;
32import com.android.internal.os.BatteryStatsImpl;
33import com.android.internal.os.IResultReceiver;
34import com.android.internal.os.ProcessCpuTracker;
35import com.android.internal.os.TransferPipe;
36import com.android.internal.os.Zygote;
37import com.android.internal.os.InstallerConnection.InstallerException;
38import com.android.internal.util.ArrayUtils;
39import com.android.internal.util.FastPrintWriter;
40import com.android.internal.util.FastXmlSerializer;
41import com.android.internal.util.MemInfoReader;
42import com.android.internal.util.Preconditions;
43import com.android.internal.util.ProgressReporter;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.KeyguardManager;
101import android.app.Notification;
102import android.app.NotificationManager;
103import android.app.PendingIntent;
104import android.app.ProfilerInfo;
105import android.app.admin.DevicePolicyManager;
106import android.app.admin.DevicePolicyManagerInternal;
107import android.app.assist.AssistContent;
108import android.app.assist.AssistStructure;
109import android.app.backup.IBackupManager;
110import android.app.usage.UsageEvents;
111import android.app.usage.UsageStatsManagerInternal;
112import android.appwidget.AppWidgetManager;
113import android.content.ActivityNotFoundException;
114import android.content.BroadcastReceiver;
115import android.content.ClipData;
116import android.content.ComponentCallbacks2;
117import android.content.ComponentName;
118import android.content.ContentProvider;
119import android.content.ContentResolver;
120import android.content.Context;
121import android.content.DialogInterface;
122import android.content.IContentProvider;
123import android.content.IIntentReceiver;
124import android.content.IIntentSender;
125import android.content.Intent;
126import android.content.IntentFilter;
127import android.content.IntentSender;
128import android.content.pm.ActivityInfo;
129import android.content.pm.ApplicationInfo;
130import android.content.pm.ConfigurationInfo;
131import android.content.pm.IPackageDataObserver;
132import android.content.pm.IPackageManager;
133import android.content.pm.InstrumentationInfo;
134import android.content.pm.PackageInfo;
135import android.content.pm.PackageManager;
136import android.content.pm.PackageManager.NameNotFoundException;
137import android.content.pm.PackageManagerInternal;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.PathPermission;
140import android.content.pm.PermissionInfo;
141import android.content.pm.ProviderInfo;
142import android.content.pm.ResolveInfo;
143import android.content.pm.ServiceInfo;
144import android.content.pm.UserInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.content.res.Resources;
148import android.database.ContentObserver;
149import android.graphics.Bitmap;
150import android.graphics.Point;
151import android.graphics.Rect;
152import android.location.LocationManager;
153import android.net.Proxy;
154import android.net.ProxyInfo;
155import android.net.Uri;
156import android.os.BatteryStats;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IProcessInfoService;
170import android.os.IProgressListener;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.PersistableBundle;
176import android.os.PowerManager;
177import android.os.PowerManagerInternal;
178import android.os.Process;
179import android.os.RemoteCallbackList;
180import android.os.RemoteException;
181import android.os.ResultReceiver;
182import android.os.ServiceManager;
183import android.os.StrictMode;
184import android.os.SystemClock;
185import android.os.SystemProperties;
186import android.os.Trace;
187import android.os.TransactionTooLargeException;
188import android.os.UpdateLock;
189import android.os.UserHandle;
190import android.os.UserManager;
191import android.os.WorkSource;
192import android.os.storage.IMountService;
193import android.os.storage.MountServiceInternal;
194import android.os.storage.StorageManager;
195import android.provider.Settings;
196import android.service.voice.IVoiceInteractionSession;
197import android.service.voice.VoiceInteractionManagerInternal;
198import android.service.voice.VoiceInteractionSession;
199import android.text.format.DateUtils;
200import android.text.format.Time;
201import android.util.ArrayMap;
202import android.util.ArraySet;
203import android.util.AtomicFile;
204import android.util.DebugUtils;
205import android.util.EventLog;
206import android.util.LocaleList;
207import android.util.Log;
208import android.util.Pair;
209import android.util.PrintWriterPrinter;
210import android.util.Slog;
211import android.util.SparseArray;
212import android.util.TimeUtils;
213import android.util.Xml;
214import android.view.Display;
215import android.view.Gravity;
216import android.view.LayoutInflater;
217import android.view.View;
218import android.view.WindowManager;
219
220import java.io.File;
221import java.io.FileDescriptor;
222import java.io.FileInputStream;
223import java.io.FileNotFoundException;
224import java.io.FileOutputStream;
225import java.io.IOException;
226import java.io.InputStreamReader;
227import java.io.PrintWriter;
228import java.io.StringWriter;
229import java.lang.ref.WeakReference;
230import java.nio.charset.StandardCharsets;
231import java.util.ArrayList;
232import java.util.Arrays;
233import java.util.Collections;
234import java.util.Comparator;
235import java.util.HashMap;
236import java.util.HashSet;
237import java.util.Iterator;
238import java.util.List;
239import java.util.Locale;
240import java.util.Map;
241import java.util.Set;
242import java.util.concurrent.atomic.AtomicBoolean;
243import java.util.concurrent.atomic.AtomicLong;
244
245import dalvik.system.VMRuntime;
246
247import libcore.io.IoUtils;
248import libcore.util.EmptyArray;
249
250import static android.Manifest.permission.INTERACT_ACROSS_USERS;
251import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
252import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
253import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
254import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
255import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
256import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
257import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
258import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
259import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
260import static android.app.ActivityManager.StackId.HOME_STACK_ID;
261import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
262import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
263import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
264import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
265import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
266import static android.content.pm.PackageManager.GET_PROVIDERS;
267import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
268import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
269import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
270import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
271import static android.content.pm.PackageManager.PERMISSION_GRANTED;
272import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
273import static android.provider.Settings.Global.DEBUG_APP;
274import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
275import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
276import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
277import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
278import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
279import static android.provider.Settings.System.FONT_SCALE;
280import static com.android.internal.util.XmlUtils.readBooleanAttribute;
281import static com.android.internal.util.XmlUtils.readIntAttribute;
282import static com.android.internal.util.XmlUtils.readLongAttribute;
283import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
284import static com.android.internal.util.XmlUtils.writeIntAttribute;
285import static com.android.internal.util.XmlUtils.writeLongAttribute;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
342import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
343import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
344import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
345import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
346import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
347import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
348import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
349import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
350import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
351import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
352import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
353import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
354import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
355import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
356import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
357import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
358import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
359import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
360import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
361import static org.xmlpull.v1.XmlPullParser.START_TAG;
362
363public final class ActivityManagerService extends ActivityManagerNative
364        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
365
366    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
367    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
368    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
369    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
370    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
371    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
372    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
373    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
374    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
375    private static final String TAG_LRU = TAG + POSTFIX_LRU;
376    private static final String TAG_MU = TAG + POSTFIX_MU;
377    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
378    private static final String TAG_POWER = TAG + POSTFIX_POWER;
379    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
380    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
381    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
382    private static final String TAG_PSS = TAG + POSTFIX_PSS;
383    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
384    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
385    private static final String TAG_STACK = TAG + POSTFIX_STACK;
386    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
387    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
388    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
389    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
390    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
391
392    /** Control over CPU and battery monitoring */
393    // write battery stats every 30 minutes.
394    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
395    static final boolean MONITOR_CPU_USAGE = true;
396    // don't sample cpu less than every 5 seconds.
397    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
398    // wait possibly forever for next cpu sample.
399    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
400    static final boolean MONITOR_THREAD_CPU_USAGE = false;
401
402    // The flags that are set for all calls we make to the package manager.
403    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
404
405    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
406
407    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
408
409    // Amount of time after a call to stopAppSwitches() during which we will
410    // prevent further untrusted switches from happening.
411    static final long APP_SWITCH_DELAY_TIME = 5*1000;
412
413    // How long we wait for a launched process to attach to the activity manager
414    // before we decide it's never going to come up for real.
415    static final int PROC_START_TIMEOUT = 10*1000;
416    // How long we wait for an attached process to publish its content providers
417    // before we decide it must be hung.
418    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
419
420    // How long we will retain processes hosting content providers in the "last activity"
421    // state before allowing them to drop down to the regular cached LRU list.  This is
422    // to avoid thrashing of provider processes under low memory situations.
423    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
424
425    // How long we wait for a launched process to attach to the activity manager
426    // before we decide it's never going to come up for real, when the process was
427    // started with a wrapper for instrumentation (such as Valgrind) because it
428    // could take much longer than usual.
429    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
430
431    // How long to wait after going idle before forcing apps to GC.
432    static final int GC_TIMEOUT = 5*1000;
433
434    // The minimum amount of time between successive GC requests for a process.
435    static final int GC_MIN_INTERVAL = 60*1000;
436
437    // The minimum amount of time between successive PSS requests for a process.
438    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
439
440    // The minimum amount of time between successive PSS requests for a process
441    // when the request is due to the memory state being lowered.
442    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
443
444    // The rate at which we check for apps using excessive power -- 15 mins.
445    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
446
447    // The minimum sample duration we will allow before deciding we have
448    // enough data on wake locks to start killing things.
449    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
450
451    // The minimum sample duration we will allow before deciding we have
452    // enough data on CPU usage to start killing things.
453    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
454
455    // How long we allow a receiver to run before giving up on it.
456    static final int BROADCAST_FG_TIMEOUT = 10*1000;
457    static final int BROADCAST_BG_TIMEOUT = 60*1000;
458
459    // How long we wait until we timeout on key dispatching.
460    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
461
462    // How long we wait until we timeout on key dispatching during instrumentation.
463    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
464
465    // This is the amount of time an app needs to be running a foreground service before
466    // we will consider it to be doing interaction for usage stats.
467    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
468
469    // Maximum amount of time we will allow to elapse before re-reporting usage stats
470    // interaction with foreground processes.
471    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
472
473    // This is the amount of time we allow an app to settle after it goes into the background,
474    // before we start restricting what it can do.
475    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
476
477    // How long to wait in getAssistContextExtras for the activity and foreground services
478    // to respond with the result.
479    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
480
481    // How long top wait when going through the modern assist (which doesn't need to block
482    // on getting this result before starting to launch its UI).
483    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
484
485    // Maximum number of persisted Uri grants a package is allowed
486    static final int MAX_PERSISTED_URI_GRANTS = 128;
487
488    static final int MY_PID = Process.myPid();
489
490    static final String[] EMPTY_STRING_ARRAY = new String[0];
491
492    // How many bytes to write into the dropbox log before truncating
493    static final int DROPBOX_MAX_SIZE = 256 * 1024;
494
495    // Access modes for handleIncomingUser.
496    static final int ALLOW_NON_FULL = 0;
497    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
498    static final int ALLOW_FULL_ONLY = 2;
499
500    // Delay in notifying task stack change listeners (in millis)
501    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
502
503    // Necessary ApplicationInfo flags to mark an app as persistent
504    private static final int PERSISTENT_MASK =
505            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
506
507    // Intent sent when remote bugreport collection has been completed
508    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
509            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
510
511    // Delay to disable app launch boost
512    static final int APP_BOOST_MESSAGE_DELAY = 3000;
513    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
514    static final int APP_BOOST_TIMEOUT = 2500;
515
516    // Used to indicate that a task is removed it should also be removed from recents.
517    private static final boolean REMOVE_FROM_RECENTS = true;
518    // Used to indicate that an app transition should be animated.
519    static final boolean ANIMATE = true;
520
521    // Determines whether to take full screen screenshots
522    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
523    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
524
525    private static native int nativeMigrateToBoost();
526    private static native int nativeMigrateFromBoost();
527    private boolean mIsBoosted = false;
528    private long mBoostStartTime = 0;
529
530    /** All system services */
531    SystemServiceManager mSystemServiceManager;
532
533    private Installer mInstaller;
534
535    /** Run all ActivityStacks through this */
536    final ActivityStackSupervisor mStackSupervisor;
537
538    final ActivityStarter mActivityStarter;
539
540    /** Task stack change listeners. */
541    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
542            new RemoteCallbackList<ITaskStackListener>();
543
544    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
545
546    public IntentFirewall mIntentFirewall;
547
548    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
549    // default actuion automatically.  Important for devices without direct input
550    // devices.
551    private boolean mShowDialogs = true;
552    private boolean mInVrMode = false;
553
554    BroadcastQueue mFgBroadcastQueue;
555    BroadcastQueue mBgBroadcastQueue;
556    // Convenient for easy iteration over the queues. Foreground is first
557    // so that dispatch of foreground broadcasts gets precedence.
558    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
559
560    BroadcastQueue broadcastQueueForIntent(Intent intent) {
561        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
562        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
563                "Broadcast intent " + intent + " on "
564                + (isFg ? "foreground" : "background") + " queue");
565        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
566    }
567
568    /**
569     * Activity we have told the window manager to have key focus.
570     */
571    ActivityRecord mFocusedActivity = null;
572
573    /**
574     * User id of the last activity mFocusedActivity was set to.
575     */
576    private int mLastFocusedUserId;
577
578    /**
579     * If non-null, we are tracking the time the user spends in the currently focused app.
580     */
581    private AppTimeTracker mCurAppTimeTracker;
582
583    /**
584     * List of intents that were used to start the most recent tasks.
585     */
586    final RecentTasks mRecentTasks;
587
588    /**
589     * For addAppTask: cached of the last activity component that was added.
590     */
591    ComponentName mLastAddedTaskComponent;
592
593    /**
594     * For addAppTask: cached of the last activity uid that was added.
595     */
596    int mLastAddedTaskUid;
597
598    /**
599     * For addAppTask: cached of the last ActivityInfo that was added.
600     */
601    ActivityInfo mLastAddedTaskActivity;
602
603    /**
604     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
605     */
606    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
607
608    /**
609     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
610     */
611    String mDeviceOwnerName;
612
613    final UserController mUserController;
614
615    final AppErrors mAppErrors;
616
617    boolean mDoingSetFocusedActivity;
618
619    public boolean canShowErrorDialogs() {
620        return mShowDialogs && !mSleeping && !mShuttingDown;
621    }
622
623    public class PendingAssistExtras extends Binder implements Runnable {
624        public final ActivityRecord activity;
625        public final Bundle extras;
626        public final Intent intent;
627        public final String hint;
628        public final IResultReceiver receiver;
629        public final int userHandle;
630        public boolean haveResult = false;
631        public Bundle result = null;
632        public AssistStructure structure = null;
633        public AssistContent content = null;
634        public Bundle receiverExtras;
635
636        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
637                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
638            activity = _activity;
639            extras = _extras;
640            intent = _intent;
641            hint = _hint;
642            receiver = _receiver;
643            receiverExtras = _receiverExtras;
644            userHandle = _userHandle;
645        }
646        @Override
647        public void run() {
648            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
649            synchronized (this) {
650                haveResult = true;
651                notifyAll();
652            }
653            pendingAssistExtrasTimedOut(this);
654        }
655    }
656
657    final ArrayList<PendingAssistExtras> mPendingAssistExtras
658            = new ArrayList<PendingAssistExtras>();
659
660    /**
661     * Process management.
662     */
663    final ProcessList mProcessList = new ProcessList();
664
665    /**
666     * All of the applications we currently have running organized by name.
667     * The keys are strings of the application package name (as
668     * returned by the package manager), and the keys are ApplicationRecord
669     * objects.
670     */
671    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
672
673    /**
674     * Tracking long-term execution of processes to look for abuse and other
675     * bad app behavior.
676     */
677    final ProcessStatsService mProcessStats;
678
679    /**
680     * The currently running isolated processes.
681     */
682    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
683
684    /**
685     * Counter for assigning isolated process uids, to avoid frequently reusing the
686     * same ones.
687     */
688    int mNextIsolatedProcessUid = 0;
689
690    /**
691     * The currently running heavy-weight process, if any.
692     */
693    ProcessRecord mHeavyWeightProcess = null;
694
695    /**
696     * All of the processes we currently have running organized by pid.
697     * The keys are the pid running the application.
698     *
699     * <p>NOTE: This object is protected by its own lock, NOT the global
700     * activity manager lock!
701     */
702    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
703
704    /**
705     * All of the processes that have been forced to be foreground.  The key
706     * is the pid of the caller who requested it (we hold a death
707     * link on it).
708     */
709    abstract class ForegroundToken implements IBinder.DeathRecipient {
710        int pid;
711        IBinder token;
712    }
713    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
714
715    /**
716     * List of records for processes that someone had tried to start before the
717     * system was ready.  We don't start them at that point, but ensure they
718     * are started by the time booting is complete.
719     */
720    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
721
722    /**
723     * List of persistent applications that are in the process
724     * of being started.
725     */
726    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
727
728    /**
729     * Processes that are being forcibly torn down.
730     */
731    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
732
733    /**
734     * List of running applications, sorted by recent usage.
735     * The first entry in the list is the least recently used.
736     */
737    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
738
739    /**
740     * Where in mLruProcesses that the processes hosting activities start.
741     */
742    int mLruProcessActivityStart = 0;
743
744    /**
745     * Where in mLruProcesses that the processes hosting services start.
746     * This is after (lower index) than mLruProcessesActivityStart.
747     */
748    int mLruProcessServiceStart = 0;
749
750    /**
751     * List of processes that should gc as soon as things are idle.
752     */
753    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
754
755    /**
756     * Processes we want to collect PSS data from.
757     */
758    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
759
760    private boolean mBinderTransactionTrackingEnabled = false;
761
762    /**
763     * Last time we requested PSS data of all processes.
764     */
765    long mLastFullPssTime = SystemClock.uptimeMillis();
766
767    /**
768     * If set, the next time we collect PSS data we should do a full collection
769     * with data from native processes and the kernel.
770     */
771    boolean mFullPssPending = false;
772
773    /**
774     * This is the process holding what we currently consider to be
775     * the "home" activity.
776     */
777    ProcessRecord mHomeProcess;
778
779    /**
780     * This is the process holding the activity the user last visited that
781     * is in a different process from the one they are currently in.
782     */
783    ProcessRecord mPreviousProcess;
784
785    /**
786     * The time at which the previous process was last visible.
787     */
788    long mPreviousProcessVisibleTime;
789
790    /**
791     * Track all uids that have actively running processes.
792     */
793    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
794
795    /**
796     * This is for verifying the UID report flow.
797     */
798    static final boolean VALIDATE_UID_STATES = true;
799    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
800
801    /**
802     * Packages that the user has asked to have run in screen size
803     * compatibility mode instead of filling the screen.
804     */
805    final CompatModePackages mCompatModePackages;
806
807    /**
808     * Set of IntentSenderRecord objects that are currently active.
809     */
810    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
811            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
812
813    /**
814     * Fingerprints (hashCode()) of stack traces that we've
815     * already logged DropBox entries for.  Guarded by itself.  If
816     * something (rogue user app) forces this over
817     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
818     */
819    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
820    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
821
822    /**
823     * Strict Mode background batched logging state.
824     *
825     * The string buffer is guarded by itself, and its lock is also
826     * used to determine if another batched write is already
827     * in-flight.
828     */
829    private final StringBuilder mStrictModeBuffer = new StringBuilder();
830
831    /**
832     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
833     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
834     */
835    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
836
837    /**
838     * Resolver for broadcast intents to registered receivers.
839     * Holds BroadcastFilter (subclass of IntentFilter).
840     */
841    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
842            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
843        @Override
844        protected boolean allowFilterResult(
845                BroadcastFilter filter, List<BroadcastFilter> dest) {
846            IBinder target = filter.receiverList.receiver.asBinder();
847            for (int i = dest.size() - 1; i >= 0; i--) {
848                if (dest.get(i).receiverList.receiver.asBinder() == target) {
849                    return false;
850                }
851            }
852            return true;
853        }
854
855        @Override
856        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
857            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
858                    || userId == filter.owningUserId) {
859                return super.newResult(filter, match, userId);
860            }
861            return null;
862        }
863
864        @Override
865        protected BroadcastFilter[] newArray(int size) {
866            return new BroadcastFilter[size];
867        }
868
869        @Override
870        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
871            return packageName.equals(filter.packageName);
872        }
873    };
874
875    /**
876     * State of all active sticky broadcasts per user.  Keys are the action of the
877     * sticky Intent, values are an ArrayList of all broadcasted intents with
878     * that action (which should usually be one).  The SparseArray is keyed
879     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
880     * for stickies that are sent to all users.
881     */
882    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
883            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
884
885    final ActiveServices mServices;
886
887    final static class Association {
888        final int mSourceUid;
889        final String mSourceProcess;
890        final int mTargetUid;
891        final ComponentName mTargetComponent;
892        final String mTargetProcess;
893
894        int mCount;
895        long mTime;
896
897        int mNesting;
898        long mStartTime;
899
900        // states of the source process when the bind occurred.
901        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
902        long mLastStateUptime;
903        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
904                - ActivityManager.MIN_PROCESS_STATE+1];
905
906        Association(int sourceUid, String sourceProcess, int targetUid,
907                ComponentName targetComponent, String targetProcess) {
908            mSourceUid = sourceUid;
909            mSourceProcess = sourceProcess;
910            mTargetUid = targetUid;
911            mTargetComponent = targetComponent;
912            mTargetProcess = targetProcess;
913        }
914    }
915
916    /**
917     * When service association tracking is enabled, this is all of the associations we
918     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
919     * -> association data.
920     */
921    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
922            mAssociations = new SparseArray<>();
923    boolean mTrackingAssociations;
924
925    /**
926     * Backup/restore process management
927     */
928    String mBackupAppName = null;
929    BackupRecord mBackupTarget = null;
930
931    final ProviderMap mProviderMap;
932
933    /**
934     * List of content providers who have clients waiting for them.  The
935     * application is currently being launched and the provider will be
936     * removed from this list once it is published.
937     */
938    final ArrayList<ContentProviderRecord> mLaunchingProviders
939            = new ArrayList<ContentProviderRecord>();
940
941    /**
942     * File storing persisted {@link #mGrantedUriPermissions}.
943     */
944    private final AtomicFile mGrantFile;
945
946    /** XML constants used in {@link #mGrantFile} */
947    private static final String TAG_URI_GRANTS = "uri-grants";
948    private static final String TAG_URI_GRANT = "uri-grant";
949    private static final String ATTR_USER_HANDLE = "userHandle";
950    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
951    private static final String ATTR_TARGET_USER_ID = "targetUserId";
952    private static final String ATTR_SOURCE_PKG = "sourcePkg";
953    private static final String ATTR_TARGET_PKG = "targetPkg";
954    private static final String ATTR_URI = "uri";
955    private static final String ATTR_MODE_FLAGS = "modeFlags";
956    private static final String ATTR_CREATED_TIME = "createdTime";
957    private static final String ATTR_PREFIX = "prefix";
958
959    /**
960     * Global set of specific {@link Uri} permissions that have been granted.
961     * This optimized lookup structure maps from {@link UriPermission#targetUid}
962     * to {@link UriPermission#uri} to {@link UriPermission}.
963     */
964    @GuardedBy("this")
965    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
966            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
967
968    public static class GrantUri {
969        public final int sourceUserId;
970        public final Uri uri;
971        public boolean prefix;
972
973        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
974            this.sourceUserId = sourceUserId;
975            this.uri = uri;
976            this.prefix = prefix;
977        }
978
979        @Override
980        public int hashCode() {
981            int hashCode = 1;
982            hashCode = 31 * hashCode + sourceUserId;
983            hashCode = 31 * hashCode + uri.hashCode();
984            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
985            return hashCode;
986        }
987
988        @Override
989        public boolean equals(Object o) {
990            if (o instanceof GrantUri) {
991                GrantUri other = (GrantUri) o;
992                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
993                        && prefix == other.prefix;
994            }
995            return false;
996        }
997
998        @Override
999        public String toString() {
1000            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1001            if (prefix) result += " [prefix]";
1002            return result;
1003        }
1004
1005        public String toSafeString() {
1006            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1007            if (prefix) result += " [prefix]";
1008            return result;
1009        }
1010
1011        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1012            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1013                    ContentProvider.getUriWithoutUserId(uri), false);
1014        }
1015    }
1016
1017    CoreSettingsObserver mCoreSettingsObserver;
1018
1019    FontScaleSettingObserver mFontScaleSettingObserver;
1020
1021    private final class FontScaleSettingObserver extends ContentObserver {
1022        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1023
1024        public FontScaleSettingObserver() {
1025            super(mHandler);
1026            ContentResolver resolver = mContext.getContentResolver();
1027            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1028        }
1029
1030        @Override
1031        public void onChange(boolean selfChange, Uri uri) {
1032            if (mFontScaleUri.equals(uri)) {
1033                updateFontScaleIfNeeded();
1034            }
1035        }
1036    }
1037
1038    /**
1039     * Thread-local storage used to carry caller permissions over through
1040     * indirect content-provider access.
1041     */
1042    private class Identity {
1043        public final IBinder token;
1044        public final int pid;
1045        public final int uid;
1046
1047        Identity(IBinder _token, int _pid, int _uid) {
1048            token = _token;
1049            pid = _pid;
1050            uid = _uid;
1051        }
1052    }
1053
1054    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1055
1056    /**
1057     * All information we have collected about the runtime performance of
1058     * any user id that can impact battery performance.
1059     */
1060    final BatteryStatsService mBatteryStatsService;
1061
1062    /**
1063     * Information about component usage
1064     */
1065    UsageStatsManagerInternal mUsageStatsService;
1066
1067    /**
1068     * Access to DeviceIdleController service.
1069     */
1070    DeviceIdleController.LocalService mLocalDeviceIdleController;
1071
1072    /**
1073     * Information about and control over application operations
1074     */
1075    final AppOpsService mAppOpsService;
1076
1077    /**
1078     * Current configuration information.  HistoryRecord objects are given
1079     * a reference to this object to indicate which configuration they are
1080     * currently running in, so this object must be kept immutable.
1081     */
1082    Configuration mConfiguration = new Configuration();
1083
1084    /**
1085     * Current sequencing integer of the configuration, for skipping old
1086     * configurations.
1087     */
1088    int mConfigurationSeq = 0;
1089
1090    boolean mSuppressResizeConfigChanges = false;
1091
1092    /**
1093     * Hardware-reported OpenGLES version.
1094     */
1095    final int GL_ES_VERSION;
1096
1097    /**
1098     * List of initialization arguments to pass to all processes when binding applications to them.
1099     * For example, references to the commonly used services.
1100     */
1101    HashMap<String, IBinder> mAppBindArgs;
1102
1103    /**
1104     * Temporary to avoid allocations.  Protected by main lock.
1105     */
1106    final StringBuilder mStringBuilder = new StringBuilder(256);
1107
1108    /**
1109     * Used to control how we initialize the service.
1110     */
1111    ComponentName mTopComponent;
1112    String mTopAction = Intent.ACTION_MAIN;
1113    String mTopData;
1114
1115    volatile boolean mProcessesReady = false;
1116    volatile boolean mSystemReady = false;
1117    volatile boolean mOnBattery = false;
1118    volatile int mFactoryTest;
1119
1120    @GuardedBy("this") boolean mBooting = false;
1121    @GuardedBy("this") boolean mCallFinishBooting = false;
1122    @GuardedBy("this") boolean mBootAnimationComplete = false;
1123    @GuardedBy("this") boolean mLaunchWarningShown = false;
1124    @GuardedBy("this") boolean mCheckedForSetup = false;
1125
1126    Context mContext;
1127
1128    /**
1129     * The time at which we will allow normal application switches again,
1130     * after a call to {@link #stopAppSwitches()}.
1131     */
1132    long mAppSwitchesAllowedTime;
1133
1134    /**
1135     * This is set to true after the first switch after mAppSwitchesAllowedTime
1136     * is set; any switches after that will clear the time.
1137     */
1138    boolean mDidAppSwitch;
1139
1140    /**
1141     * Last time (in realtime) at which we checked for power usage.
1142     */
1143    long mLastPowerCheckRealtime;
1144
1145    /**
1146     * Last time (in uptime) at which we checked for power usage.
1147     */
1148    long mLastPowerCheckUptime;
1149
1150    /**
1151     * Set while we are wanting to sleep, to prevent any
1152     * activities from being started/resumed.
1153     */
1154    private boolean mSleeping = false;
1155
1156    /**
1157     * The process state used for processes that are running the top activities.
1158     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1159     */
1160    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1161
1162    /**
1163     * Set while we are running a voice interaction.  This overrides
1164     * sleeping while it is active.
1165     */
1166    private IVoiceInteractionSession mRunningVoice;
1167
1168    /**
1169     * For some direct access we need to power manager.
1170     */
1171    PowerManagerInternal mLocalPowerManager;
1172
1173    /**
1174     * We want to hold a wake lock while running a voice interaction session, since
1175     * this may happen with the screen off and we need to keep the CPU running to
1176     * be able to continue to interact with the user.
1177     */
1178    PowerManager.WakeLock mVoiceWakeLock;
1179
1180    /**
1181     * State of external calls telling us if the device is awake or asleep.
1182     */
1183    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1184
1185    /**
1186     * A list of tokens that cause the top activity to be put to sleep.
1187     * They are used by components that may hide and block interaction with underlying
1188     * activities.
1189     */
1190    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1191
1192    static final int LOCK_SCREEN_HIDDEN = 0;
1193    static final int LOCK_SCREEN_LEAVING = 1;
1194    static final int LOCK_SCREEN_SHOWN = 2;
1195    /**
1196     * State of external call telling us if the lock screen is shown.
1197     */
1198    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1199
1200    /**
1201     * Set if we are shutting down the system, similar to sleeping.
1202     */
1203    boolean mShuttingDown = false;
1204
1205    /**
1206     * Current sequence id for oom_adj computation traversal.
1207     */
1208    int mAdjSeq = 0;
1209
1210    /**
1211     * Current sequence id for process LRU updating.
1212     */
1213    int mLruSeq = 0;
1214
1215    /**
1216     * Keep track of the non-cached/empty process we last found, to help
1217     * determine how to distribute cached/empty processes next time.
1218     */
1219    int mNumNonCachedProcs = 0;
1220
1221    /**
1222     * Keep track of the number of cached hidden procs, to balance oom adj
1223     * distribution between those and empty procs.
1224     */
1225    int mNumCachedHiddenProcs = 0;
1226
1227    /**
1228     * Keep track of the number of service processes we last found, to
1229     * determine on the next iteration which should be B services.
1230     */
1231    int mNumServiceProcs = 0;
1232    int mNewNumAServiceProcs = 0;
1233    int mNewNumServiceProcs = 0;
1234
1235    /**
1236     * Allow the current computed overall memory level of the system to go down?
1237     * This is set to false when we are killing processes for reasons other than
1238     * memory management, so that the now smaller process list will not be taken as
1239     * an indication that memory is tighter.
1240     */
1241    boolean mAllowLowerMemLevel = false;
1242
1243    /**
1244     * The last computed memory level, for holding when we are in a state that
1245     * processes are going away for other reasons.
1246     */
1247    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1248
1249    /**
1250     * The last total number of process we have, to determine if changes actually look
1251     * like a shrinking number of process due to lower RAM.
1252     */
1253    int mLastNumProcesses;
1254
1255    /**
1256     * The uptime of the last time we performed idle maintenance.
1257     */
1258    long mLastIdleTime = SystemClock.uptimeMillis();
1259
1260    /**
1261     * Total time spent with RAM that has been added in the past since the last idle time.
1262     */
1263    long mLowRamTimeSinceLastIdle = 0;
1264
1265    /**
1266     * If RAM is currently low, when that horrible situation started.
1267     */
1268    long mLowRamStartTime = 0;
1269
1270    /**
1271     * For reporting to battery stats the current top application.
1272     */
1273    private String mCurResumedPackage = null;
1274    private int mCurResumedUid = -1;
1275
1276    /**
1277     * For reporting to battery stats the apps currently running foreground
1278     * service.  The ProcessMap is package/uid tuples; each of these contain
1279     * an array of the currently foreground processes.
1280     */
1281    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1282            = new ProcessMap<ArrayList<ProcessRecord>>();
1283
1284    /**
1285     * This is set if we had to do a delayed dexopt of an app before launching
1286     * it, to increase the ANR timeouts in that case.
1287     */
1288    boolean mDidDexOpt;
1289
1290    /**
1291     * Set if the systemServer made a call to enterSafeMode.
1292     */
1293    boolean mSafeMode;
1294
1295    /**
1296     * If true, we are running under a test environment so will sample PSS from processes
1297     * much more rapidly to try to collect better data when the tests are rapidly
1298     * running through apps.
1299     */
1300    boolean mTestPssMode = false;
1301
1302    String mDebugApp = null;
1303    boolean mWaitForDebugger = false;
1304    boolean mDebugTransient = false;
1305    String mOrigDebugApp = null;
1306    boolean mOrigWaitForDebugger = false;
1307    boolean mAlwaysFinishActivities = false;
1308    boolean mLenientBackgroundCheck = false;
1309    boolean mForceResizableActivities;
1310    boolean mSupportsMultiWindow;
1311    boolean mSupportsFreeformWindowManagement;
1312    boolean mSupportsPictureInPicture;
1313    Rect mDefaultPinnedStackBounds;
1314    IActivityController mController = null;
1315    boolean mControllerIsAMonkey = false;
1316    String mProfileApp = null;
1317    ProcessRecord mProfileProc = null;
1318    String mProfileFile;
1319    ParcelFileDescriptor mProfileFd;
1320    int mSamplingInterval = 0;
1321    boolean mAutoStopProfiler = false;
1322    int mProfileType = 0;
1323    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1324    String mMemWatchDumpProcName;
1325    String mMemWatchDumpFile;
1326    int mMemWatchDumpPid;
1327    int mMemWatchDumpUid;
1328    String mTrackAllocationApp = null;
1329    String mNativeDebuggingApp = null;
1330
1331    final long[] mTmpLong = new long[2];
1332
1333    static final class ProcessChangeItem {
1334        static final int CHANGE_ACTIVITIES = 1<<0;
1335        static final int CHANGE_PROCESS_STATE = 1<<1;
1336        int changes;
1337        int uid;
1338        int pid;
1339        int processState;
1340        boolean foregroundActivities;
1341    }
1342
1343    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1344    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1345
1346    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1347    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1348
1349    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1350    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1351
1352    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1353    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1354
1355    /**
1356     * Runtime CPU use collection thread.  This object's lock is used to
1357     * perform synchronization with the thread (notifying it to run).
1358     */
1359    final Thread mProcessCpuThread;
1360
1361    /**
1362     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1363     * Must acquire this object's lock when accessing it.
1364     * NOTE: this lock will be held while doing long operations (trawling
1365     * through all processes in /proc), so it should never be acquired by
1366     * any critical paths such as when holding the main activity manager lock.
1367     */
1368    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1369            MONITOR_THREAD_CPU_USAGE);
1370    final AtomicLong mLastCpuTime = new AtomicLong(0);
1371    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1372
1373    long mLastWriteTime = 0;
1374
1375    /**
1376     * Used to retain an update lock when the foreground activity is in
1377     * immersive mode.
1378     */
1379    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1380
1381    /**
1382     * Set to true after the system has finished booting.
1383     */
1384    boolean mBooted = false;
1385
1386    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1387    int mProcessLimitOverride = -1;
1388
1389    WindowManagerService mWindowManager;
1390    final ActivityThread mSystemThread;
1391
1392    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1393        final ProcessRecord mApp;
1394        final int mPid;
1395        final IApplicationThread mAppThread;
1396
1397        AppDeathRecipient(ProcessRecord app, int pid,
1398                IApplicationThread thread) {
1399            if (DEBUG_ALL) Slog.v(
1400                TAG, "New death recipient " + this
1401                + " for thread " + thread.asBinder());
1402            mApp = app;
1403            mPid = pid;
1404            mAppThread = thread;
1405        }
1406
1407        @Override
1408        public void binderDied() {
1409            if (DEBUG_ALL) Slog.v(
1410                TAG, "Death received in " + this
1411                + " for thread " + mAppThread.asBinder());
1412            synchronized(ActivityManagerService.this) {
1413                appDiedLocked(mApp, mPid, mAppThread, true);
1414            }
1415        }
1416    }
1417
1418    static final int SHOW_ERROR_UI_MSG = 1;
1419    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1420    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1421    static final int UPDATE_CONFIGURATION_MSG = 4;
1422    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1423    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1424    static final int SERVICE_TIMEOUT_MSG = 12;
1425    static final int UPDATE_TIME_ZONE = 13;
1426    static final int SHOW_UID_ERROR_UI_MSG = 14;
1427    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1428    static final int PROC_START_TIMEOUT_MSG = 20;
1429    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1430    static final int KILL_APPLICATION_MSG = 22;
1431    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1432    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1433    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1434    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1435    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1436    static final int CLEAR_DNS_CACHE_MSG = 28;
1437    static final int UPDATE_HTTP_PROXY_MSG = 29;
1438    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1439    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1440    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1441    static final int REPORT_MEM_USAGE_MSG = 33;
1442    static final int REPORT_USER_SWITCH_MSG = 34;
1443    static final int CONTINUE_USER_SWITCH_MSG = 35;
1444    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1445    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1446    static final int PERSIST_URI_GRANTS_MSG = 38;
1447    static final int REQUEST_ALL_PSS_MSG = 39;
1448    static final int START_PROFILES_MSG = 40;
1449    static final int UPDATE_TIME = 41;
1450    static final int SYSTEM_USER_START_MSG = 42;
1451    static final int SYSTEM_USER_CURRENT_MSG = 43;
1452    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1453    static final int FINISH_BOOTING_MSG = 45;
1454    static final int START_USER_SWITCH_UI_MSG = 46;
1455    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1456    static final int DISMISS_DIALOG_UI_MSG = 48;
1457    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1458    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1459    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1460    static final int DELETE_DUMPHEAP_MSG = 52;
1461    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1462    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1463    static final int REPORT_TIME_TRACKER_MSG = 55;
1464    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1465    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1466    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1467    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1468    static final int IDLE_UIDS_MSG = 60;
1469    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1470    static final int LOG_STACK_STATE = 62;
1471    static final int VR_MODE_CHANGE_MSG = 63;
1472    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1473    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1474    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1475    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1476    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1477    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1478
1479    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1480    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1481    static final int FIRST_COMPAT_MODE_MSG = 300;
1482    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1483
1484    static ServiceThread sKillThread = null;
1485    static KillHandler sKillHandler = null;
1486
1487    CompatModeDialog mCompatModeDialog;
1488    long mLastMemUsageReportTime = 0;
1489
1490    /**
1491     * Flag whether the current user is a "monkey", i.e. whether
1492     * the UI is driven by a UI automation tool.
1493     */
1494    private boolean mUserIsMonkey;
1495
1496    /** Flag whether the device has a Recents UI */
1497    boolean mHasRecents;
1498
1499    /** The dimensions of the thumbnails in the Recents UI. */
1500    int mThumbnailWidth;
1501    int mThumbnailHeight;
1502    float mFullscreenThumbnailScale;
1503
1504    final ServiceThread mHandlerThread;
1505    final MainHandler mHandler;
1506    final UiHandler mUiHandler;
1507
1508    PackageManagerInternal mPackageManagerInt;
1509
1510    final class KillHandler extends Handler {
1511        static final int KILL_PROCESS_GROUP_MSG = 4000;
1512
1513        public KillHandler(Looper looper) {
1514            super(looper, null, true);
1515        }
1516
1517        @Override
1518        public void handleMessage(Message msg) {
1519            switch (msg.what) {
1520                case KILL_PROCESS_GROUP_MSG:
1521                {
1522                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1523                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1524                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1525                }
1526                break;
1527
1528                default:
1529                    super.handleMessage(msg);
1530            }
1531        }
1532    }
1533
1534    final class UiHandler extends Handler {
1535        public UiHandler() {
1536            super(com.android.server.UiThread.get().getLooper(), null, true);
1537        }
1538
1539        @Override
1540        public void handleMessage(Message msg) {
1541            switch (msg.what) {
1542            case SHOW_ERROR_UI_MSG: {
1543                mAppErrors.handleShowAppErrorUi(msg);
1544                ensureBootCompleted();
1545            } break;
1546            case SHOW_NOT_RESPONDING_UI_MSG: {
1547                mAppErrors.handleShowAnrUi(msg);
1548                ensureBootCompleted();
1549            } break;
1550            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1551                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1552                synchronized (ActivityManagerService.this) {
1553                    ProcessRecord proc = (ProcessRecord) data.get("app");
1554                    if (proc == null) {
1555                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1556                        break;
1557                    }
1558                    if (proc.crashDialog != null) {
1559                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1560                        return;
1561                    }
1562                    AppErrorResult res = (AppErrorResult) data.get("result");
1563                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1564                        Dialog d = new StrictModeViolationDialog(mContext,
1565                                ActivityManagerService.this, res, proc);
1566                        d.show();
1567                        proc.crashDialog = d;
1568                    } else {
1569                        // The device is asleep, so just pretend that the user
1570                        // saw a crash dialog and hit "force quit".
1571                        res.set(0);
1572                    }
1573                }
1574                ensureBootCompleted();
1575            } break;
1576            case SHOW_FACTORY_ERROR_UI_MSG: {
1577                Dialog d = new FactoryErrorDialog(
1578                    mContext, msg.getData().getCharSequence("msg"));
1579                d.show();
1580                ensureBootCompleted();
1581            } break;
1582            case WAIT_FOR_DEBUGGER_UI_MSG: {
1583                synchronized (ActivityManagerService.this) {
1584                    ProcessRecord app = (ProcessRecord)msg.obj;
1585                    if (msg.arg1 != 0) {
1586                        if (!app.waitedForDebugger) {
1587                            Dialog d = new AppWaitingForDebuggerDialog(
1588                                    ActivityManagerService.this,
1589                                    mContext, app);
1590                            app.waitDialog = d;
1591                            app.waitedForDebugger = true;
1592                            d.show();
1593                        }
1594                    } else {
1595                        if (app.waitDialog != null) {
1596                            app.waitDialog.dismiss();
1597                            app.waitDialog = null;
1598                        }
1599                    }
1600                }
1601            } break;
1602            case SHOW_UID_ERROR_UI_MSG: {
1603                if (mShowDialogs) {
1604                    AlertDialog d = new BaseErrorDialog(mContext);
1605                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1606                    d.setCancelable(false);
1607                    d.setTitle(mContext.getText(R.string.android_system_label));
1608                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1609                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1610                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1611                    d.show();
1612                }
1613            } break;
1614            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1615                if (mShowDialogs) {
1616                    AlertDialog d = new BaseErrorDialog(mContext);
1617                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1618                    d.setCancelable(false);
1619                    d.setTitle(mContext.getText(R.string.android_system_label));
1620                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1621                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1622                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1623                    d.show();
1624                }
1625            } break;
1626            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1627                synchronized (ActivityManagerService.this) {
1628                    ActivityRecord ar = (ActivityRecord) msg.obj;
1629                    if (mCompatModeDialog != null) {
1630                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1631                                ar.info.applicationInfo.packageName)) {
1632                            return;
1633                        }
1634                        mCompatModeDialog.dismiss();
1635                        mCompatModeDialog = null;
1636                    }
1637                    if (ar != null && false) {
1638                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1639                                ar.packageName)) {
1640                            int mode = mCompatModePackages.computeCompatModeLocked(
1641                                    ar.info.applicationInfo);
1642                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1643                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1644                                mCompatModeDialog = new CompatModeDialog(
1645                                        ActivityManagerService.this, mContext,
1646                                        ar.info.applicationInfo);
1647                                mCompatModeDialog.show();
1648                            }
1649                        }
1650                    }
1651                }
1652                break;
1653            }
1654            case START_USER_SWITCH_UI_MSG: {
1655                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1656                break;
1657            }
1658            case DISMISS_DIALOG_UI_MSG: {
1659                final Dialog d = (Dialog) msg.obj;
1660                d.dismiss();
1661                break;
1662            }
1663            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1664                dispatchProcessesChanged();
1665                break;
1666            }
1667            case DISPATCH_PROCESS_DIED_UI_MSG: {
1668                final int pid = msg.arg1;
1669                final int uid = msg.arg2;
1670                dispatchProcessDied(pid, uid);
1671                break;
1672            }
1673            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1674                dispatchUidsChanged();
1675            } break;
1676            }
1677        }
1678    }
1679
1680    final class MainHandler extends Handler {
1681        public MainHandler(Looper looper) {
1682            super(looper, null, true);
1683        }
1684
1685        @Override
1686        public void handleMessage(Message msg) {
1687            switch (msg.what) {
1688            case UPDATE_CONFIGURATION_MSG: {
1689                final ContentResolver resolver = mContext.getContentResolver();
1690                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1691                        msg.arg1);
1692            } break;
1693            case GC_BACKGROUND_PROCESSES_MSG: {
1694                synchronized (ActivityManagerService.this) {
1695                    performAppGcsIfAppropriateLocked();
1696                }
1697            } break;
1698            case SERVICE_TIMEOUT_MSG: {
1699                if (mDidDexOpt) {
1700                    mDidDexOpt = false;
1701                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1702                    nmsg.obj = msg.obj;
1703                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1704                    return;
1705                }
1706                mServices.serviceTimeout((ProcessRecord)msg.obj);
1707            } break;
1708            case UPDATE_TIME_ZONE: {
1709                synchronized (ActivityManagerService.this) {
1710                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1711                        ProcessRecord r = mLruProcesses.get(i);
1712                        if (r.thread != null) {
1713                            try {
1714                                r.thread.updateTimeZone();
1715                            } catch (RemoteException ex) {
1716                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1717                            }
1718                        }
1719                    }
1720                }
1721            } break;
1722            case CLEAR_DNS_CACHE_MSG: {
1723                synchronized (ActivityManagerService.this) {
1724                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1725                        ProcessRecord r = mLruProcesses.get(i);
1726                        if (r.thread != null) {
1727                            try {
1728                                r.thread.clearDnsCache();
1729                            } catch (RemoteException ex) {
1730                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1731                            }
1732                        }
1733                    }
1734                }
1735            } break;
1736            case UPDATE_HTTP_PROXY_MSG: {
1737                ProxyInfo proxy = (ProxyInfo)msg.obj;
1738                String host = "";
1739                String port = "";
1740                String exclList = "";
1741                Uri pacFileUrl = Uri.EMPTY;
1742                if (proxy != null) {
1743                    host = proxy.getHost();
1744                    port = Integer.toString(proxy.getPort());
1745                    exclList = proxy.getExclusionListAsString();
1746                    pacFileUrl = proxy.getPacFileUrl();
1747                }
1748                synchronized (ActivityManagerService.this) {
1749                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1750                        ProcessRecord r = mLruProcesses.get(i);
1751                        if (r.thread != null) {
1752                            try {
1753                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1754                            } catch (RemoteException ex) {
1755                                Slog.w(TAG, "Failed to update http proxy for: " +
1756                                        r.info.processName);
1757                            }
1758                        }
1759                    }
1760                }
1761            } break;
1762            case PROC_START_TIMEOUT_MSG: {
1763                if (mDidDexOpt) {
1764                    mDidDexOpt = false;
1765                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1766                    nmsg.obj = msg.obj;
1767                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1768                    return;
1769                }
1770                ProcessRecord app = (ProcessRecord)msg.obj;
1771                synchronized (ActivityManagerService.this) {
1772                    processStartTimedOutLocked(app);
1773                }
1774            } break;
1775            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1776                ProcessRecord app = (ProcessRecord)msg.obj;
1777                synchronized (ActivityManagerService.this) {
1778                    processContentProviderPublishTimedOutLocked(app);
1779                }
1780            } break;
1781            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1782                synchronized (ActivityManagerService.this) {
1783                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1784                }
1785            } break;
1786            case KILL_APPLICATION_MSG: {
1787                synchronized (ActivityManagerService.this) {
1788                    int appid = msg.arg1;
1789                    boolean restart = (msg.arg2 == 1);
1790                    Bundle bundle = (Bundle)msg.obj;
1791                    String pkg = bundle.getString("pkg");
1792                    String reason = bundle.getString("reason");
1793                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1794                            false, UserHandle.USER_ALL, reason);
1795                }
1796            } break;
1797            case FINALIZE_PENDING_INTENT_MSG: {
1798                ((PendingIntentRecord)msg.obj).completeFinalize();
1799            } break;
1800            case POST_HEAVY_NOTIFICATION_MSG: {
1801                INotificationManager inm = NotificationManager.getService();
1802                if (inm == null) {
1803                    return;
1804                }
1805
1806                ActivityRecord root = (ActivityRecord)msg.obj;
1807                ProcessRecord process = root.app;
1808                if (process == null) {
1809                    return;
1810                }
1811
1812                try {
1813                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1814                    String text = mContext.getString(R.string.heavy_weight_notification,
1815                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1816                    Notification notification = new Notification.Builder(context)
1817                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1818                            .setWhen(0)
1819                            .setOngoing(true)
1820                            .setTicker(text)
1821                            .setColor(mContext.getColor(
1822                                    com.android.internal.R.color.system_notification_accent_color))
1823                            .setContentTitle(text)
1824                            .setContentText(
1825                                    mContext.getText(R.string.heavy_weight_notification_detail))
1826                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1827                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1828                                    new UserHandle(root.userId)))
1829                            .build();
1830                    try {
1831                        int[] outId = new int[1];
1832                        inm.enqueueNotificationWithTag("android", "android", null,
1833                                R.string.heavy_weight_notification,
1834                                notification, outId, root.userId);
1835                    } catch (RuntimeException e) {
1836                        Slog.w(ActivityManagerService.TAG,
1837                                "Error showing notification for heavy-weight app", e);
1838                    } catch (RemoteException e) {
1839                    }
1840                } catch (NameNotFoundException e) {
1841                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1842                }
1843            } break;
1844            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1845                INotificationManager inm = NotificationManager.getService();
1846                if (inm == null) {
1847                    return;
1848                }
1849                try {
1850                    inm.cancelNotificationWithTag("android", null,
1851                            R.string.heavy_weight_notification,  msg.arg1);
1852                } catch (RuntimeException e) {
1853                    Slog.w(ActivityManagerService.TAG,
1854                            "Error canceling notification for service", e);
1855                } catch (RemoteException e) {
1856                }
1857            } break;
1858            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1859                synchronized (ActivityManagerService.this) {
1860                    checkExcessivePowerUsageLocked(true);
1861                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1862                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1863                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1864                }
1865            } break;
1866            case REPORT_MEM_USAGE_MSG: {
1867                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1868                Thread thread = new Thread() {
1869                    @Override public void run() {
1870                        reportMemUsage(memInfos);
1871                    }
1872                };
1873                thread.start();
1874                break;
1875            }
1876            case REPORT_USER_SWITCH_MSG: {
1877                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1878                break;
1879            }
1880            case CONTINUE_USER_SWITCH_MSG: {
1881                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1882                break;
1883            }
1884            case USER_SWITCH_TIMEOUT_MSG: {
1885                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1886                break;
1887            }
1888            case IMMERSIVE_MODE_LOCK_MSG: {
1889                final boolean nextState = (msg.arg1 != 0);
1890                if (mUpdateLock.isHeld() != nextState) {
1891                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1892                            "Applying new update lock state '" + nextState
1893                            + "' for " + (ActivityRecord)msg.obj);
1894                    if (nextState) {
1895                        mUpdateLock.acquire();
1896                    } else {
1897                        mUpdateLock.release();
1898                    }
1899                }
1900                break;
1901            }
1902            case PERSIST_URI_GRANTS_MSG: {
1903                writeGrantedUriPermissions();
1904                break;
1905            }
1906            case REQUEST_ALL_PSS_MSG: {
1907                synchronized (ActivityManagerService.this) {
1908                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1909                }
1910                break;
1911            }
1912            case START_PROFILES_MSG: {
1913                synchronized (ActivityManagerService.this) {
1914                    mUserController.startProfilesLocked();
1915                }
1916                break;
1917            }
1918            case UPDATE_TIME: {
1919                synchronized (ActivityManagerService.this) {
1920                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1921                        ProcessRecord r = mLruProcesses.get(i);
1922                        if (r.thread != null) {
1923                            try {
1924                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1925                            } catch (RemoteException ex) {
1926                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1927                            }
1928                        }
1929                    }
1930                }
1931                break;
1932            }
1933            case SYSTEM_USER_START_MSG: {
1934                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1935                        Integer.toString(msg.arg1), msg.arg1);
1936                mSystemServiceManager.startUser(msg.arg1);
1937                break;
1938            }
1939            case SYSTEM_USER_UNLOCK_MSG: {
1940                final int userId = msg.arg1;
1941                mSystemServiceManager.unlockUser(userId);
1942                synchronized (ActivityManagerService.this) {
1943                    mRecentTasks.loadUserRecentsLocked(userId);
1944                }
1945                if (userId == UserHandle.USER_SYSTEM) {
1946                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1947                }
1948                installEncryptionUnawareProviders(userId);
1949                if (msg.obj instanceof ProgressReporter) {
1950                    ((ProgressReporter) msg.obj).finish();
1951                }
1952                break;
1953            }
1954            case SYSTEM_USER_CURRENT_MSG: {
1955                mBatteryStatsService.noteEvent(
1956                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1957                        Integer.toString(msg.arg2), msg.arg2);
1958                mBatteryStatsService.noteEvent(
1959                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1960                        Integer.toString(msg.arg1), msg.arg1);
1961                mSystemServiceManager.switchUser(msg.arg1);
1962                break;
1963            }
1964            case ENTER_ANIMATION_COMPLETE_MSG: {
1965                synchronized (ActivityManagerService.this) {
1966                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1967                    if (r != null && r.app != null && r.app.thread != null) {
1968                        try {
1969                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1970                        } catch (RemoteException e) {
1971                        }
1972                    }
1973                }
1974                break;
1975            }
1976            case FINISH_BOOTING_MSG: {
1977                if (msg.arg1 != 0) {
1978                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1979                    finishBooting();
1980                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1981                }
1982                if (msg.arg2 != 0) {
1983                    enableScreenAfterBoot();
1984                }
1985                break;
1986            }
1987            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1988                try {
1989                    Locale l = (Locale) msg.obj;
1990                    IBinder service = ServiceManager.getService("mount");
1991                    IMountService mountService = IMountService.Stub.asInterface(service);
1992                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1993                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1994                } catch (RemoteException e) {
1995                    Log.e(TAG, "Error storing locale for decryption UI", e);
1996                }
1997                break;
1998            }
1999            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2000                synchronized (ActivityManagerService.this) {
2001                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2002                        try {
2003                            // Make a one-way callback to the listener
2004                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2005                        } catch (RemoteException e){
2006                            // Handled by the RemoteCallbackList
2007                        }
2008                    }
2009                    mTaskStackListeners.finishBroadcast();
2010                }
2011                break;
2012            }
2013            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2014                synchronized (ActivityManagerService.this) {
2015                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2016                        try {
2017                            // Make a one-way callback to the listener
2018                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2019                        } catch (RemoteException e){
2020                            // Handled by the RemoteCallbackList
2021                        }
2022                    }
2023                    mTaskStackListeners.finishBroadcast();
2024                }
2025                break;
2026            }
2027            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2028                synchronized (ActivityManagerService.this) {
2029                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2030                        try {
2031                            // Make a one-way callback to the listener
2032                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2033                        } catch (RemoteException e){
2034                            // Handled by the RemoteCallbackList
2035                        }
2036                    }
2037                    mTaskStackListeners.finishBroadcast();
2038                }
2039                break;
2040            }
2041            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2042                synchronized (ActivityManagerService.this) {
2043                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2044                        try {
2045                            // Make a one-way callback to the listener
2046                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2047                        } catch (RemoteException e){
2048                            // Handled by the RemoteCallbackList
2049                        }
2050                    }
2051                    mTaskStackListeners.finishBroadcast();
2052                }
2053                break;
2054            }
2055            case NOTIFY_FORCED_RESIZABLE_MSG: {
2056                synchronized (ActivityManagerService.this) {
2057                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2058                        try {
2059                            // Make a one-way callback to the listener
2060                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2061                                    (String) msg.obj, msg.arg1);
2062                        } catch (RemoteException e){
2063                            // Handled by the RemoteCallbackList
2064                        }
2065                    }
2066                    mTaskStackListeners.finishBroadcast();
2067                }
2068                break;
2069            }
2070                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2071                    synchronized (ActivityManagerService.this) {
2072                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2073                            try {
2074                                // Make a one-way callback to the listener
2075                                mTaskStackListeners.getBroadcastItem(i)
2076                                        .onActivityDismissingDockedStack();
2077                            } catch (RemoteException e){
2078                                // Handled by the RemoteCallbackList
2079                            }
2080                        }
2081                        mTaskStackListeners.finishBroadcast();
2082                    }
2083                    break;
2084                }
2085            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2086                final int uid = msg.arg1;
2087                final byte[] firstPacket = (byte[]) msg.obj;
2088
2089                synchronized (mPidsSelfLocked) {
2090                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2091                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2092                        if (p.uid == uid) {
2093                            try {
2094                                p.thread.notifyCleartextNetwork(firstPacket);
2095                            } catch (RemoteException ignored) {
2096                            }
2097                        }
2098                    }
2099                }
2100                break;
2101            }
2102            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2103                final String procName;
2104                final int uid;
2105                final long memLimit;
2106                final String reportPackage;
2107                synchronized (ActivityManagerService.this) {
2108                    procName = mMemWatchDumpProcName;
2109                    uid = mMemWatchDumpUid;
2110                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2111                    if (val == null) {
2112                        val = mMemWatchProcesses.get(procName, 0);
2113                    }
2114                    if (val != null) {
2115                        memLimit = val.first;
2116                        reportPackage = val.second;
2117                    } else {
2118                        memLimit = 0;
2119                        reportPackage = null;
2120                    }
2121                }
2122                if (procName == null) {
2123                    return;
2124                }
2125
2126                if (DEBUG_PSS) Slog.d(TAG_PSS,
2127                        "Showing dump heap notification from " + procName + "/" + uid);
2128
2129                INotificationManager inm = NotificationManager.getService();
2130                if (inm == null) {
2131                    return;
2132                }
2133
2134                String text = mContext.getString(R.string.dump_heap_notification, procName);
2135
2136
2137                Intent deleteIntent = new Intent();
2138                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2139                Intent intent = new Intent();
2140                intent.setClassName("android", DumpHeapActivity.class.getName());
2141                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2142                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2143                if (reportPackage != null) {
2144                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2145                }
2146                int userId = UserHandle.getUserId(uid);
2147                Notification notification = new Notification.Builder(mContext)
2148                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2149                        .setWhen(0)
2150                        .setOngoing(true)
2151                        .setAutoCancel(true)
2152                        .setTicker(text)
2153                        .setColor(mContext.getColor(
2154                                com.android.internal.R.color.system_notification_accent_color))
2155                        .setContentTitle(text)
2156                        .setContentText(
2157                                mContext.getText(R.string.dump_heap_notification_detail))
2158                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2159                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2160                                new UserHandle(userId)))
2161                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2162                                deleteIntent, 0, UserHandle.SYSTEM))
2163                        .build();
2164
2165                try {
2166                    int[] outId = new int[1];
2167                    inm.enqueueNotificationWithTag("android", "android", null,
2168                            R.string.dump_heap_notification,
2169                            notification, outId, userId);
2170                } catch (RuntimeException e) {
2171                    Slog.w(ActivityManagerService.TAG,
2172                            "Error showing notification for dump heap", e);
2173                } catch (RemoteException e) {
2174                }
2175            } break;
2176            case DELETE_DUMPHEAP_MSG: {
2177                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2178                        DumpHeapActivity.JAVA_URI,
2179                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2180                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2181                        UserHandle.myUserId());
2182                synchronized (ActivityManagerService.this) {
2183                    mMemWatchDumpFile = null;
2184                    mMemWatchDumpProcName = null;
2185                    mMemWatchDumpPid = -1;
2186                    mMemWatchDumpUid = -1;
2187                }
2188            } break;
2189            case FOREGROUND_PROFILE_CHANGED_MSG: {
2190                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2191            } break;
2192            case REPORT_TIME_TRACKER_MSG: {
2193                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2194                tracker.deliverResult(mContext);
2195            } break;
2196            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2197                mUserController.dispatchUserSwitchComplete(msg.arg1);
2198            } break;
2199            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2200                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2201                try {
2202                    connection.shutdown();
2203                } catch (RemoteException e) {
2204                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2205                }
2206                // Only a UiAutomation can set this flag and now that
2207                // it is finished we make sure it is reset to its default.
2208                mUserIsMonkey = false;
2209            } break;
2210            case APP_BOOST_DEACTIVATE_MSG: {
2211                synchronized(ActivityManagerService.this) {
2212                    if (mIsBoosted) {
2213                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2214                            nativeMigrateFromBoost();
2215                            mIsBoosted = false;
2216                            mBoostStartTime = 0;
2217                        } else {
2218                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2219                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2220                        }
2221                    }
2222                }
2223            } break;
2224            case IDLE_UIDS_MSG: {
2225                idleUids();
2226            } break;
2227            case LOG_STACK_STATE: {
2228                synchronized (ActivityManagerService.this) {
2229                    mStackSupervisor.logStackState();
2230                }
2231            } break;
2232            case VR_MODE_CHANGE_MSG: {
2233                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2234                final ActivityRecord r = (ActivityRecord) msg.obj;
2235                boolean vrMode;
2236                ComponentName requestedPackage;
2237                ComponentName callingPackage;
2238                int userId;
2239                synchronized (ActivityManagerService.this) {
2240                    vrMode = r.requestedVrComponent != null;
2241                    requestedPackage = r.requestedVrComponent;
2242                    userId = r.userId;
2243                    callingPackage = r.info.getComponentName();
2244                    if (mInVrMode != vrMode) {
2245                        mInVrMode = vrMode;
2246                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2247                    }
2248                }
2249                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2250            } break;
2251            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2252                final ActivityRecord r = (ActivityRecord) msg.obj;
2253                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2254                if (needsVrMode) {
2255                    VrManagerInternal vrService =
2256                            LocalServices.getService(VrManagerInternal.class);
2257                    boolean enable = msg.arg1 == 1;
2258                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2259                            r.info.getComponentName());
2260                }
2261            } break;
2262            }
2263        }
2264    };
2265
2266    static final int COLLECT_PSS_BG_MSG = 1;
2267
2268    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2269        @Override
2270        public void handleMessage(Message msg) {
2271            switch (msg.what) {
2272            case COLLECT_PSS_BG_MSG: {
2273                long start = SystemClock.uptimeMillis();
2274                MemInfoReader memInfo = null;
2275                synchronized (ActivityManagerService.this) {
2276                    if (mFullPssPending) {
2277                        mFullPssPending = false;
2278                        memInfo = new MemInfoReader();
2279                    }
2280                }
2281                if (memInfo != null) {
2282                    updateCpuStatsNow();
2283                    long nativeTotalPss = 0;
2284                    synchronized (mProcessCpuTracker) {
2285                        final int N = mProcessCpuTracker.countStats();
2286                        for (int j=0; j<N; j++) {
2287                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2288                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2289                                // This is definitely an application process; skip it.
2290                                continue;
2291                            }
2292                            synchronized (mPidsSelfLocked) {
2293                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2294                                    // This is one of our own processes; skip it.
2295                                    continue;
2296                                }
2297                            }
2298                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2299                        }
2300                    }
2301                    memInfo.readMemInfo();
2302                    synchronized (ActivityManagerService.this) {
2303                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2304                                + (SystemClock.uptimeMillis()-start) + "ms");
2305                        final long cachedKb = memInfo.getCachedSizeKb();
2306                        final long freeKb = memInfo.getFreeSizeKb();
2307                        final long zramKb = memInfo.getZramTotalSizeKb();
2308                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2309                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2310                                kernelKb*1024, nativeTotalPss*1024);
2311                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2312                                nativeTotalPss);
2313                    }
2314                }
2315
2316                int num = 0;
2317                long[] tmp = new long[2];
2318                do {
2319                    ProcessRecord proc;
2320                    int procState;
2321                    int pid;
2322                    long lastPssTime;
2323                    synchronized (ActivityManagerService.this) {
2324                        if (mPendingPssProcesses.size() <= 0) {
2325                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2326                                    "Collected PSS of " + num + " processes in "
2327                                    + (SystemClock.uptimeMillis() - start) + "ms");
2328                            mPendingPssProcesses.clear();
2329                            return;
2330                        }
2331                        proc = mPendingPssProcesses.remove(0);
2332                        procState = proc.pssProcState;
2333                        lastPssTime = proc.lastPssTime;
2334                        if (proc.thread != null && procState == proc.setProcState
2335                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2336                                        < SystemClock.uptimeMillis()) {
2337                            pid = proc.pid;
2338                        } else {
2339                            proc = null;
2340                            pid = 0;
2341                        }
2342                    }
2343                    if (proc != null) {
2344                        long pss = Debug.getPss(pid, tmp, null);
2345                        synchronized (ActivityManagerService.this) {
2346                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2347                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2348                                num++;
2349                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2350                                        SystemClock.uptimeMillis());
2351                            }
2352                        }
2353                    }
2354                } while (true);
2355            }
2356            }
2357        }
2358    };
2359
2360    public void setSystemProcess() {
2361        try {
2362            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2363            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2364            ServiceManager.addService("meminfo", new MemBinder(this));
2365            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2366            ServiceManager.addService("dbinfo", new DbBinder(this));
2367            if (MONITOR_CPU_USAGE) {
2368                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2369            }
2370            ServiceManager.addService("permission", new PermissionController(this));
2371            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2372
2373            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2374                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2375            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2376
2377            synchronized (this) {
2378                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2379                app.persistent = true;
2380                app.pid = MY_PID;
2381                app.maxAdj = ProcessList.SYSTEM_ADJ;
2382                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2383                synchronized (mPidsSelfLocked) {
2384                    mPidsSelfLocked.put(app.pid, app);
2385                }
2386                updateLruProcessLocked(app, false, null);
2387                updateOomAdjLocked();
2388            }
2389        } catch (PackageManager.NameNotFoundException e) {
2390            throw new RuntimeException(
2391                    "Unable to find android system package", e);
2392        }
2393    }
2394
2395    public void setWindowManager(WindowManagerService wm) {
2396        mWindowManager = wm;
2397        mStackSupervisor.setWindowManager(wm);
2398        mActivityStarter.setWindowManager(wm);
2399    }
2400
2401    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2402        mUsageStatsService = usageStatsManager;
2403    }
2404
2405    public void startObservingNativeCrashes() {
2406        final NativeCrashListener ncl = new NativeCrashListener(this);
2407        ncl.start();
2408    }
2409
2410    public IAppOpsService getAppOpsService() {
2411        return mAppOpsService;
2412    }
2413
2414    static class MemBinder extends Binder {
2415        ActivityManagerService mActivityManagerService;
2416        MemBinder(ActivityManagerService activityManagerService) {
2417            mActivityManagerService = activityManagerService;
2418        }
2419
2420        @Override
2421        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2422            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2423                    != PackageManager.PERMISSION_GRANTED) {
2424                pw.println("Permission Denial: can't dump meminfo from from pid="
2425                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2426                        + " without permission " + android.Manifest.permission.DUMP);
2427                return;
2428            }
2429
2430            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2431        }
2432    }
2433
2434    static class GraphicsBinder extends Binder {
2435        ActivityManagerService mActivityManagerService;
2436        GraphicsBinder(ActivityManagerService activityManagerService) {
2437            mActivityManagerService = activityManagerService;
2438        }
2439
2440        @Override
2441        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2442            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2443                    != PackageManager.PERMISSION_GRANTED) {
2444                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2445                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2446                        + " without permission " + android.Manifest.permission.DUMP);
2447                return;
2448            }
2449
2450            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2451        }
2452    }
2453
2454    static class DbBinder extends Binder {
2455        ActivityManagerService mActivityManagerService;
2456        DbBinder(ActivityManagerService activityManagerService) {
2457            mActivityManagerService = activityManagerService;
2458        }
2459
2460        @Override
2461        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2462            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2463                    != PackageManager.PERMISSION_GRANTED) {
2464                pw.println("Permission Denial: can't dump dbinfo from from pid="
2465                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2466                        + " without permission " + android.Manifest.permission.DUMP);
2467                return;
2468            }
2469
2470            mActivityManagerService.dumpDbInfo(fd, pw, args);
2471        }
2472    }
2473
2474    static class CpuBinder extends Binder {
2475        ActivityManagerService mActivityManagerService;
2476        CpuBinder(ActivityManagerService activityManagerService) {
2477            mActivityManagerService = activityManagerService;
2478        }
2479
2480        @Override
2481        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2482            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2483                    != PackageManager.PERMISSION_GRANTED) {
2484                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2485                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2486                        + " without permission " + android.Manifest.permission.DUMP);
2487                return;
2488            }
2489
2490            synchronized (mActivityManagerService.mProcessCpuTracker) {
2491                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2492                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2493                        SystemClock.uptimeMillis()));
2494            }
2495        }
2496    }
2497
2498    public static final class Lifecycle extends SystemService {
2499        private final ActivityManagerService mService;
2500
2501        public Lifecycle(Context context) {
2502            super(context);
2503            mService = new ActivityManagerService(context);
2504        }
2505
2506        @Override
2507        public void onStart() {
2508            mService.start();
2509        }
2510
2511        public ActivityManagerService getService() {
2512            return mService;
2513        }
2514    }
2515
2516    // Note: This method is invoked on the main thread but may need to attach various
2517    // handlers to other threads.  So take care to be explicit about the looper.
2518    public ActivityManagerService(Context systemContext) {
2519        mContext = systemContext;
2520        mFactoryTest = FactoryTest.getMode();
2521        mSystemThread = ActivityThread.currentActivityThread();
2522
2523        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2524
2525        mHandlerThread = new ServiceThread(TAG,
2526                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2527        mHandlerThread.start();
2528        mHandler = new MainHandler(mHandlerThread.getLooper());
2529        mUiHandler = new UiHandler();
2530
2531        /* static; one-time init here */
2532        if (sKillHandler == null) {
2533            sKillThread = new ServiceThread(TAG + ":kill",
2534                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2535            sKillThread.start();
2536            sKillHandler = new KillHandler(sKillThread.getLooper());
2537        }
2538
2539        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2540                "foreground", BROADCAST_FG_TIMEOUT, false);
2541        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2542                "background", BROADCAST_BG_TIMEOUT, true);
2543        mBroadcastQueues[0] = mFgBroadcastQueue;
2544        mBroadcastQueues[1] = mBgBroadcastQueue;
2545
2546        mServices = new ActiveServices(this);
2547        mProviderMap = new ProviderMap(this);
2548        mAppErrors = new AppErrors(mContext, this);
2549
2550        // TODO: Move creation of battery stats service outside of activity manager service.
2551        File dataDir = Environment.getDataDirectory();
2552        File systemDir = new File(dataDir, "system");
2553        systemDir.mkdirs();
2554        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2555        mBatteryStatsService.getActiveStatistics().readLocked();
2556        mBatteryStatsService.scheduleWriteToDisk();
2557        mOnBattery = DEBUG_POWER ? true
2558                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2559        mBatteryStatsService.getActiveStatistics().setCallback(this);
2560
2561        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2562
2563        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2564        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2565                new IAppOpsCallback.Stub() {
2566                    @Override public void opChanged(int op, int uid, String packageName) {
2567                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2568                            if (mAppOpsService.checkOperation(op, uid, packageName)
2569                                    != AppOpsManager.MODE_ALLOWED) {
2570                                runInBackgroundDisabled(uid);
2571                            }
2572                        }
2573                    }
2574                });
2575
2576        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2577
2578        mUserController = new UserController(this);
2579
2580        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2581            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2582
2583        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2584
2585        mConfiguration.setToDefaults();
2586        mConfiguration.setLocales(LocaleList.getDefault());
2587
2588        mConfigurationSeq = mConfiguration.seq = 1;
2589        mProcessCpuTracker.init();
2590
2591        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2592        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2593        mStackSupervisor = new ActivityStackSupervisor(this);
2594        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2595        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2596
2597        mProcessCpuThread = new Thread("CpuTracker") {
2598            @Override
2599            public void run() {
2600                while (true) {
2601                    try {
2602                        try {
2603                            synchronized(this) {
2604                                final long now = SystemClock.uptimeMillis();
2605                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2606                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2607                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2608                                //        + ", write delay=" + nextWriteDelay);
2609                                if (nextWriteDelay < nextCpuDelay) {
2610                                    nextCpuDelay = nextWriteDelay;
2611                                }
2612                                if (nextCpuDelay > 0) {
2613                                    mProcessCpuMutexFree.set(true);
2614                                    this.wait(nextCpuDelay);
2615                                }
2616                            }
2617                        } catch (InterruptedException e) {
2618                        }
2619                        updateCpuStatsNow();
2620                    } catch (Exception e) {
2621                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2622                    }
2623                }
2624            }
2625        };
2626
2627        Watchdog.getInstance().addMonitor(this);
2628        Watchdog.getInstance().addThread(mHandler);
2629    }
2630
2631    public void setSystemServiceManager(SystemServiceManager mgr) {
2632        mSystemServiceManager = mgr;
2633    }
2634
2635    public void setInstaller(Installer installer) {
2636        mInstaller = installer;
2637    }
2638
2639    private void start() {
2640        Process.removeAllProcessGroups();
2641        mProcessCpuThread.start();
2642
2643        mBatteryStatsService.publish(mContext);
2644        mAppOpsService.publish(mContext);
2645        Slog.d("AppOps", "AppOpsService published");
2646        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2647    }
2648
2649    void onUserStoppedLocked(int userId) {
2650        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2651    }
2652
2653    public void initPowerManagement() {
2654        mStackSupervisor.initPowerManagement();
2655        mBatteryStatsService.initPowerManagement();
2656        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2657        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2658        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2659        mVoiceWakeLock.setReferenceCounted(false);
2660    }
2661
2662    @Override
2663    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2664            throws RemoteException {
2665        if (code == SYSPROPS_TRANSACTION) {
2666            // We need to tell all apps about the system property change.
2667            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2668            synchronized(this) {
2669                final int NP = mProcessNames.getMap().size();
2670                for (int ip=0; ip<NP; ip++) {
2671                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2672                    final int NA = apps.size();
2673                    for (int ia=0; ia<NA; ia++) {
2674                        ProcessRecord app = apps.valueAt(ia);
2675                        if (app.thread != null) {
2676                            procs.add(app.thread.asBinder());
2677                        }
2678                    }
2679                }
2680            }
2681
2682            int N = procs.size();
2683            for (int i=0; i<N; i++) {
2684                Parcel data2 = Parcel.obtain();
2685                try {
2686                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2687                } catch (RemoteException e) {
2688                }
2689                data2.recycle();
2690            }
2691        }
2692        try {
2693            return super.onTransact(code, data, reply, flags);
2694        } catch (RuntimeException e) {
2695            // The activity manager only throws security exceptions, so let's
2696            // log all others.
2697            if (!(e instanceof SecurityException)) {
2698                Slog.wtf(TAG, "Activity Manager Crash", e);
2699            }
2700            throw e;
2701        }
2702    }
2703
2704    void updateCpuStats() {
2705        final long now = SystemClock.uptimeMillis();
2706        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2707            return;
2708        }
2709        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2710            synchronized (mProcessCpuThread) {
2711                mProcessCpuThread.notify();
2712            }
2713        }
2714    }
2715
2716    void updateCpuStatsNow() {
2717        synchronized (mProcessCpuTracker) {
2718            mProcessCpuMutexFree.set(false);
2719            final long now = SystemClock.uptimeMillis();
2720            boolean haveNewCpuStats = false;
2721
2722            if (MONITOR_CPU_USAGE &&
2723                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2724                mLastCpuTime.set(now);
2725                mProcessCpuTracker.update();
2726                if (mProcessCpuTracker.hasGoodLastStats()) {
2727                    haveNewCpuStats = true;
2728                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2729                    //Slog.i(TAG, "Total CPU usage: "
2730                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2731
2732                    // Slog the cpu usage if the property is set.
2733                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2734                        int user = mProcessCpuTracker.getLastUserTime();
2735                        int system = mProcessCpuTracker.getLastSystemTime();
2736                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2737                        int irq = mProcessCpuTracker.getLastIrqTime();
2738                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2739                        int idle = mProcessCpuTracker.getLastIdleTime();
2740
2741                        int total = user + system + iowait + irq + softIrq + idle;
2742                        if (total == 0) total = 1;
2743
2744                        EventLog.writeEvent(EventLogTags.CPU,
2745                                ((user+system+iowait+irq+softIrq) * 100) / total,
2746                                (user * 100) / total,
2747                                (system * 100) / total,
2748                                (iowait * 100) / total,
2749                                (irq * 100) / total,
2750                                (softIrq * 100) / total);
2751                    }
2752                }
2753            }
2754
2755            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2756            synchronized(bstats) {
2757                synchronized(mPidsSelfLocked) {
2758                    if (haveNewCpuStats) {
2759                        if (bstats.startAddingCpuLocked()) {
2760                            int totalUTime = 0;
2761                            int totalSTime = 0;
2762                            final int N = mProcessCpuTracker.countStats();
2763                            for (int i=0; i<N; i++) {
2764                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2765                                if (!st.working) {
2766                                    continue;
2767                                }
2768                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2769                                totalUTime += st.rel_utime;
2770                                totalSTime += st.rel_stime;
2771                                if (pr != null) {
2772                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2773                                    if (ps == null || !ps.isActive()) {
2774                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2775                                                pr.info.uid, pr.processName);
2776                                    }
2777                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2778                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2779                                } else {
2780                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2781                                    if (ps == null || !ps.isActive()) {
2782                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2783                                                bstats.mapUid(st.uid), st.name);
2784                                    }
2785                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2786                                }
2787                            }
2788                            final int userTime = mProcessCpuTracker.getLastUserTime();
2789                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2790                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2791                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2792                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2793                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2794                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2795                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2796                        }
2797                    }
2798                }
2799
2800                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2801                    mLastWriteTime = now;
2802                    mBatteryStatsService.scheduleWriteToDisk();
2803                }
2804            }
2805        }
2806    }
2807
2808    @Override
2809    public void batteryNeedsCpuUpdate() {
2810        updateCpuStatsNow();
2811    }
2812
2813    @Override
2814    public void batteryPowerChanged(boolean onBattery) {
2815        // When plugging in, update the CPU stats first before changing
2816        // the plug state.
2817        updateCpuStatsNow();
2818        synchronized (this) {
2819            synchronized(mPidsSelfLocked) {
2820                mOnBattery = DEBUG_POWER ? true : onBattery;
2821            }
2822        }
2823    }
2824
2825    @Override
2826    public void batterySendBroadcast(Intent intent) {
2827        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2828                AppOpsManager.OP_NONE, null, false, false,
2829                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2830    }
2831
2832    /**
2833     * Initialize the application bind args. These are passed to each
2834     * process when the bindApplication() IPC is sent to the process. They're
2835     * lazily setup to make sure the services are running when they're asked for.
2836     */
2837    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2838        if (mAppBindArgs == null) {
2839            mAppBindArgs = new HashMap<>();
2840
2841            // Isolated processes won't get this optimization, so that we don't
2842            // violate the rules about which services they have access to.
2843            if (!isolated) {
2844                // Setup the application init args
2845                mAppBindArgs.put("package", ServiceManager.getService("package"));
2846                mAppBindArgs.put("window", ServiceManager.getService("window"));
2847                mAppBindArgs.put(Context.ALARM_SERVICE,
2848                        ServiceManager.getService(Context.ALARM_SERVICE));
2849            }
2850        }
2851        return mAppBindArgs;
2852    }
2853
2854    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2855        if (r == null || mFocusedActivity == r) {
2856            return false;
2857        }
2858
2859        if (!r.isFocusable()) {
2860            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2861            return false;
2862        }
2863
2864        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2865
2866        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2867        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2868                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2869        mDoingSetFocusedActivity = true;
2870
2871        final ActivityRecord last = mFocusedActivity;
2872        mFocusedActivity = r;
2873        if (r.task.isApplicationTask()) {
2874            if (mCurAppTimeTracker != r.appTimeTracker) {
2875                // We are switching app tracking.  Complete the current one.
2876                if (mCurAppTimeTracker != null) {
2877                    mCurAppTimeTracker.stop();
2878                    mHandler.obtainMessage(
2879                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2880                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2881                    mCurAppTimeTracker = null;
2882                }
2883                if (r.appTimeTracker != null) {
2884                    mCurAppTimeTracker = r.appTimeTracker;
2885                    startTimeTrackingFocusedActivityLocked();
2886                }
2887            } else {
2888                startTimeTrackingFocusedActivityLocked();
2889            }
2890        } else {
2891            r.appTimeTracker = null;
2892        }
2893        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2894        // TODO: Probably not, because we don't want to resume voice on switching
2895        // back to this activity
2896        if (r.task.voiceInteractor != null) {
2897            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2898        } else {
2899            finishRunningVoiceLocked();
2900            IVoiceInteractionSession session;
2901            if (last != null && ((session = last.task.voiceSession) != null
2902                    || (session = last.voiceSession) != null)) {
2903                // We had been in a voice interaction session, but now focused has
2904                // move to something different.  Just finish the session, we can't
2905                // return to it and retain the proper state and synchronization with
2906                // the voice interaction service.
2907                finishVoiceTask(session);
2908            }
2909        }
2910        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2911            mWindowManager.setFocusedApp(r.appToken, true);
2912        }
2913        applyUpdateLockStateLocked(r);
2914        applyUpdateVrModeLocked(r);
2915        if (mFocusedActivity.userId != mLastFocusedUserId) {
2916            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2917            mHandler.obtainMessage(
2918                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2919            mLastFocusedUserId = mFocusedActivity.userId;
2920        }
2921
2922        // Log a warning if the focused app is changed during the process. This could
2923        // indicate a problem of the focus setting logic!
2924        if (mFocusedActivity != r) Slog.w(TAG,
2925                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2926        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2927
2928        EventLogTags.writeAmFocusedActivity(
2929                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2930                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2931                reason);
2932        return true;
2933    }
2934
2935    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2936        if (mFocusedActivity != goingAway) {
2937            return;
2938        }
2939
2940        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2941        if (focusedStack != null) {
2942            final ActivityRecord top = focusedStack.topActivity();
2943            if (top != null && top.userId != mLastFocusedUserId) {
2944                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2945                mHandler.sendMessage(
2946                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2947                mLastFocusedUserId = top.userId;
2948            }
2949        }
2950
2951        // Try to move focus to another activity if possible.
2952        if (setFocusedActivityLocked(
2953                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2954            return;
2955        }
2956
2957        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2958                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2959        mFocusedActivity = null;
2960        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2961    }
2962
2963    @Override
2964    public void setFocusedStack(int stackId) {
2965        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2966        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2967        final long callingId = Binder.clearCallingIdentity();
2968        try {
2969            synchronized (this) {
2970                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2971                if (stack == null) {
2972                    return;
2973                }
2974                final ActivityRecord r = stack.topRunningActivityLocked();
2975                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2976                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2977                }
2978            }
2979        } finally {
2980            Binder.restoreCallingIdentity(callingId);
2981        }
2982    }
2983
2984    @Override
2985    public void setFocusedTask(int taskId) {
2986        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2987        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2988        final long callingId = Binder.clearCallingIdentity();
2989        try {
2990            synchronized (this) {
2991                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2992                if (task == null) {
2993                    return;
2994                }
2995                final ActivityRecord r = task.topRunningActivityLocked();
2996                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2997                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2998                }
2999            }
3000        } finally {
3001            Binder.restoreCallingIdentity(callingId);
3002        }
3003    }
3004
3005    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3006    @Override
3007    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3008        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3009        synchronized (this) {
3010            if (listener != null) {
3011                mTaskStackListeners.register(listener);
3012            }
3013        }
3014    }
3015
3016    @Override
3017    public void notifyActivityDrawn(IBinder token) {
3018        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3019        synchronized (this) {
3020            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3021            if (r != null) {
3022                r.task.stack.notifyActivityDrawnLocked(r);
3023            }
3024        }
3025    }
3026
3027    final void applyUpdateLockStateLocked(ActivityRecord r) {
3028        // Modifications to the UpdateLock state are done on our handler, outside
3029        // the activity manager's locks.  The new state is determined based on the
3030        // state *now* of the relevant activity record.  The object is passed to
3031        // the handler solely for logging detail, not to be consulted/modified.
3032        final boolean nextState = r != null && r.immersive;
3033        mHandler.sendMessage(
3034                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3035    }
3036
3037    final void applyUpdateVrModeLocked(ActivityRecord r) {
3038        mHandler.sendMessage(
3039                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3040    }
3041
3042    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3043        mHandler.sendMessage(
3044                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3045    }
3046
3047    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3048        Message msg = Message.obtain();
3049        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3050        msg.obj = r.task.askedCompatMode ? null : r;
3051        mUiHandler.sendMessage(msg);
3052    }
3053
3054    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3055            String what, Object obj, ProcessRecord srcApp) {
3056        app.lastActivityTime = now;
3057
3058        if (app.activities.size() > 0) {
3059            // Don't want to touch dependent processes that are hosting activities.
3060            return index;
3061        }
3062
3063        int lrui = mLruProcesses.lastIndexOf(app);
3064        if (lrui < 0) {
3065            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3066                    + what + " " + obj + " from " + srcApp);
3067            return index;
3068        }
3069
3070        if (lrui >= index) {
3071            // Don't want to cause this to move dependent processes *back* in the
3072            // list as if they were less frequently used.
3073            return index;
3074        }
3075
3076        if (lrui >= mLruProcessActivityStart) {
3077            // Don't want to touch dependent processes that are hosting activities.
3078            return index;
3079        }
3080
3081        mLruProcesses.remove(lrui);
3082        if (index > 0) {
3083            index--;
3084        }
3085        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3086                + " in LRU list: " + app);
3087        mLruProcesses.add(index, app);
3088        return index;
3089    }
3090
3091    static void killProcessGroup(int uid, int pid) {
3092        if (sKillHandler != null) {
3093            sKillHandler.sendMessage(
3094                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3095        } else {
3096            Slog.w(TAG, "Asked to kill process group before system bringup!");
3097            Process.killProcessGroup(uid, pid);
3098        }
3099    }
3100
3101    final void removeLruProcessLocked(ProcessRecord app) {
3102        int lrui = mLruProcesses.lastIndexOf(app);
3103        if (lrui >= 0) {
3104            if (!app.killed) {
3105                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3106                Process.killProcessQuiet(app.pid);
3107                killProcessGroup(app.uid, app.pid);
3108            }
3109            if (lrui <= mLruProcessActivityStart) {
3110                mLruProcessActivityStart--;
3111            }
3112            if (lrui <= mLruProcessServiceStart) {
3113                mLruProcessServiceStart--;
3114            }
3115            mLruProcesses.remove(lrui);
3116        }
3117    }
3118
3119    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3120            ProcessRecord client) {
3121        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3122                || app.treatLikeActivity;
3123        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3124        if (!activityChange && hasActivity) {
3125            // The process has activities, so we are only allowing activity-based adjustments
3126            // to move it.  It should be kept in the front of the list with other
3127            // processes that have activities, and we don't want those to change their
3128            // order except due to activity operations.
3129            return;
3130        }
3131
3132        mLruSeq++;
3133        final long now = SystemClock.uptimeMillis();
3134        app.lastActivityTime = now;
3135
3136        // First a quick reject: if the app is already at the position we will
3137        // put it, then there is nothing to do.
3138        if (hasActivity) {
3139            final int N = mLruProcesses.size();
3140            if (N > 0 && mLruProcesses.get(N-1) == app) {
3141                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3142                return;
3143            }
3144        } else {
3145            if (mLruProcessServiceStart > 0
3146                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3147                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3148                return;
3149            }
3150        }
3151
3152        int lrui = mLruProcesses.lastIndexOf(app);
3153
3154        if (app.persistent && lrui >= 0) {
3155            // We don't care about the position of persistent processes, as long as
3156            // they are in the list.
3157            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3158            return;
3159        }
3160
3161        /* In progress: compute new position first, so we can avoid doing work
3162           if the process is not actually going to move.  Not yet working.
3163        int addIndex;
3164        int nextIndex;
3165        boolean inActivity = false, inService = false;
3166        if (hasActivity) {
3167            // Process has activities, put it at the very tipsy-top.
3168            addIndex = mLruProcesses.size();
3169            nextIndex = mLruProcessServiceStart;
3170            inActivity = true;
3171        } else if (hasService) {
3172            // Process has services, put it at the top of the service list.
3173            addIndex = mLruProcessActivityStart;
3174            nextIndex = mLruProcessServiceStart;
3175            inActivity = true;
3176            inService = true;
3177        } else  {
3178            // Process not otherwise of interest, it goes to the top of the non-service area.
3179            addIndex = mLruProcessServiceStart;
3180            if (client != null) {
3181                int clientIndex = mLruProcesses.lastIndexOf(client);
3182                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3183                        + app);
3184                if (clientIndex >= 0 && addIndex > clientIndex) {
3185                    addIndex = clientIndex;
3186                }
3187            }
3188            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3189        }
3190
3191        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3192                + mLruProcessActivityStart + "): " + app);
3193        */
3194
3195        if (lrui >= 0) {
3196            if (lrui < mLruProcessActivityStart) {
3197                mLruProcessActivityStart--;
3198            }
3199            if (lrui < mLruProcessServiceStart) {
3200                mLruProcessServiceStart--;
3201            }
3202            /*
3203            if (addIndex > lrui) {
3204                addIndex--;
3205            }
3206            if (nextIndex > lrui) {
3207                nextIndex--;
3208            }
3209            */
3210            mLruProcesses.remove(lrui);
3211        }
3212
3213        /*
3214        mLruProcesses.add(addIndex, app);
3215        if (inActivity) {
3216            mLruProcessActivityStart++;
3217        }
3218        if (inService) {
3219            mLruProcessActivityStart++;
3220        }
3221        */
3222
3223        int nextIndex;
3224        if (hasActivity) {
3225            final int N = mLruProcesses.size();
3226            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3227                // Process doesn't have activities, but has clients with
3228                // activities...  move it up, but one below the top (the top
3229                // should always have a real activity).
3230                if (DEBUG_LRU) Slog.d(TAG_LRU,
3231                        "Adding to second-top of LRU activity list: " + app);
3232                mLruProcesses.add(N - 1, app);
3233                // To keep it from spamming the LRU list (by making a bunch of clients),
3234                // we will push down any other entries owned by the app.
3235                final int uid = app.info.uid;
3236                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3237                    ProcessRecord subProc = mLruProcesses.get(i);
3238                    if (subProc.info.uid == uid) {
3239                        // We want to push this one down the list.  If the process after
3240                        // it is for the same uid, however, don't do so, because we don't
3241                        // want them internally to be re-ordered.
3242                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3243                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3244                                    "Pushing uid " + uid + " swapping at " + i + ": "
3245                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3246                            ProcessRecord tmp = mLruProcesses.get(i);
3247                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3248                            mLruProcesses.set(i - 1, tmp);
3249                            i--;
3250                        }
3251                    } else {
3252                        // A gap, we can stop here.
3253                        break;
3254                    }
3255                }
3256            } else {
3257                // Process has activities, put it at the very tipsy-top.
3258                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3259                mLruProcesses.add(app);
3260            }
3261            nextIndex = mLruProcessServiceStart;
3262        } else if (hasService) {
3263            // Process has services, put it at the top of the service list.
3264            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3265            mLruProcesses.add(mLruProcessActivityStart, app);
3266            nextIndex = mLruProcessServiceStart;
3267            mLruProcessActivityStart++;
3268        } else  {
3269            // Process not otherwise of interest, it goes to the top of the non-service area.
3270            int index = mLruProcessServiceStart;
3271            if (client != null) {
3272                // If there is a client, don't allow the process to be moved up higher
3273                // in the list than that client.
3274                int clientIndex = mLruProcesses.lastIndexOf(client);
3275                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3276                        + " when updating " + app);
3277                if (clientIndex <= lrui) {
3278                    // Don't allow the client index restriction to push it down farther in the
3279                    // list than it already is.
3280                    clientIndex = lrui;
3281                }
3282                if (clientIndex >= 0 && index > clientIndex) {
3283                    index = clientIndex;
3284                }
3285            }
3286            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3287            mLruProcesses.add(index, app);
3288            nextIndex = index-1;
3289            mLruProcessActivityStart++;
3290            mLruProcessServiceStart++;
3291        }
3292
3293        // If the app is currently using a content provider or service,
3294        // bump those processes as well.
3295        for (int j=app.connections.size()-1; j>=0; j--) {
3296            ConnectionRecord cr = app.connections.valueAt(j);
3297            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3298                    && cr.binding.service.app != null
3299                    && cr.binding.service.app.lruSeq != mLruSeq
3300                    && !cr.binding.service.app.persistent) {
3301                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3302                        "service connection", cr, app);
3303            }
3304        }
3305        for (int j=app.conProviders.size()-1; j>=0; j--) {
3306            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3307            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3308                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3309                        "provider reference", cpr, app);
3310            }
3311        }
3312    }
3313
3314    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3315        if (uid == Process.SYSTEM_UID) {
3316            // The system gets to run in any process.  If there are multiple
3317            // processes with the same uid, just pick the first (this
3318            // should never happen).
3319            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3320            if (procs == null) return null;
3321            final int procCount = procs.size();
3322            for (int i = 0; i < procCount; i++) {
3323                final int procUid = procs.keyAt(i);
3324                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3325                    // Don't use an app process or different user process for system component.
3326                    continue;
3327                }
3328                return procs.valueAt(i);
3329            }
3330        }
3331        ProcessRecord proc = mProcessNames.get(processName, uid);
3332        if (false && proc != null && !keepIfLarge
3333                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3334                && proc.lastCachedPss >= 4000) {
3335            // Turn this condition on to cause killing to happen regularly, for testing.
3336            if (proc.baseProcessTracker != null) {
3337                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3338            }
3339            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3340        } else if (proc != null && !keepIfLarge
3341                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3342                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3343            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3344            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3345                if (proc.baseProcessTracker != null) {
3346                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3347                }
3348                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3349            }
3350        }
3351        return proc;
3352    }
3353
3354    void notifyPackageUse(String packageName, int reason) {
3355        IPackageManager pm = AppGlobals.getPackageManager();
3356        try {
3357            pm.notifyPackageUse(packageName, reason);
3358        } catch (RemoteException e) {
3359        }
3360    }
3361
3362    boolean isNextTransitionForward() {
3363        int transit = mWindowManager.getPendingAppTransition();
3364        return transit == TRANSIT_ACTIVITY_OPEN
3365                || transit == TRANSIT_TASK_OPEN
3366                || transit == TRANSIT_TASK_TO_FRONT;
3367    }
3368
3369    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3370            String processName, String abiOverride, int uid, Runnable crashHandler) {
3371        synchronized(this) {
3372            ApplicationInfo info = new ApplicationInfo();
3373            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3374            // For isolated processes, the former contains the parent's uid and the latter the
3375            // actual uid of the isolated process.
3376            // In the special case introduced by this method (which is, starting an isolated
3377            // process directly from the SystemServer without an actual parent app process) the
3378            // closest thing to a parent's uid is SYSTEM_UID.
3379            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3380            // the |isolated| logic in the ProcessRecord constructor.
3381            info.uid = Process.SYSTEM_UID;
3382            info.processName = processName;
3383            info.className = entryPoint;
3384            info.packageName = "android";
3385            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3386                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3387                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3388                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3389                    crashHandler);
3390            return proc != null ? proc.pid : 0;
3391        }
3392    }
3393
3394    final ProcessRecord startProcessLocked(String processName,
3395            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3396            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3397            boolean isolated, boolean keepIfLarge) {
3398        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3399                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3400                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3401                null /* crashHandler */);
3402    }
3403
3404    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3405            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3406            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3407            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3408        long startTime = SystemClock.elapsedRealtime();
3409        ProcessRecord app;
3410        if (!isolated) {
3411            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3412            checkTime(startTime, "startProcess: after getProcessRecord");
3413
3414            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3415                // If we are in the background, then check to see if this process
3416                // is bad.  If so, we will just silently fail.
3417                if (mAppErrors.isBadProcessLocked(info)) {
3418                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3419                            + "/" + info.processName);
3420                    return null;
3421                }
3422            } else {
3423                // When the user is explicitly starting a process, then clear its
3424                // crash count so that we won't make it bad until they see at
3425                // least one crash dialog again, and make the process good again
3426                // if it had been bad.
3427                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3428                        + "/" + info.processName);
3429                mAppErrors.resetProcessCrashTimeLocked(info);
3430                if (mAppErrors.isBadProcessLocked(info)) {
3431                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3432                            UserHandle.getUserId(info.uid), info.uid,
3433                            info.processName);
3434                    mAppErrors.clearBadProcessLocked(info);
3435                    if (app != null) {
3436                        app.bad = false;
3437                    }
3438                }
3439            }
3440        } else {
3441            // If this is an isolated process, it can't re-use an existing process.
3442            app = null;
3443        }
3444
3445        // app launch boost for big.little configurations
3446        // use cpusets to migrate freshly launched tasks to big cores
3447        synchronized(ActivityManagerService.this) {
3448            nativeMigrateToBoost();
3449            mIsBoosted = true;
3450            mBoostStartTime = SystemClock.uptimeMillis();
3451            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3452            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3453        }
3454
3455        // We don't have to do anything more if:
3456        // (1) There is an existing application record; and
3457        // (2) The caller doesn't think it is dead, OR there is no thread
3458        //     object attached to it so we know it couldn't have crashed; and
3459        // (3) There is a pid assigned to it, so it is either starting or
3460        //     already running.
3461        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3462                + " app=" + app + " knownToBeDead=" + knownToBeDead
3463                + " thread=" + (app != null ? app.thread : null)
3464                + " pid=" + (app != null ? app.pid : -1));
3465        if (app != null && app.pid > 0) {
3466            if (!knownToBeDead || app.thread == null) {
3467                // We already have the app running, or are waiting for it to
3468                // come up (we have a pid but not yet its thread), so keep it.
3469                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3470                // If this is a new package in the process, add the package to the list
3471                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3472                checkTime(startTime, "startProcess: done, added package to proc");
3473                return app;
3474            }
3475
3476            // An application record is attached to a previous process,
3477            // clean it up now.
3478            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3479            checkTime(startTime, "startProcess: bad proc running, killing");
3480            killProcessGroup(app.uid, app.pid);
3481            handleAppDiedLocked(app, true, true);
3482            checkTime(startTime, "startProcess: done killing old proc");
3483        }
3484
3485        String hostingNameStr = hostingName != null
3486                ? hostingName.flattenToShortString() : null;
3487
3488        if (app == null) {
3489            checkTime(startTime, "startProcess: creating new process record");
3490            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3491            if (app == null) {
3492                Slog.w(TAG, "Failed making new process record for "
3493                        + processName + "/" + info.uid + " isolated=" + isolated);
3494                return null;
3495            }
3496            app.crashHandler = crashHandler;
3497            checkTime(startTime, "startProcess: done creating new process record");
3498        } else {
3499            // If this is a new package in the process, add the package to the list
3500            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3501            checkTime(startTime, "startProcess: added package to existing proc");
3502        }
3503
3504        // If the system is not ready yet, then hold off on starting this
3505        // process until it is.
3506        if (!mProcessesReady
3507                && !isAllowedWhileBooting(info)
3508                && !allowWhileBooting) {
3509            if (!mProcessesOnHold.contains(app)) {
3510                mProcessesOnHold.add(app);
3511            }
3512            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3513                    "System not ready, putting on hold: " + app);
3514            checkTime(startTime, "startProcess: returning with proc on hold");
3515            return app;
3516        }
3517
3518        checkTime(startTime, "startProcess: stepping in to startProcess");
3519        startProcessLocked(
3520                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3521        checkTime(startTime, "startProcess: done starting proc!");
3522        return (app.pid != 0) ? app : null;
3523    }
3524
3525    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3526        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3527    }
3528
3529    private final void startProcessLocked(ProcessRecord app,
3530            String hostingType, String hostingNameStr) {
3531        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3532                null /* entryPoint */, null /* entryPointArgs */);
3533    }
3534
3535    private final void startProcessLocked(ProcessRecord app, String hostingType,
3536            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3537        long startTime = SystemClock.elapsedRealtime();
3538        if (app.pid > 0 && app.pid != MY_PID) {
3539            checkTime(startTime, "startProcess: removing from pids map");
3540            synchronized (mPidsSelfLocked) {
3541                mPidsSelfLocked.remove(app.pid);
3542                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3543            }
3544            checkTime(startTime, "startProcess: done removing from pids map");
3545            app.setPid(0);
3546        }
3547
3548        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3549                "startProcessLocked removing on hold: " + app);
3550        mProcessesOnHold.remove(app);
3551
3552        checkTime(startTime, "startProcess: starting to update cpu stats");
3553        updateCpuStats();
3554        checkTime(startTime, "startProcess: done updating cpu stats");
3555
3556        try {
3557            try {
3558                final int userId = UserHandle.getUserId(app.uid);
3559                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3560            } catch (RemoteException e) {
3561                throw e.rethrowAsRuntimeException();
3562            }
3563
3564            int uid = app.uid;
3565            int[] gids = null;
3566            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3567            if (!app.isolated) {
3568                int[] permGids = null;
3569                try {
3570                    checkTime(startTime, "startProcess: getting gids from package manager");
3571                    final IPackageManager pm = AppGlobals.getPackageManager();
3572                    permGids = pm.getPackageGids(app.info.packageName,
3573                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3574                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3575                            MountServiceInternal.class);
3576                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3577                            app.info.packageName);
3578                } catch (RemoteException e) {
3579                    throw e.rethrowAsRuntimeException();
3580                }
3581
3582                /*
3583                 * Add shared application and profile GIDs so applications can share some
3584                 * resources like shared libraries and access user-wide resources
3585                 */
3586                if (ArrayUtils.isEmpty(permGids)) {
3587                    gids = new int[2];
3588                } else {
3589                    gids = new int[permGids.length + 2];
3590                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3591                }
3592                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3593                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3594            }
3595            checkTime(startTime, "startProcess: building args");
3596            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3597                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3598                        && mTopComponent != null
3599                        && app.processName.equals(mTopComponent.getPackageName())) {
3600                    uid = 0;
3601                }
3602                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3603                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3604                    uid = 0;
3605                }
3606            }
3607            int debugFlags = 0;
3608            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3609                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3610                // Also turn on CheckJNI for debuggable apps. It's quite
3611                // awkward to turn on otherwise.
3612                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3613            }
3614            // Run the app in safe mode if its manifest requests so or the
3615            // system is booted in safe mode.
3616            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3617                mSafeMode == true) {
3618                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3619            }
3620            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3621                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3622            }
3623            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3624            if ("true".equals(genDebugInfoProperty)) {
3625                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3626            }
3627            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3628                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3629            }
3630            if ("1".equals(SystemProperties.get("debug.assert"))) {
3631                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3632            }
3633            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3634                // Enable all debug flags required by the native debugger.
3635                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3636                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3637                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3638                mNativeDebuggingApp = null;
3639            }
3640
3641            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3642            if (requiredAbi == null) {
3643                requiredAbi = Build.SUPPORTED_ABIS[0];
3644            }
3645
3646            String instructionSet = null;
3647            if (app.info.primaryCpuAbi != null) {
3648                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3649            }
3650
3651            app.gids = gids;
3652            app.requiredAbi = requiredAbi;
3653            app.instructionSet = instructionSet;
3654
3655            // Start the process.  It will either succeed and return a result containing
3656            // the PID of the new process, or else throw a RuntimeException.
3657            boolean isActivityProcess = (entryPoint == null);
3658            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3659            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3660                    app.processName);
3661            checkTime(startTime, "startProcess: asking zygote to start proc");
3662            Process.ProcessStartResult startResult = Process.start(entryPoint,
3663                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3664                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3665                    app.info.dataDir, entryPointArgs);
3666            checkTime(startTime, "startProcess: returned from zygote!");
3667            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3668
3669            if (app.isolated) {
3670                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3671            }
3672            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3673            checkTime(startTime, "startProcess: done updating battery stats");
3674
3675            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3676                    UserHandle.getUserId(uid), startResult.pid, uid,
3677                    app.processName, hostingType,
3678                    hostingNameStr != null ? hostingNameStr : "");
3679
3680            try {
3681                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3682                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3683            } catch (RemoteException ex) {
3684                // Ignore
3685            }
3686
3687            if (app.persistent) {
3688                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3689            }
3690
3691            checkTime(startTime, "startProcess: building log message");
3692            StringBuilder buf = mStringBuilder;
3693            buf.setLength(0);
3694            buf.append("Start proc ");
3695            buf.append(startResult.pid);
3696            buf.append(':');
3697            buf.append(app.processName);
3698            buf.append('/');
3699            UserHandle.formatUid(buf, uid);
3700            if (!isActivityProcess) {
3701                buf.append(" [");
3702                buf.append(entryPoint);
3703                buf.append("]");
3704            }
3705            buf.append(" for ");
3706            buf.append(hostingType);
3707            if (hostingNameStr != null) {
3708                buf.append(" ");
3709                buf.append(hostingNameStr);
3710            }
3711            Slog.i(TAG, buf.toString());
3712            app.setPid(startResult.pid);
3713            app.usingWrapper = startResult.usingWrapper;
3714            app.removed = false;
3715            app.killed = false;
3716            app.killedByAm = false;
3717            checkTime(startTime, "startProcess: starting to update pids map");
3718            synchronized (mPidsSelfLocked) {
3719                this.mPidsSelfLocked.put(startResult.pid, app);
3720                if (isActivityProcess) {
3721                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3722                    msg.obj = app;
3723                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3724                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3725                }
3726            }
3727            checkTime(startTime, "startProcess: done updating pids map");
3728        } catch (RuntimeException e) {
3729            // XXX do better error recovery.
3730            app.setPid(0);
3731            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3732            if (app.isolated) {
3733                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3734            }
3735            Slog.e(TAG, "Failure starting process " + app.processName, e);
3736        }
3737    }
3738
3739    void updateUsageStats(ActivityRecord component, boolean resumed) {
3740        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3741                "updateUsageStats: comp=" + component + "res=" + resumed);
3742        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3743        if (resumed) {
3744            if (mUsageStatsService != null) {
3745                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3746                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3747            }
3748            synchronized (stats) {
3749                stats.noteActivityResumedLocked(component.app.uid);
3750            }
3751        } else {
3752            if (mUsageStatsService != null) {
3753                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3754                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3755            }
3756            synchronized (stats) {
3757                stats.noteActivityPausedLocked(component.app.uid);
3758            }
3759        }
3760    }
3761
3762    Intent getHomeIntent() {
3763        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3764        intent.setComponent(mTopComponent);
3765        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3766        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3767            intent.addCategory(Intent.CATEGORY_HOME);
3768        }
3769        return intent;
3770    }
3771
3772    boolean startHomeActivityLocked(int userId, String reason) {
3773        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3774                && mTopAction == null) {
3775            // We are running in factory test mode, but unable to find
3776            // the factory test app, so just sit around displaying the
3777            // error message and don't try to start anything.
3778            return false;
3779        }
3780        Intent intent = getHomeIntent();
3781        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3782        if (aInfo != null) {
3783            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3784            // Don't do this if the home app is currently being
3785            // instrumented.
3786            aInfo = new ActivityInfo(aInfo);
3787            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3788            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3789                    aInfo.applicationInfo.uid, true);
3790            if (app == null || app.instrumentationClass == null) {
3791                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3792                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3793            }
3794        }
3795
3796        return true;
3797    }
3798
3799    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3800        ActivityInfo ai = null;
3801        ComponentName comp = intent.getComponent();
3802        try {
3803            if (comp != null) {
3804                // Factory test.
3805                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3806            } else {
3807                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3808                        intent,
3809                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3810                        flags, userId);
3811
3812                if (info != null) {
3813                    ai = info.activityInfo;
3814                }
3815            }
3816        } catch (RemoteException e) {
3817            // ignore
3818        }
3819
3820        return ai;
3821    }
3822
3823    /**
3824     * Starts the "new version setup screen" if appropriate.
3825     */
3826    void startSetupActivityLocked() {
3827        // Only do this once per boot.
3828        if (mCheckedForSetup) {
3829            return;
3830        }
3831
3832        // We will show this screen if the current one is a different
3833        // version than the last one shown, and we are not running in
3834        // low-level factory test mode.
3835        final ContentResolver resolver = mContext.getContentResolver();
3836        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3837                Settings.Global.getInt(resolver,
3838                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3839            mCheckedForSetup = true;
3840
3841            // See if we should be showing the platform update setup UI.
3842            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3843            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3844                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3845            if (!ris.isEmpty()) {
3846                final ResolveInfo ri = ris.get(0);
3847                String vers = ri.activityInfo.metaData != null
3848                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3849                        : null;
3850                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3851                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3852                            Intent.METADATA_SETUP_VERSION);
3853                }
3854                String lastVers = Settings.Secure.getString(
3855                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3856                if (vers != null && !vers.equals(lastVers)) {
3857                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3858                    intent.setComponent(new ComponentName(
3859                            ri.activityInfo.packageName, ri.activityInfo.name));
3860                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3861                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3862                            null, 0, 0, 0, null, false, false, null, null, null);
3863                }
3864            }
3865        }
3866    }
3867
3868    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3869        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3870    }
3871
3872    void enforceNotIsolatedCaller(String caller) {
3873        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3874            throw new SecurityException("Isolated process not allowed to call " + caller);
3875        }
3876    }
3877
3878    void enforceShellRestriction(String restriction, int userHandle) {
3879        if (Binder.getCallingUid() == Process.SHELL_UID) {
3880            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3881                throw new SecurityException("Shell does not have permission to access user "
3882                        + userHandle);
3883            }
3884        }
3885    }
3886
3887    @Override
3888    public int getFrontActivityScreenCompatMode() {
3889        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3890        synchronized (this) {
3891            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3892        }
3893    }
3894
3895    @Override
3896    public void setFrontActivityScreenCompatMode(int mode) {
3897        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3898                "setFrontActivityScreenCompatMode");
3899        synchronized (this) {
3900            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3901        }
3902    }
3903
3904    @Override
3905    public int getPackageScreenCompatMode(String packageName) {
3906        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3907        synchronized (this) {
3908            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3909        }
3910    }
3911
3912    @Override
3913    public void setPackageScreenCompatMode(String packageName, int mode) {
3914        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3915                "setPackageScreenCompatMode");
3916        synchronized (this) {
3917            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3918        }
3919    }
3920
3921    @Override
3922    public boolean getPackageAskScreenCompat(String packageName) {
3923        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3924        synchronized (this) {
3925            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3926        }
3927    }
3928
3929    @Override
3930    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3931        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3932                "setPackageAskScreenCompat");
3933        synchronized (this) {
3934            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3935        }
3936    }
3937
3938    private boolean hasUsageStatsPermission(String callingPackage) {
3939        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3940                Binder.getCallingUid(), callingPackage);
3941        if (mode == AppOpsManager.MODE_DEFAULT) {
3942            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3943                    == PackageManager.PERMISSION_GRANTED;
3944        }
3945        return mode == AppOpsManager.MODE_ALLOWED;
3946    }
3947
3948    @Override
3949    public int getPackageProcessState(String packageName, String callingPackage) {
3950        if (!hasUsageStatsPermission(callingPackage)) {
3951            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3952                    "getPackageProcessState");
3953        }
3954
3955        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3956        synchronized (this) {
3957            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3958                final ProcessRecord proc = mLruProcesses.get(i);
3959                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3960                        || procState > proc.setProcState) {
3961                    boolean found = false;
3962                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3963                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3964                            procState = proc.setProcState;
3965                            found = true;
3966                        }
3967                    }
3968                    if (proc.pkgDeps != null && !found) {
3969                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3970                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3971                                procState = proc.setProcState;
3972                                break;
3973                            }
3974                        }
3975                    }
3976                }
3977            }
3978        }
3979        return procState;
3980    }
3981
3982    @Override
3983    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3984        synchronized (this) {
3985            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3986            if (app == null) {
3987                return false;
3988            }
3989            if (app.trimMemoryLevel < level && app.thread != null &&
3990                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3991                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3992                try {
3993                    app.thread.scheduleTrimMemory(level);
3994                    app.trimMemoryLevel = level;
3995                    return true;
3996                } catch (RemoteException e) {
3997                    // Fallthrough to failure case.
3998                }
3999            }
4000        }
4001        return false;
4002    }
4003
4004    private void dispatchProcessesChanged() {
4005        int N;
4006        synchronized (this) {
4007            N = mPendingProcessChanges.size();
4008            if (mActiveProcessChanges.length < N) {
4009                mActiveProcessChanges = new ProcessChangeItem[N];
4010            }
4011            mPendingProcessChanges.toArray(mActiveProcessChanges);
4012            mPendingProcessChanges.clear();
4013            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4014                    "*** Delivering " + N + " process changes");
4015        }
4016
4017        int i = mProcessObservers.beginBroadcast();
4018        while (i > 0) {
4019            i--;
4020            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4021            if (observer != null) {
4022                try {
4023                    for (int j=0; j<N; j++) {
4024                        ProcessChangeItem item = mActiveProcessChanges[j];
4025                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4026                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4027                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4028                                    + item.uid + ": " + item.foregroundActivities);
4029                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4030                                    item.foregroundActivities);
4031                        }
4032                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4033                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4034                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4035                                    + ": " + item.processState);
4036                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4037                        }
4038                    }
4039                } catch (RemoteException e) {
4040                }
4041            }
4042        }
4043        mProcessObservers.finishBroadcast();
4044
4045        synchronized (this) {
4046            for (int j=0; j<N; j++) {
4047                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4048            }
4049        }
4050    }
4051
4052    private void dispatchProcessDied(int pid, int uid) {
4053        int i = mProcessObservers.beginBroadcast();
4054        while (i > 0) {
4055            i--;
4056            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4057            if (observer != null) {
4058                try {
4059                    observer.onProcessDied(pid, uid);
4060                } catch (RemoteException e) {
4061                }
4062            }
4063        }
4064        mProcessObservers.finishBroadcast();
4065    }
4066
4067    private void dispatchUidsChanged() {
4068        int N;
4069        synchronized (this) {
4070            N = mPendingUidChanges.size();
4071            if (mActiveUidChanges.length < N) {
4072                mActiveUidChanges = new UidRecord.ChangeItem[N];
4073            }
4074            for (int i=0; i<N; i++) {
4075                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4076                mActiveUidChanges[i] = change;
4077                if (change.uidRecord != null) {
4078                    change.uidRecord.pendingChange = null;
4079                    change.uidRecord = null;
4080                }
4081            }
4082            mPendingUidChanges.clear();
4083            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4084                    "*** Delivering " + N + " uid changes");
4085        }
4086
4087        if (mLocalPowerManager != null) {
4088            for (int j=0; j<N; j++) {
4089                UidRecord.ChangeItem item = mActiveUidChanges[j];
4090                if (item.change == UidRecord.CHANGE_GONE
4091                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4092                    mLocalPowerManager.uidGone(item.uid);
4093                } else {
4094                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4095                }
4096            }
4097        }
4098
4099        int i = mUidObservers.beginBroadcast();
4100        while (i > 0) {
4101            i--;
4102            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4103            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4104            if (observer != null) {
4105                try {
4106                    for (int j=0; j<N; j++) {
4107                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4108                        final int change = item.change;
4109                        UidRecord validateUid = null;
4110                        if (VALIDATE_UID_STATES && i == 0) {
4111                            validateUid = mValidateUids.get(item.uid);
4112                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4113                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4114                                validateUid = new UidRecord(item.uid);
4115                                mValidateUids.put(item.uid, validateUid);
4116                            }
4117                        }
4118                        if (change == UidRecord.CHANGE_IDLE
4119                                || change == UidRecord.CHANGE_GONE_IDLE) {
4120                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4121                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4122                                        "UID idle uid=" + item.uid);
4123                                observer.onUidIdle(item.uid);
4124                            }
4125                            if (VALIDATE_UID_STATES && i == 0) {
4126                                if (validateUid != null) {
4127                                    validateUid.idle = true;
4128                                }
4129                            }
4130                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4131                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4132                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4133                                        "UID active uid=" + item.uid);
4134                                observer.onUidActive(item.uid);
4135                            }
4136                            if (VALIDATE_UID_STATES && i == 0) {
4137                                validateUid.idle = false;
4138                            }
4139                        }
4140                        if (change == UidRecord.CHANGE_GONE
4141                                || change == UidRecord.CHANGE_GONE_IDLE) {
4142                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4143                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4144                                        "UID gone uid=" + item.uid);
4145                                observer.onUidGone(item.uid);
4146                            }
4147                            if (VALIDATE_UID_STATES && i == 0) {
4148                                if (validateUid != null) {
4149                                    mValidateUids.remove(item.uid);
4150                                }
4151                            }
4152                        } else {
4153                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4154                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4155                                        "UID CHANGED uid=" + item.uid
4156                                                + ": " + item.processState);
4157                                observer.onUidStateChanged(item.uid, item.processState);
4158                            }
4159                            if (VALIDATE_UID_STATES && i == 0) {
4160                                validateUid.curProcState = validateUid.setProcState
4161                                        = item.processState;
4162                            }
4163                        }
4164                    }
4165                } catch (RemoteException e) {
4166                }
4167            }
4168        }
4169        mUidObservers.finishBroadcast();
4170
4171        synchronized (this) {
4172            for (int j=0; j<N; j++) {
4173                mAvailUidChanges.add(mActiveUidChanges[j]);
4174            }
4175        }
4176    }
4177
4178    @Override
4179    public final int startActivity(IApplicationThread caller, String callingPackage,
4180            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4181            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4182        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4183                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4184                UserHandle.getCallingUserId());
4185    }
4186
4187    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4188        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4189        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4190                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4191                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4192
4193        // TODO: Switch to user app stacks here.
4194        String mimeType = intent.getType();
4195        final Uri data = intent.getData();
4196        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4197            mimeType = getProviderMimeType(data, userId);
4198        }
4199        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4200
4201        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4202        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4203                null, 0, 0, null, null, null, null, false, userId, container, null);
4204    }
4205
4206    @Override
4207    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4208            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4209            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4210        enforceNotIsolatedCaller("startActivity");
4211        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4212                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4213        // TODO: Switch to user app stacks here.
4214        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4215                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4216                profilerInfo, null, null, bOptions, false, userId, null, null);
4217    }
4218
4219    @Override
4220    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4221            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4222            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4223            int userId) {
4224
4225        // This is very dangerous -- it allows you to perform a start activity (including
4226        // permission grants) as any app that may launch one of your own activities.  So
4227        // we will only allow this to be done from activities that are part of the core framework,
4228        // and then only when they are running as the system.
4229        final ActivityRecord sourceRecord;
4230        final int targetUid;
4231        final String targetPackage;
4232        synchronized (this) {
4233            if (resultTo == null) {
4234                throw new SecurityException("Must be called from an activity");
4235            }
4236            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4237            if (sourceRecord == null) {
4238                throw new SecurityException("Called with bad activity token: " + resultTo);
4239            }
4240            if (!sourceRecord.info.packageName.equals("android")) {
4241                throw new SecurityException(
4242                        "Must be called from an activity that is declared in the android package");
4243            }
4244            if (sourceRecord.app == null) {
4245                throw new SecurityException("Called without a process attached to activity");
4246            }
4247            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4248                // This is still okay, as long as this activity is running under the
4249                // uid of the original calling activity.
4250                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4251                    throw new SecurityException(
4252                            "Calling activity in uid " + sourceRecord.app.uid
4253                                    + " must be system uid or original calling uid "
4254                                    + sourceRecord.launchedFromUid);
4255                }
4256            }
4257            if (ignoreTargetSecurity) {
4258                if (intent.getComponent() == null) {
4259                    throw new SecurityException(
4260                            "Component must be specified with ignoreTargetSecurity");
4261                }
4262                if (intent.getSelector() != null) {
4263                    throw new SecurityException(
4264                            "Selector not allowed with ignoreTargetSecurity");
4265                }
4266            }
4267            targetUid = sourceRecord.launchedFromUid;
4268            targetPackage = sourceRecord.launchedFromPackage;
4269        }
4270
4271        if (userId == UserHandle.USER_NULL) {
4272            userId = UserHandle.getUserId(sourceRecord.app.uid);
4273        }
4274
4275        // TODO: Switch to user app stacks here.
4276        try {
4277            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4278                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4279                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4280            return ret;
4281        } catch (SecurityException e) {
4282            // XXX need to figure out how to propagate to original app.
4283            // A SecurityException here is generally actually a fault of the original
4284            // calling activity (such as a fairly granting permissions), so propagate it
4285            // back to them.
4286            /*
4287            StringBuilder msg = new StringBuilder();
4288            msg.append("While launching");
4289            msg.append(intent.toString());
4290            msg.append(": ");
4291            msg.append(e.getMessage());
4292            */
4293            throw e;
4294        }
4295    }
4296
4297    @Override
4298    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4299            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4300            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4301        enforceNotIsolatedCaller("startActivityAndWait");
4302        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4303                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4304        WaitResult res = new WaitResult();
4305        // TODO: Switch to user app stacks here.
4306        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4307                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4308                bOptions, false, userId, null, null);
4309        return res;
4310    }
4311
4312    @Override
4313    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4314            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4315            int startFlags, Configuration config, Bundle bOptions, int userId) {
4316        enforceNotIsolatedCaller("startActivityWithConfig");
4317        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4318                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4319        // TODO: Switch to user app stacks here.
4320        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4321                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4322                null, null, config, bOptions, false, userId, null, null);
4323        return ret;
4324    }
4325
4326    @Override
4327    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4328            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4329            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4330            throws TransactionTooLargeException {
4331        enforceNotIsolatedCaller("startActivityIntentSender");
4332        // Refuse possible leaked file descriptors
4333        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4334            throw new IllegalArgumentException("File descriptors passed in Intent");
4335        }
4336
4337        IIntentSender sender = intent.getTarget();
4338        if (!(sender instanceof PendingIntentRecord)) {
4339            throw new IllegalArgumentException("Bad PendingIntent object");
4340        }
4341
4342        PendingIntentRecord pir = (PendingIntentRecord)sender;
4343
4344        synchronized (this) {
4345            // If this is coming from the currently resumed activity, it is
4346            // effectively saying that app switches are allowed at this point.
4347            final ActivityStack stack = getFocusedStack();
4348            if (stack.mResumedActivity != null &&
4349                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4350                mAppSwitchesAllowedTime = 0;
4351            }
4352        }
4353        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4354                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4355        return ret;
4356    }
4357
4358    @Override
4359    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4360            Intent intent, String resolvedType, IVoiceInteractionSession session,
4361            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4362            Bundle bOptions, int userId) {
4363        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4364                != PackageManager.PERMISSION_GRANTED) {
4365            String msg = "Permission Denial: startVoiceActivity() from pid="
4366                    + Binder.getCallingPid()
4367                    + ", uid=" + Binder.getCallingUid()
4368                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4369            Slog.w(TAG, msg);
4370            throw new SecurityException(msg);
4371        }
4372        if (session == null || interactor == null) {
4373            throw new NullPointerException("null session or interactor");
4374        }
4375        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4376                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4377        // TODO: Switch to user app stacks here.
4378        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4379                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4380                null, bOptions, false, userId, null, null);
4381    }
4382
4383    @Override
4384    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4385            throws RemoteException {
4386        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4387        synchronized (this) {
4388            ActivityRecord activity = getFocusedStack().topActivity();
4389            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4390                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4391            }
4392            if (mRunningVoice != null || activity.task.voiceSession != null
4393                    || activity.voiceSession != null) {
4394                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4395                return;
4396            }
4397            if (activity.pendingVoiceInteractionStart) {
4398                Slog.w(TAG, "Pending start of voice interaction already.");
4399                return;
4400            }
4401            activity.pendingVoiceInteractionStart = true;
4402        }
4403        LocalServices.getService(VoiceInteractionManagerInternal.class)
4404                .startLocalVoiceInteraction(callingActivity, options);
4405    }
4406
4407    @Override
4408    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4409        LocalServices.getService(VoiceInteractionManagerInternal.class)
4410                .stopLocalVoiceInteraction(callingActivity);
4411    }
4412
4413    @Override
4414    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4415        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4416                .supportsLocalVoiceInteraction();
4417    }
4418
4419    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4420            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4421        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4422        if (activityToCallback == null) return;
4423        activityToCallback.setVoiceSessionLocked(voiceSession);
4424
4425        // Inform the activity
4426        try {
4427            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4428                    voiceInteractor);
4429            long token = Binder.clearCallingIdentity();
4430            try {
4431                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4432            } finally {
4433                Binder.restoreCallingIdentity(token);
4434            }
4435            // TODO: VI Should we cache the activity so that it's easier to find later
4436            // rather than scan through all the stacks and activities?
4437        } catch (RemoteException re) {
4438            activityToCallback.clearVoiceSessionLocked();
4439            // TODO: VI Should this terminate the voice session?
4440        }
4441    }
4442
4443    @Override
4444    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4445        synchronized (this) {
4446            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4447                if (keepAwake) {
4448                    mVoiceWakeLock.acquire();
4449                } else {
4450                    mVoiceWakeLock.release();
4451                }
4452            }
4453        }
4454    }
4455
4456    @Override
4457    public boolean startNextMatchingActivity(IBinder callingActivity,
4458            Intent intent, Bundle bOptions) {
4459        // Refuse possible leaked file descriptors
4460        if (intent != null && intent.hasFileDescriptors() == true) {
4461            throw new IllegalArgumentException("File descriptors passed in Intent");
4462        }
4463        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4464
4465        synchronized (this) {
4466            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4467            if (r == null) {
4468                ActivityOptions.abort(options);
4469                return false;
4470            }
4471            if (r.app == null || r.app.thread == null) {
4472                // The caller is not running...  d'oh!
4473                ActivityOptions.abort(options);
4474                return false;
4475            }
4476            intent = new Intent(intent);
4477            // The caller is not allowed to change the data.
4478            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4479            // And we are resetting to find the next component...
4480            intent.setComponent(null);
4481
4482            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4483
4484            ActivityInfo aInfo = null;
4485            try {
4486                List<ResolveInfo> resolves =
4487                    AppGlobals.getPackageManager().queryIntentActivities(
4488                            intent, r.resolvedType,
4489                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4490                            UserHandle.getCallingUserId()).getList();
4491
4492                // Look for the original activity in the list...
4493                final int N = resolves != null ? resolves.size() : 0;
4494                for (int i=0; i<N; i++) {
4495                    ResolveInfo rInfo = resolves.get(i);
4496                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4497                            && rInfo.activityInfo.name.equals(r.info.name)) {
4498                        // We found the current one...  the next matching is
4499                        // after it.
4500                        i++;
4501                        if (i<N) {
4502                            aInfo = resolves.get(i).activityInfo;
4503                        }
4504                        if (debug) {
4505                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4506                                    + "/" + r.info.name);
4507                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4508                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4509                        }
4510                        break;
4511                    }
4512                }
4513            } catch (RemoteException e) {
4514            }
4515
4516            if (aInfo == null) {
4517                // Nobody who is next!
4518                ActivityOptions.abort(options);
4519                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4520                return false;
4521            }
4522
4523            intent.setComponent(new ComponentName(
4524                    aInfo.applicationInfo.packageName, aInfo.name));
4525            intent.setFlags(intent.getFlags()&~(
4526                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4527                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4528                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4529                    Intent.FLAG_ACTIVITY_NEW_TASK));
4530
4531            // Okay now we need to start the new activity, replacing the
4532            // currently running activity.  This is a little tricky because
4533            // we want to start the new one as if the current one is finished,
4534            // but not finish the current one first so that there is no flicker.
4535            // And thus...
4536            final boolean wasFinishing = r.finishing;
4537            r.finishing = true;
4538
4539            // Propagate reply information over to the new activity.
4540            final ActivityRecord resultTo = r.resultTo;
4541            final String resultWho = r.resultWho;
4542            final int requestCode = r.requestCode;
4543            r.resultTo = null;
4544            if (resultTo != null) {
4545                resultTo.removeResultsLocked(r, resultWho, requestCode);
4546            }
4547
4548            final long origId = Binder.clearCallingIdentity();
4549            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4550                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4551                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4552                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4553                    false, false, null, null, null);
4554            Binder.restoreCallingIdentity(origId);
4555
4556            r.finishing = wasFinishing;
4557            if (res != ActivityManager.START_SUCCESS) {
4558                return false;
4559            }
4560            return true;
4561        }
4562    }
4563
4564    @Override
4565    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4566        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4567            String msg = "Permission Denial: startActivityFromRecents called without " +
4568                    START_TASKS_FROM_RECENTS;
4569            Slog.w(TAG, msg);
4570            throw new SecurityException(msg);
4571        }
4572        final long origId = Binder.clearCallingIdentity();
4573        try {
4574            synchronized (this) {
4575                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4576            }
4577        } finally {
4578            Binder.restoreCallingIdentity(origId);
4579        }
4580    }
4581
4582    final int startActivityInPackage(int uid, String callingPackage,
4583            Intent intent, String resolvedType, IBinder resultTo,
4584            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4585            IActivityContainer container, TaskRecord inTask) {
4586
4587        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4588                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4589
4590        // TODO: Switch to user app stacks here.
4591        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4592                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4593                null, null, null, bOptions, false, userId, container, inTask);
4594        return ret;
4595    }
4596
4597    @Override
4598    public final int startActivities(IApplicationThread caller, String callingPackage,
4599            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4600            int userId) {
4601        enforceNotIsolatedCaller("startActivities");
4602        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4603                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4604        // TODO: Switch to user app stacks here.
4605        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4606                resolvedTypes, resultTo, bOptions, userId);
4607        return ret;
4608    }
4609
4610    final int startActivitiesInPackage(int uid, String callingPackage,
4611            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4612            Bundle bOptions, int userId) {
4613
4614        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4615                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4616        // TODO: Switch to user app stacks here.
4617        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4618                resultTo, bOptions, userId);
4619        return ret;
4620    }
4621
4622    @Override
4623    public void reportActivityFullyDrawn(IBinder token) {
4624        synchronized (this) {
4625            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4626            if (r == null) {
4627                return;
4628            }
4629            r.reportFullyDrawnLocked();
4630        }
4631    }
4632
4633    @Override
4634    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4635        synchronized (this) {
4636            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4637            if (r == null) {
4638                return;
4639            }
4640            TaskRecord task = r.task;
4641            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4642                // Fixed screen orientation isn't supported when activities aren't in full screen
4643                // mode.
4644                return;
4645            }
4646            final long origId = Binder.clearCallingIdentity();
4647            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4648            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4649                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4650            if (config != null) {
4651                r.frozenBeforeDestroy = true;
4652                if (!updateConfigurationLocked(config, r, false)) {
4653                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4654                }
4655            }
4656            Binder.restoreCallingIdentity(origId);
4657        }
4658    }
4659
4660    @Override
4661    public int getRequestedOrientation(IBinder token) {
4662        synchronized (this) {
4663            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4664            if (r == null) {
4665                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4666            }
4667            return mWindowManager.getAppOrientation(r.appToken);
4668        }
4669    }
4670
4671    /**
4672     * This is the internal entry point for handling Activity.finish().
4673     *
4674     * @param token The Binder token referencing the Activity we want to finish.
4675     * @param resultCode Result code, if any, from this Activity.
4676     * @param resultData Result data (Intent), if any, from this Activity.
4677     * @param finishTask Whether to finish the task associated with this Activity.
4678     *
4679     * @return Returns true if the activity successfully finished, or false if it is still running.
4680     */
4681    @Override
4682    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4683            int finishTask) {
4684        // Refuse possible leaked file descriptors
4685        if (resultData != null && resultData.hasFileDescriptors() == true) {
4686            throw new IllegalArgumentException("File descriptors passed in Intent");
4687        }
4688
4689        synchronized(this) {
4690            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4691            if (r == null) {
4692                return true;
4693            }
4694            // Keep track of the root activity of the task before we finish it
4695            TaskRecord tr = r.task;
4696            ActivityRecord rootR = tr.getRootActivity();
4697            if (rootR == null) {
4698                Slog.w(TAG, "Finishing task with all activities already finished");
4699            }
4700            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4701            // finish.
4702            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4703                    mStackSupervisor.isLastLockedTask(tr)) {
4704                Slog.i(TAG, "Not finishing task in lock task mode");
4705                mStackSupervisor.showLockTaskToast();
4706                return false;
4707            }
4708            if (mController != null) {
4709                // Find the first activity that is not finishing.
4710                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4711                if (next != null) {
4712                    // ask watcher if this is allowed
4713                    boolean resumeOK = true;
4714                    try {
4715                        resumeOK = mController.activityResuming(next.packageName);
4716                    } catch (RemoteException e) {
4717                        mController = null;
4718                        Watchdog.getInstance().setActivityController(null);
4719                    }
4720
4721                    if (!resumeOK) {
4722                        Slog.i(TAG, "Not finishing activity because controller resumed");
4723                        return false;
4724                    }
4725                }
4726            }
4727            final long origId = Binder.clearCallingIdentity();
4728            try {
4729                boolean res;
4730                final boolean finishWithRootActivity =
4731                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4732                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4733                        || (finishWithRootActivity && r == rootR)) {
4734                    // If requested, remove the task that is associated to this activity only if it
4735                    // was the root activity in the task. The result code and data is ignored
4736                    // because we don't support returning them across task boundaries. Also, to
4737                    // keep backwards compatibility we remove the task from recents when finishing
4738                    // task with root activity.
4739                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4740                    if (!res) {
4741                        Slog.i(TAG, "Removing task failed to finish activity");
4742                    }
4743                } else {
4744                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4745                            resultData, "app-request", true);
4746                    if (!res) {
4747                        Slog.i(TAG, "Failed to finish by app-request");
4748                    }
4749                }
4750                return res;
4751            } finally {
4752                Binder.restoreCallingIdentity(origId);
4753            }
4754        }
4755    }
4756
4757    @Override
4758    public final void finishHeavyWeightApp() {
4759        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4760                != PackageManager.PERMISSION_GRANTED) {
4761            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4762                    + Binder.getCallingPid()
4763                    + ", uid=" + Binder.getCallingUid()
4764                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4765            Slog.w(TAG, msg);
4766            throw new SecurityException(msg);
4767        }
4768
4769        synchronized(this) {
4770            if (mHeavyWeightProcess == null) {
4771                return;
4772            }
4773
4774            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4775            for (int i = 0; i < activities.size(); i++) {
4776                ActivityRecord r = activities.get(i);
4777                if (!r.finishing && r.isInStackLocked()) {
4778                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4779                            null, "finish-heavy", true);
4780                }
4781            }
4782
4783            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4784                    mHeavyWeightProcess.userId, 0));
4785            mHeavyWeightProcess = null;
4786        }
4787    }
4788
4789    @Override
4790    public void crashApplication(int uid, int initialPid, String packageName,
4791            String message) {
4792        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4793                != PackageManager.PERMISSION_GRANTED) {
4794            String msg = "Permission Denial: crashApplication() from pid="
4795                    + Binder.getCallingPid()
4796                    + ", uid=" + Binder.getCallingUid()
4797                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4798            Slog.w(TAG, msg);
4799            throw new SecurityException(msg);
4800        }
4801
4802        synchronized(this) {
4803            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4804        }
4805    }
4806
4807    @Override
4808    public final void finishSubActivity(IBinder token, String resultWho,
4809            int requestCode) {
4810        synchronized(this) {
4811            final long origId = Binder.clearCallingIdentity();
4812            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4813            if (r != null) {
4814                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4815            }
4816            Binder.restoreCallingIdentity(origId);
4817        }
4818    }
4819
4820    @Override
4821    public boolean finishActivityAffinity(IBinder token) {
4822        synchronized(this) {
4823            final long origId = Binder.clearCallingIdentity();
4824            try {
4825                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4826                if (r == null) {
4827                    return false;
4828                }
4829
4830                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4831                // can finish.
4832                final TaskRecord task = r.task;
4833                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4834                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4835                    mStackSupervisor.showLockTaskToast();
4836                    return false;
4837                }
4838                return task.stack.finishActivityAffinityLocked(r);
4839            } finally {
4840                Binder.restoreCallingIdentity(origId);
4841            }
4842        }
4843    }
4844
4845    @Override
4846    public void finishVoiceTask(IVoiceInteractionSession session) {
4847        synchronized (this) {
4848            final long origId = Binder.clearCallingIdentity();
4849            try {
4850                // TODO: VI Consider treating local voice interactions and voice tasks
4851                // differently here
4852                mStackSupervisor.finishVoiceTask(session);
4853            } finally {
4854                Binder.restoreCallingIdentity(origId);
4855            }
4856        }
4857
4858    }
4859
4860    @Override
4861    public boolean releaseActivityInstance(IBinder token) {
4862        synchronized(this) {
4863            final long origId = Binder.clearCallingIdentity();
4864            try {
4865                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4866                if (r == null) {
4867                    return false;
4868                }
4869                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4870            } finally {
4871                Binder.restoreCallingIdentity(origId);
4872            }
4873        }
4874    }
4875
4876    @Override
4877    public void releaseSomeActivities(IApplicationThread appInt) {
4878        synchronized(this) {
4879            final long origId = Binder.clearCallingIdentity();
4880            try {
4881                ProcessRecord app = getRecordForAppLocked(appInt);
4882                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4883            } finally {
4884                Binder.restoreCallingIdentity(origId);
4885            }
4886        }
4887    }
4888
4889    @Override
4890    public boolean willActivityBeVisible(IBinder token) {
4891        synchronized(this) {
4892            ActivityStack stack = ActivityRecord.getStackLocked(token);
4893            if (stack != null) {
4894                return stack.willActivityBeVisibleLocked(token);
4895            }
4896            return false;
4897        }
4898    }
4899
4900    @Override
4901    public void overridePendingTransition(IBinder token, String packageName,
4902            int enterAnim, int exitAnim) {
4903        synchronized(this) {
4904            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4905            if (self == null) {
4906                return;
4907            }
4908
4909            final long origId = Binder.clearCallingIdentity();
4910
4911            if (self.state == ActivityState.RESUMED
4912                    || self.state == ActivityState.PAUSING) {
4913                mWindowManager.overridePendingAppTransition(packageName,
4914                        enterAnim, exitAnim, null);
4915            }
4916
4917            Binder.restoreCallingIdentity(origId);
4918        }
4919    }
4920
4921    /**
4922     * Main function for removing an existing process from the activity manager
4923     * as a result of that process going away.  Clears out all connections
4924     * to the process.
4925     */
4926    private final void handleAppDiedLocked(ProcessRecord app,
4927            boolean restarting, boolean allowRestart) {
4928        int pid = app.pid;
4929        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4930        if (!kept && !restarting) {
4931            removeLruProcessLocked(app);
4932            if (pid > 0) {
4933                ProcessList.remove(pid);
4934            }
4935        }
4936
4937        if (mProfileProc == app) {
4938            clearProfilerLocked();
4939        }
4940
4941        // Remove this application's activities from active lists.
4942        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4943
4944        app.activities.clear();
4945
4946        if (app.instrumentationClass != null) {
4947            Slog.w(TAG, "Crash of app " + app.processName
4948                  + " running instrumentation " + app.instrumentationClass);
4949            Bundle info = new Bundle();
4950            info.putString("shortMsg", "Process crashed.");
4951            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4952        }
4953
4954        if (!restarting && hasVisibleActivities
4955                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4956            // If there was nothing to resume, and we are not already restarting this process, but
4957            // there is a visible activity that is hosted by the process...  then make sure all
4958            // visible activities are running, taking care of restarting this process.
4959            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4960        }
4961    }
4962
4963    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4964        IBinder threadBinder = thread.asBinder();
4965        // Find the application record.
4966        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4967            ProcessRecord rec = mLruProcesses.get(i);
4968            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4969                return i;
4970            }
4971        }
4972        return -1;
4973    }
4974
4975    final ProcessRecord getRecordForAppLocked(
4976            IApplicationThread thread) {
4977        if (thread == null) {
4978            return null;
4979        }
4980
4981        int appIndex = getLRURecordIndexForAppLocked(thread);
4982        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4983    }
4984
4985    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4986        // If there are no longer any background processes running,
4987        // and the app that died was not running instrumentation,
4988        // then tell everyone we are now low on memory.
4989        boolean haveBg = false;
4990        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4991            ProcessRecord rec = mLruProcesses.get(i);
4992            if (rec.thread != null
4993                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4994                haveBg = true;
4995                break;
4996            }
4997        }
4998
4999        if (!haveBg) {
5000            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5001            if (doReport) {
5002                long now = SystemClock.uptimeMillis();
5003                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5004                    doReport = false;
5005                } else {
5006                    mLastMemUsageReportTime = now;
5007                }
5008            }
5009            final ArrayList<ProcessMemInfo> memInfos
5010                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5011            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5012            long now = SystemClock.uptimeMillis();
5013            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5014                ProcessRecord rec = mLruProcesses.get(i);
5015                if (rec == dyingProc || rec.thread == null) {
5016                    continue;
5017                }
5018                if (doReport) {
5019                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5020                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5021                }
5022                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5023                    // The low memory report is overriding any current
5024                    // state for a GC request.  Make sure to do
5025                    // heavy/important/visible/foreground processes first.
5026                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5027                        rec.lastRequestedGc = 0;
5028                    } else {
5029                        rec.lastRequestedGc = rec.lastLowMemory;
5030                    }
5031                    rec.reportLowMemory = true;
5032                    rec.lastLowMemory = now;
5033                    mProcessesToGc.remove(rec);
5034                    addProcessToGcListLocked(rec);
5035                }
5036            }
5037            if (doReport) {
5038                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5039                mHandler.sendMessage(msg);
5040            }
5041            scheduleAppGcsLocked();
5042        }
5043    }
5044
5045    final void appDiedLocked(ProcessRecord app) {
5046       appDiedLocked(app, app.pid, app.thread, false);
5047    }
5048
5049    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5050            boolean fromBinderDied) {
5051        // First check if this ProcessRecord is actually active for the pid.
5052        synchronized (mPidsSelfLocked) {
5053            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5054            if (curProc != app) {
5055                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5056                return;
5057            }
5058        }
5059
5060        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5061        synchronized (stats) {
5062            stats.noteProcessDiedLocked(app.info.uid, pid);
5063        }
5064
5065        if (!app.killed) {
5066            if (!fromBinderDied) {
5067                Process.killProcessQuiet(pid);
5068            }
5069            killProcessGroup(app.uid, pid);
5070            app.killed = true;
5071        }
5072
5073        // Clean up already done if the process has been re-started.
5074        if (app.pid == pid && app.thread != null &&
5075                app.thread.asBinder() == thread.asBinder()) {
5076            boolean doLowMem = app.instrumentationClass == null;
5077            boolean doOomAdj = doLowMem;
5078            if (!app.killedByAm) {
5079                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5080                        + ") has died");
5081                mAllowLowerMemLevel = true;
5082            } else {
5083                // Note that we always want to do oom adj to update our state with the
5084                // new number of procs.
5085                mAllowLowerMemLevel = false;
5086                doLowMem = false;
5087            }
5088            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5089            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5090                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5091            handleAppDiedLocked(app, false, true);
5092
5093            if (doOomAdj) {
5094                updateOomAdjLocked();
5095            }
5096            if (doLowMem) {
5097                doLowMemReportIfNeededLocked(app);
5098            }
5099        } else if (app.pid != pid) {
5100            // A new process has already been started.
5101            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5102                    + ") has died and restarted (pid " + app.pid + ").");
5103            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5104        } else if (DEBUG_PROCESSES) {
5105            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5106                    + thread.asBinder());
5107        }
5108    }
5109
5110    /**
5111     * If a stack trace dump file is configured, dump process stack traces.
5112     * @param clearTraces causes the dump file to be erased prior to the new
5113     *    traces being written, if true; when false, the new traces will be
5114     *    appended to any existing file content.
5115     * @param firstPids of dalvik VM processes to dump stack traces for first
5116     * @param lastPids of dalvik VM processes to dump stack traces for last
5117     * @param nativeProcs optional list of native process names to dump stack crawls
5118     * @return file containing stack traces, or null if no dump file is configured
5119     */
5120    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5121            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5122        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5123        if (tracesPath == null || tracesPath.length() == 0) {
5124            return null;
5125        }
5126
5127        File tracesFile = new File(tracesPath);
5128        try {
5129            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5130            tracesFile.createNewFile();
5131            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5132        } catch (IOException e) {
5133            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5134            return null;
5135        }
5136
5137        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5138        return tracesFile;
5139    }
5140
5141    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5142            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5143        // Use a FileObserver to detect when traces finish writing.
5144        // The order of traces is considered important to maintain for legibility.
5145        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5146            @Override
5147            public synchronized void onEvent(int event, String path) { notify(); }
5148        };
5149
5150        try {
5151            observer.startWatching();
5152
5153            // First collect all of the stacks of the most important pids.
5154            if (firstPids != null) {
5155                try {
5156                    int num = firstPids.size();
5157                    for (int i = 0; i < num; i++) {
5158                        synchronized (observer) {
5159                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5160                                    + firstPids.get(i));
5161                            final long sime = SystemClock.elapsedRealtime();
5162                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5163                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5164                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5165                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5166                        }
5167                    }
5168                } catch (InterruptedException e) {
5169                    Slog.wtf(TAG, e);
5170                }
5171            }
5172
5173            // Next collect the stacks of the native pids
5174            if (nativeProcs != null) {
5175                int[] pids = Process.getPidsForCommands(nativeProcs);
5176                if (pids != null) {
5177                    for (int pid : pids) {
5178                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5179                        final long sime = SystemClock.elapsedRealtime();
5180                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5181                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5182                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5183                    }
5184                }
5185            }
5186
5187            // Lastly, measure CPU usage.
5188            if (processCpuTracker != null) {
5189                processCpuTracker.init();
5190                System.gc();
5191                processCpuTracker.update();
5192                try {
5193                    synchronized (processCpuTracker) {
5194                        processCpuTracker.wait(500); // measure over 1/2 second.
5195                    }
5196                } catch (InterruptedException e) {
5197                }
5198                processCpuTracker.update();
5199
5200                // We'll take the stack crawls of just the top apps using CPU.
5201                final int N = processCpuTracker.countWorkingStats();
5202                int numProcs = 0;
5203                for (int i=0; i<N && numProcs<5; i++) {
5204                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5205                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5206                        numProcs++;
5207                        try {
5208                            synchronized (observer) {
5209                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5210                                        + stats.pid);
5211                                final long stime = SystemClock.elapsedRealtime();
5212                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5213                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5214                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5215                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5216                            }
5217                        } catch (InterruptedException e) {
5218                            Slog.wtf(TAG, e);
5219                        }
5220                    } else if (DEBUG_ANR) {
5221                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5222                                + stats.pid);
5223                    }
5224                }
5225            }
5226        } finally {
5227            observer.stopWatching();
5228        }
5229    }
5230
5231    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5232        if (true || IS_USER_BUILD) {
5233            return;
5234        }
5235        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5236        if (tracesPath == null || tracesPath.length() == 0) {
5237            return;
5238        }
5239
5240        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5241        StrictMode.allowThreadDiskWrites();
5242        try {
5243            final File tracesFile = new File(tracesPath);
5244            final File tracesDir = tracesFile.getParentFile();
5245            final File tracesTmp = new File(tracesDir, "__tmp__");
5246            try {
5247                if (tracesFile.exists()) {
5248                    tracesTmp.delete();
5249                    tracesFile.renameTo(tracesTmp);
5250                }
5251                StringBuilder sb = new StringBuilder();
5252                Time tobj = new Time();
5253                tobj.set(System.currentTimeMillis());
5254                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5255                sb.append(": ");
5256                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5257                sb.append(" since ");
5258                sb.append(msg);
5259                FileOutputStream fos = new FileOutputStream(tracesFile);
5260                fos.write(sb.toString().getBytes());
5261                if (app == null) {
5262                    fos.write("\n*** No application process!".getBytes());
5263                }
5264                fos.close();
5265                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5266            } catch (IOException e) {
5267                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5268                return;
5269            }
5270
5271            if (app != null) {
5272                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5273                firstPids.add(app.pid);
5274                dumpStackTraces(tracesPath, firstPids, null, null, null);
5275            }
5276
5277            File lastTracesFile = null;
5278            File curTracesFile = null;
5279            for (int i=9; i>=0; i--) {
5280                String name = String.format(Locale.US, "slow%02d.txt", i);
5281                curTracesFile = new File(tracesDir, name);
5282                if (curTracesFile.exists()) {
5283                    if (lastTracesFile != null) {
5284                        curTracesFile.renameTo(lastTracesFile);
5285                    } else {
5286                        curTracesFile.delete();
5287                    }
5288                }
5289                lastTracesFile = curTracesFile;
5290            }
5291            tracesFile.renameTo(curTracesFile);
5292            if (tracesTmp.exists()) {
5293                tracesTmp.renameTo(tracesFile);
5294            }
5295        } finally {
5296            StrictMode.setThreadPolicy(oldPolicy);
5297        }
5298    }
5299
5300    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5301        if (!mLaunchWarningShown) {
5302            mLaunchWarningShown = true;
5303            mUiHandler.post(new Runnable() {
5304                @Override
5305                public void run() {
5306                    synchronized (ActivityManagerService.this) {
5307                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5308                        d.show();
5309                        mUiHandler.postDelayed(new Runnable() {
5310                            @Override
5311                            public void run() {
5312                                synchronized (ActivityManagerService.this) {
5313                                    d.dismiss();
5314                                    mLaunchWarningShown = false;
5315                                }
5316                            }
5317                        }, 4000);
5318                    }
5319                }
5320            });
5321        }
5322    }
5323
5324    @Override
5325    public boolean clearApplicationUserData(final String packageName,
5326            final IPackageDataObserver observer, int userId) {
5327        enforceNotIsolatedCaller("clearApplicationUserData");
5328        int uid = Binder.getCallingUid();
5329        int pid = Binder.getCallingPid();
5330        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5331                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5332
5333        final DevicePolicyManagerInternal dpmi = LocalServices
5334                .getService(DevicePolicyManagerInternal.class);
5335        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5336            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5337        }
5338
5339        long callingId = Binder.clearCallingIdentity();
5340        try {
5341            IPackageManager pm = AppGlobals.getPackageManager();
5342            int pkgUid = -1;
5343            synchronized(this) {
5344                try {
5345                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5346                } catch (RemoteException e) {
5347                }
5348                if (pkgUid == -1) {
5349                    Slog.w(TAG, "Invalid packageName: " + packageName);
5350                    if (observer != null) {
5351                        try {
5352                            observer.onRemoveCompleted(packageName, false);
5353                        } catch (RemoteException e) {
5354                            Slog.i(TAG, "Observer no longer exists.");
5355                        }
5356                    }
5357                    return false;
5358                }
5359                if (uid == pkgUid || checkComponentPermission(
5360                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5361                        pid, uid, -1, true)
5362                        == PackageManager.PERMISSION_GRANTED) {
5363                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5364                } else {
5365                    throw new SecurityException("PID " + pid + " does not have permission "
5366                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5367                                    + " of package " + packageName);
5368                }
5369
5370                // Remove all tasks match the cleared application package and user
5371                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5372                    final TaskRecord tr = mRecentTasks.get(i);
5373                    final String taskPackageName =
5374                            tr.getBaseIntent().getComponent().getPackageName();
5375                    if (tr.userId != userId) continue;
5376                    if (!taskPackageName.equals(packageName)) continue;
5377                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5378                }
5379            }
5380
5381            try {
5382                // Clear application user data
5383                pm.clearApplicationUserData(packageName, observer, userId);
5384
5385                synchronized(this) {
5386                    // Remove all permissions granted from/to this package
5387                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5388                }
5389
5390                // Remove all zen rules created by this package; revoke it's zen access.
5391                INotificationManager inm = NotificationManager.getService();
5392                inm.removeAutomaticZenRules(packageName);
5393                inm.setNotificationPolicyAccessGranted(packageName, false);
5394
5395                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5396                        Uri.fromParts("package", packageName, null));
5397                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5398                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5399                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5400                        null, null, 0, null, null, null, null, false, false, userId);
5401            } catch (RemoteException e) {
5402            }
5403        } finally {
5404            Binder.restoreCallingIdentity(callingId);
5405        }
5406        return true;
5407    }
5408
5409    @Override
5410    public void killBackgroundProcesses(final String packageName, int userId) {
5411        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5412                != PackageManager.PERMISSION_GRANTED &&
5413                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5414                        != PackageManager.PERMISSION_GRANTED) {
5415            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5416                    + Binder.getCallingPid()
5417                    + ", uid=" + Binder.getCallingUid()
5418                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5419            Slog.w(TAG, msg);
5420            throw new SecurityException(msg);
5421        }
5422
5423        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5424                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5425        long callingId = Binder.clearCallingIdentity();
5426        try {
5427            IPackageManager pm = AppGlobals.getPackageManager();
5428            synchronized(this) {
5429                int appId = -1;
5430                try {
5431                    appId = UserHandle.getAppId(
5432                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5433                } catch (RemoteException e) {
5434                }
5435                if (appId == -1) {
5436                    Slog.w(TAG, "Invalid packageName: " + packageName);
5437                    return;
5438                }
5439                killPackageProcessesLocked(packageName, appId, userId,
5440                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5441            }
5442        } finally {
5443            Binder.restoreCallingIdentity(callingId);
5444        }
5445    }
5446
5447    @Override
5448    public void killAllBackgroundProcesses() {
5449        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5450                != PackageManager.PERMISSION_GRANTED) {
5451            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5452                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5453                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5454            Slog.w(TAG, msg);
5455            throw new SecurityException(msg);
5456        }
5457
5458        final long callingId = Binder.clearCallingIdentity();
5459        try {
5460            synchronized (this) {
5461                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5462                final int NP = mProcessNames.getMap().size();
5463                for (int ip = 0; ip < NP; ip++) {
5464                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5465                    final int NA = apps.size();
5466                    for (int ia = 0; ia < NA; ia++) {
5467                        final ProcessRecord app = apps.valueAt(ia);
5468                        if (app.persistent) {
5469                            // We don't kill persistent processes.
5470                            continue;
5471                        }
5472                        if (app.removed) {
5473                            procs.add(app);
5474                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5475                            app.removed = true;
5476                            procs.add(app);
5477                        }
5478                    }
5479                }
5480
5481                final int N = procs.size();
5482                for (int i = 0; i < N; i++) {
5483                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5484                }
5485
5486                mAllowLowerMemLevel = true;
5487
5488                updateOomAdjLocked();
5489                doLowMemReportIfNeededLocked(null);
5490            }
5491        } finally {
5492            Binder.restoreCallingIdentity(callingId);
5493        }
5494    }
5495
5496    /**
5497     * Kills all background processes, except those matching any of the
5498     * specified properties.
5499     *
5500     * @param minTargetSdk the target SDK version at or above which to preserve
5501     *                     processes, or {@code -1} to ignore the target SDK
5502     * @param maxProcState the process state at or below which to preserve
5503     *                     processes, or {@code -1} to ignore the process state
5504     */
5505    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5506        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5507                != PackageManager.PERMISSION_GRANTED) {
5508            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5509                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5510                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5511            Slog.w(TAG, msg);
5512            throw new SecurityException(msg);
5513        }
5514
5515        final long callingId = Binder.clearCallingIdentity();
5516        try {
5517            synchronized (this) {
5518                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5519                final int NP = mProcessNames.getMap().size();
5520                for (int ip = 0; ip < NP; ip++) {
5521                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5522                    final int NA = apps.size();
5523                    for (int ia = 0; ia < NA; ia++) {
5524                        final ProcessRecord app = apps.valueAt(ia);
5525                        if (app.removed) {
5526                            procs.add(app);
5527                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5528                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5529                            app.removed = true;
5530                            procs.add(app);
5531                        }
5532                    }
5533                }
5534
5535                final int N = procs.size();
5536                for (int i = 0; i < N; i++) {
5537                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5538                }
5539            }
5540        } finally {
5541            Binder.restoreCallingIdentity(callingId);
5542        }
5543    }
5544
5545    @Override
5546    public void forceStopPackage(final String packageName, int userId) {
5547        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5548                != PackageManager.PERMISSION_GRANTED) {
5549            String msg = "Permission Denial: forceStopPackage() from pid="
5550                    + Binder.getCallingPid()
5551                    + ", uid=" + Binder.getCallingUid()
5552                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5553            Slog.w(TAG, msg);
5554            throw new SecurityException(msg);
5555        }
5556        final int callingPid = Binder.getCallingPid();
5557        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5558                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5559        long callingId = Binder.clearCallingIdentity();
5560        try {
5561            IPackageManager pm = AppGlobals.getPackageManager();
5562            synchronized(this) {
5563                int[] users = userId == UserHandle.USER_ALL
5564                        ? mUserController.getUsers() : new int[] { userId };
5565                for (int user : users) {
5566                    int pkgUid = -1;
5567                    try {
5568                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5569                                user);
5570                    } catch (RemoteException e) {
5571                    }
5572                    if (pkgUid == -1) {
5573                        Slog.w(TAG, "Invalid packageName: " + packageName);
5574                        continue;
5575                    }
5576                    try {
5577                        pm.setPackageStoppedState(packageName, true, user);
5578                    } catch (RemoteException e) {
5579                    } catch (IllegalArgumentException e) {
5580                        Slog.w(TAG, "Failed trying to unstop package "
5581                                + packageName + ": " + e);
5582                    }
5583                    if (mUserController.isUserRunningLocked(user, 0)) {
5584                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5585                    }
5586                }
5587            }
5588        } finally {
5589            Binder.restoreCallingIdentity(callingId);
5590        }
5591    }
5592
5593    @Override
5594    public void addPackageDependency(String packageName) {
5595        synchronized (this) {
5596            int callingPid = Binder.getCallingPid();
5597            if (callingPid == Process.myPid()) {
5598                //  Yeah, um, no.
5599                return;
5600            }
5601            ProcessRecord proc;
5602            synchronized (mPidsSelfLocked) {
5603                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5604            }
5605            if (proc != null) {
5606                if (proc.pkgDeps == null) {
5607                    proc.pkgDeps = new ArraySet<String>(1);
5608                }
5609                proc.pkgDeps.add(packageName);
5610            }
5611        }
5612    }
5613
5614    /*
5615     * The pkg name and app id have to be specified.
5616     */
5617    @Override
5618    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5619        if (pkg == null) {
5620            return;
5621        }
5622        // Make sure the uid is valid.
5623        if (appid < 0) {
5624            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5625            return;
5626        }
5627        int callerUid = Binder.getCallingUid();
5628        // Only the system server can kill an application
5629        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5630            // Post an aysnc message to kill the application
5631            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5632            msg.arg1 = appid;
5633            msg.arg2 = 0;
5634            Bundle bundle = new Bundle();
5635            bundle.putString("pkg", pkg);
5636            bundle.putString("reason", reason);
5637            msg.obj = bundle;
5638            mHandler.sendMessage(msg);
5639        } else {
5640            throw new SecurityException(callerUid + " cannot kill pkg: " +
5641                    pkg);
5642        }
5643    }
5644
5645    @Override
5646    public void closeSystemDialogs(String reason) {
5647        enforceNotIsolatedCaller("closeSystemDialogs");
5648
5649        final int pid = Binder.getCallingPid();
5650        final int uid = Binder.getCallingUid();
5651        final long origId = Binder.clearCallingIdentity();
5652        try {
5653            synchronized (this) {
5654                // Only allow this from foreground processes, so that background
5655                // applications can't abuse it to prevent system UI from being shown.
5656                if (uid >= Process.FIRST_APPLICATION_UID) {
5657                    ProcessRecord proc;
5658                    synchronized (mPidsSelfLocked) {
5659                        proc = mPidsSelfLocked.get(pid);
5660                    }
5661                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5662                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5663                                + " from background process " + proc);
5664                        return;
5665                    }
5666                }
5667                closeSystemDialogsLocked(reason);
5668            }
5669        } finally {
5670            Binder.restoreCallingIdentity(origId);
5671        }
5672    }
5673
5674    void closeSystemDialogsLocked(String reason) {
5675        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5676        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5677                | Intent.FLAG_RECEIVER_FOREGROUND);
5678        if (reason != null) {
5679            intent.putExtra("reason", reason);
5680        }
5681        mWindowManager.closeSystemDialogs(reason);
5682
5683        mStackSupervisor.closeSystemDialogsLocked();
5684
5685        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5686                AppOpsManager.OP_NONE, null, false, false,
5687                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5688    }
5689
5690    @Override
5691    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5692        enforceNotIsolatedCaller("getProcessMemoryInfo");
5693        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5694        for (int i=pids.length-1; i>=0; i--) {
5695            ProcessRecord proc;
5696            int oomAdj;
5697            synchronized (this) {
5698                synchronized (mPidsSelfLocked) {
5699                    proc = mPidsSelfLocked.get(pids[i]);
5700                    oomAdj = proc != null ? proc.setAdj : 0;
5701                }
5702            }
5703            infos[i] = new Debug.MemoryInfo();
5704            Debug.getMemoryInfo(pids[i], infos[i]);
5705            if (proc != null) {
5706                synchronized (this) {
5707                    if (proc.thread != null && proc.setAdj == oomAdj) {
5708                        // Record this for posterity if the process has been stable.
5709                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5710                                infos[i].getTotalUss(), false, proc.pkgList);
5711                    }
5712                }
5713            }
5714        }
5715        return infos;
5716    }
5717
5718    @Override
5719    public long[] getProcessPss(int[] pids) {
5720        enforceNotIsolatedCaller("getProcessPss");
5721        long[] pss = new long[pids.length];
5722        for (int i=pids.length-1; i>=0; i--) {
5723            ProcessRecord proc;
5724            int oomAdj;
5725            synchronized (this) {
5726                synchronized (mPidsSelfLocked) {
5727                    proc = mPidsSelfLocked.get(pids[i]);
5728                    oomAdj = proc != null ? proc.setAdj : 0;
5729                }
5730            }
5731            long[] tmpUss = new long[1];
5732            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5733            if (proc != null) {
5734                synchronized (this) {
5735                    if (proc.thread != null && proc.setAdj == oomAdj) {
5736                        // Record this for posterity if the process has been stable.
5737                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5738                    }
5739                }
5740            }
5741        }
5742        return pss;
5743    }
5744
5745    @Override
5746    public void killApplicationProcess(String processName, int uid) {
5747        if (processName == null) {
5748            return;
5749        }
5750
5751        int callerUid = Binder.getCallingUid();
5752        // Only the system server can kill an application
5753        if (callerUid == Process.SYSTEM_UID) {
5754            synchronized (this) {
5755                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5756                if (app != null && app.thread != null) {
5757                    try {
5758                        app.thread.scheduleSuicide();
5759                    } catch (RemoteException e) {
5760                        // If the other end already died, then our work here is done.
5761                    }
5762                } else {
5763                    Slog.w(TAG, "Process/uid not found attempting kill of "
5764                            + processName + " / " + uid);
5765                }
5766            }
5767        } else {
5768            throw new SecurityException(callerUid + " cannot kill app process: " +
5769                    processName);
5770        }
5771    }
5772
5773    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5774        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5775                false, true, false, false, UserHandle.getUserId(uid), reason);
5776        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5777                Uri.fromParts("package", packageName, null));
5778        if (!mProcessesReady) {
5779            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5780                    | Intent.FLAG_RECEIVER_FOREGROUND);
5781        }
5782        intent.putExtra(Intent.EXTRA_UID, uid);
5783        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5784        broadcastIntentLocked(null, null, intent,
5785                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5786                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5787    }
5788
5789
5790    private final boolean killPackageProcessesLocked(String packageName, int appId,
5791            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5792            boolean doit, boolean evenPersistent, String reason) {
5793        ArrayList<ProcessRecord> procs = new ArrayList<>();
5794
5795        // Remove all processes this package may have touched: all with the
5796        // same UID (except for the system or root user), and all whose name
5797        // matches the package name.
5798        final int NP = mProcessNames.getMap().size();
5799        for (int ip=0; ip<NP; ip++) {
5800            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5801            final int NA = apps.size();
5802            for (int ia=0; ia<NA; ia++) {
5803                ProcessRecord app = apps.valueAt(ia);
5804                if (app.persistent && !evenPersistent) {
5805                    // we don't kill persistent processes
5806                    continue;
5807                }
5808                if (app.removed) {
5809                    if (doit) {
5810                        procs.add(app);
5811                    }
5812                    continue;
5813                }
5814
5815                // Skip process if it doesn't meet our oom adj requirement.
5816                if (app.setAdj < minOomAdj) {
5817                    continue;
5818                }
5819
5820                // If no package is specified, we call all processes under the
5821                // give user id.
5822                if (packageName == null) {
5823                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5824                        continue;
5825                    }
5826                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5827                        continue;
5828                    }
5829                // Package has been specified, we want to hit all processes
5830                // that match it.  We need to qualify this by the processes
5831                // that are running under the specified app and user ID.
5832                } else {
5833                    final boolean isDep = app.pkgDeps != null
5834                            && app.pkgDeps.contains(packageName);
5835                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5836                        continue;
5837                    }
5838                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5839                        continue;
5840                    }
5841                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5842                        continue;
5843                    }
5844                }
5845
5846                // Process has passed all conditions, kill it!
5847                if (!doit) {
5848                    return true;
5849                }
5850                app.removed = true;
5851                procs.add(app);
5852            }
5853        }
5854
5855        int N = procs.size();
5856        for (int i=0; i<N; i++) {
5857            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5858        }
5859        updateOomAdjLocked();
5860        return N > 0;
5861    }
5862
5863    private void cleanupDisabledPackageComponentsLocked(
5864            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5865
5866        Set<String> disabledClasses = null;
5867        boolean packageDisabled = false;
5868        IPackageManager pm = AppGlobals.getPackageManager();
5869
5870        if (changedClasses == null) {
5871            // Nothing changed...
5872            return;
5873        }
5874
5875        // Determine enable/disable state of the package and its components.
5876        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5877        for (int i = changedClasses.length - 1; i >= 0; i--) {
5878            final String changedClass = changedClasses[i];
5879
5880            if (changedClass.equals(packageName)) {
5881                try {
5882                    // Entire package setting changed
5883                    enabled = pm.getApplicationEnabledSetting(packageName,
5884                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5885                } catch (Exception e) {
5886                    // No such package/component; probably racing with uninstall.  In any
5887                    // event it means we have nothing further to do here.
5888                    return;
5889                }
5890                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5891                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5892                if (packageDisabled) {
5893                    // Entire package is disabled.
5894                    // No need to continue to check component states.
5895                    disabledClasses = null;
5896                    break;
5897                }
5898            } else {
5899                try {
5900                    enabled = pm.getComponentEnabledSetting(
5901                            new ComponentName(packageName, changedClass),
5902                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5903                } catch (Exception e) {
5904                    // As above, probably racing with uninstall.
5905                    return;
5906                }
5907                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5908                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5909                    if (disabledClasses == null) {
5910                        disabledClasses = new ArraySet<>(changedClasses.length);
5911                    }
5912                    disabledClasses.add(changedClass);
5913                }
5914            }
5915        }
5916
5917        if (!packageDisabled && disabledClasses == null) {
5918            // Nothing to do here...
5919            return;
5920        }
5921
5922        // Clean-up disabled activities.
5923        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5924                packageName, disabledClasses, true, false, userId) && mBooted) {
5925            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5926            mStackSupervisor.scheduleIdleLocked();
5927        }
5928
5929        // Clean-up disabled tasks
5930        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5931
5932        // Clean-up disabled services.
5933        mServices.bringDownDisabledPackageServicesLocked(
5934                packageName, disabledClasses, userId, false, killProcess, true);
5935
5936        // Clean-up disabled providers.
5937        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5938        mProviderMap.collectPackageProvidersLocked(
5939                packageName, disabledClasses, true, false, userId, providers);
5940        for (int i = providers.size() - 1; i >= 0; i--) {
5941            removeDyingProviderLocked(null, providers.get(i), true);
5942        }
5943
5944        // Clean-up disabled broadcast receivers.
5945        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5946            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5947                    packageName, disabledClasses, userId, true);
5948        }
5949
5950    }
5951
5952    final boolean forceStopPackageLocked(String packageName, int appId,
5953            boolean callerWillRestart, boolean purgeCache, boolean doit,
5954            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5955        int i;
5956
5957        if (userId == UserHandle.USER_ALL && packageName == null) {
5958            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5959        }
5960
5961        if (appId < 0 && packageName != null) {
5962            try {
5963                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5964                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5965            } catch (RemoteException e) {
5966            }
5967        }
5968
5969        if (doit) {
5970            if (packageName != null) {
5971                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5972                        + " user=" + userId + ": " + reason);
5973            } else {
5974                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5975            }
5976
5977            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5978        }
5979
5980        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5981                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5982                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5983
5984        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5985                packageName, null, doit, evenPersistent, userId)) {
5986            if (!doit) {
5987                return true;
5988            }
5989            didSomething = true;
5990        }
5991
5992        if (mServices.bringDownDisabledPackageServicesLocked(
5993                packageName, null, userId, evenPersistent, true, doit)) {
5994            if (!doit) {
5995                return true;
5996            }
5997            didSomething = true;
5998        }
5999
6000        if (packageName == null) {
6001            // Remove all sticky broadcasts from this user.
6002            mStickyBroadcasts.remove(userId);
6003        }
6004
6005        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6006        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6007                userId, providers)) {
6008            if (!doit) {
6009                return true;
6010            }
6011            didSomething = true;
6012        }
6013        for (i = providers.size() - 1; i >= 0; i--) {
6014            removeDyingProviderLocked(null, providers.get(i), true);
6015        }
6016
6017        // Remove transient permissions granted from/to this package/user
6018        removeUriPermissionsForPackageLocked(packageName, userId, false);
6019
6020        if (doit) {
6021            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6022                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6023                        packageName, null, userId, doit);
6024            }
6025        }
6026
6027        if (packageName == null || uninstalling) {
6028            // Remove pending intents.  For now we only do this when force
6029            // stopping users, because we have some problems when doing this
6030            // for packages -- app widgets are not currently cleaned up for
6031            // such packages, so they can be left with bad pending intents.
6032            if (mIntentSenderRecords.size() > 0) {
6033                Iterator<WeakReference<PendingIntentRecord>> it
6034                        = mIntentSenderRecords.values().iterator();
6035                while (it.hasNext()) {
6036                    WeakReference<PendingIntentRecord> wpir = it.next();
6037                    if (wpir == null) {
6038                        it.remove();
6039                        continue;
6040                    }
6041                    PendingIntentRecord pir = wpir.get();
6042                    if (pir == null) {
6043                        it.remove();
6044                        continue;
6045                    }
6046                    if (packageName == null) {
6047                        // Stopping user, remove all objects for the user.
6048                        if (pir.key.userId != userId) {
6049                            // Not the same user, skip it.
6050                            continue;
6051                        }
6052                    } else {
6053                        if (UserHandle.getAppId(pir.uid) != appId) {
6054                            // Different app id, skip it.
6055                            continue;
6056                        }
6057                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6058                            // Different user, skip it.
6059                            continue;
6060                        }
6061                        if (!pir.key.packageName.equals(packageName)) {
6062                            // Different package, skip it.
6063                            continue;
6064                        }
6065                    }
6066                    if (!doit) {
6067                        return true;
6068                    }
6069                    didSomething = true;
6070                    it.remove();
6071                    pir.canceled = true;
6072                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6073                        pir.key.activity.pendingResults.remove(pir.ref);
6074                    }
6075                }
6076            }
6077        }
6078
6079        if (doit) {
6080            if (purgeCache && packageName != null) {
6081                AttributeCache ac = AttributeCache.instance();
6082                if (ac != null) {
6083                    ac.removePackage(packageName);
6084                }
6085            }
6086            if (mBooted) {
6087                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6088                mStackSupervisor.scheduleIdleLocked();
6089            }
6090        }
6091
6092        return didSomething;
6093    }
6094
6095    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6096        ProcessRecord old = mProcessNames.remove(name, uid);
6097        if (old != null) {
6098            old.uidRecord.numProcs--;
6099            if (old.uidRecord.numProcs == 0) {
6100                // No more processes using this uid, tell clients it is gone.
6101                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6102                        "No more processes in " + old.uidRecord);
6103                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6104                mActiveUids.remove(uid);
6105                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6106            }
6107            old.uidRecord = null;
6108        }
6109        mIsolatedProcesses.remove(uid);
6110        return old;
6111    }
6112
6113    private final void addProcessNameLocked(ProcessRecord proc) {
6114        // We shouldn't already have a process under this name, but just in case we
6115        // need to clean up whatever may be there now.
6116        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6117        if (old == proc && proc.persistent) {
6118            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6119            Slog.w(TAG, "Re-adding persistent process " + proc);
6120        } else if (old != null) {
6121            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6122        }
6123        UidRecord uidRec = mActiveUids.get(proc.uid);
6124        if (uidRec == null) {
6125            uidRec = new UidRecord(proc.uid);
6126            // This is the first appearance of the uid, report it now!
6127            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6128                    "Creating new process uid: " + uidRec);
6129            mActiveUids.put(proc.uid, uidRec);
6130            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6131            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6132        }
6133        proc.uidRecord = uidRec;
6134        uidRec.numProcs++;
6135        mProcessNames.put(proc.processName, proc.uid, proc);
6136        if (proc.isolated) {
6137            mIsolatedProcesses.put(proc.uid, proc);
6138        }
6139    }
6140
6141    boolean removeProcessLocked(ProcessRecord app,
6142            boolean callerWillRestart, boolean allowRestart, String reason) {
6143        final String name = app.processName;
6144        final int uid = app.uid;
6145        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6146            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6147
6148        removeProcessNameLocked(name, uid);
6149        if (mHeavyWeightProcess == app) {
6150            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6151                    mHeavyWeightProcess.userId, 0));
6152            mHeavyWeightProcess = null;
6153        }
6154        boolean needRestart = false;
6155        if (app.pid > 0 && app.pid != MY_PID) {
6156            int pid = app.pid;
6157            synchronized (mPidsSelfLocked) {
6158                mPidsSelfLocked.remove(pid);
6159                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6160            }
6161            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6162            if (app.isolated) {
6163                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6164            }
6165            boolean willRestart = false;
6166            if (app.persistent && !app.isolated) {
6167                if (!callerWillRestart) {
6168                    willRestart = true;
6169                } else {
6170                    needRestart = true;
6171                }
6172            }
6173            app.kill(reason, true);
6174            handleAppDiedLocked(app, willRestart, allowRestart);
6175            if (willRestart) {
6176                removeLruProcessLocked(app);
6177                addAppLocked(app.info, false, null /* ABI override */);
6178            }
6179        } else {
6180            mRemovedProcesses.add(app);
6181        }
6182
6183        return needRestart;
6184    }
6185
6186    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6187        cleanupAppInLaunchingProvidersLocked(app, true);
6188        removeProcessLocked(app, false, true, "timeout publishing content providers");
6189    }
6190
6191    private final void processStartTimedOutLocked(ProcessRecord app) {
6192        final int pid = app.pid;
6193        boolean gone = false;
6194        synchronized (mPidsSelfLocked) {
6195            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6196            if (knownApp != null && knownApp.thread == null) {
6197                mPidsSelfLocked.remove(pid);
6198                gone = true;
6199            }
6200        }
6201
6202        if (gone) {
6203            Slog.w(TAG, "Process " + app + " failed to attach");
6204            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6205                    pid, app.uid, app.processName);
6206            removeProcessNameLocked(app.processName, app.uid);
6207            if (mHeavyWeightProcess == app) {
6208                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6209                        mHeavyWeightProcess.userId, 0));
6210                mHeavyWeightProcess = null;
6211            }
6212            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6213            if (app.isolated) {
6214                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6215            }
6216            // Take care of any launching providers waiting for this process.
6217            cleanupAppInLaunchingProvidersLocked(app, true);
6218            // Take care of any services that are waiting for the process.
6219            mServices.processStartTimedOutLocked(app);
6220            app.kill("start timeout", true);
6221            removeLruProcessLocked(app);
6222            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6223                Slog.w(TAG, "Unattached app died before backup, skipping");
6224                try {
6225                    IBackupManager bm = IBackupManager.Stub.asInterface(
6226                            ServiceManager.getService(Context.BACKUP_SERVICE));
6227                    bm.agentDisconnected(app.info.packageName);
6228                } catch (RemoteException e) {
6229                    // Can't happen; the backup manager is local
6230                }
6231            }
6232            if (isPendingBroadcastProcessLocked(pid)) {
6233                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6234                skipPendingBroadcastLocked(pid);
6235            }
6236        } else {
6237            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6238        }
6239    }
6240
6241    private final boolean attachApplicationLocked(IApplicationThread thread,
6242            int pid) {
6243
6244        // Find the application record that is being attached...  either via
6245        // the pid if we are running in multiple processes, or just pull the
6246        // next app record if we are emulating process with anonymous threads.
6247        ProcessRecord app;
6248        if (pid != MY_PID && pid >= 0) {
6249            synchronized (mPidsSelfLocked) {
6250                app = mPidsSelfLocked.get(pid);
6251            }
6252        } else {
6253            app = null;
6254        }
6255
6256        if (app == null) {
6257            Slog.w(TAG, "No pending application record for pid " + pid
6258                    + " (IApplicationThread " + thread + "); dropping process");
6259            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6260            if (pid > 0 && pid != MY_PID) {
6261                Process.killProcessQuiet(pid);
6262                //TODO: killProcessGroup(app.info.uid, pid);
6263            } else {
6264                try {
6265                    thread.scheduleExit();
6266                } catch (Exception e) {
6267                    // Ignore exceptions.
6268                }
6269            }
6270            return false;
6271        }
6272
6273        // If this application record is still attached to a previous
6274        // process, clean it up now.
6275        if (app.thread != null) {
6276            handleAppDiedLocked(app, true, true);
6277        }
6278
6279        // Tell the process all about itself.
6280
6281        if (DEBUG_ALL) Slog.v(
6282                TAG, "Binding process pid " + pid + " to record " + app);
6283
6284        final String processName = app.processName;
6285        try {
6286            AppDeathRecipient adr = new AppDeathRecipient(
6287                    app, pid, thread);
6288            thread.asBinder().linkToDeath(adr, 0);
6289            app.deathRecipient = adr;
6290        } catch (RemoteException e) {
6291            app.resetPackageList(mProcessStats);
6292            startProcessLocked(app, "link fail", processName);
6293            return false;
6294        }
6295
6296        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6297
6298        app.makeActive(thread, mProcessStats);
6299        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6300        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6301        app.forcingToForeground = null;
6302        updateProcessForegroundLocked(app, false, false);
6303        app.hasShownUi = false;
6304        app.debugging = false;
6305        app.cached = false;
6306        app.killedByAm = false;
6307        app.unlocked = mContext.getSystemService(UserManager.class).isUserUnlocked(app.userId);
6308
6309        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6310
6311        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6312        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6313
6314        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6315            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6316            msg.obj = app;
6317            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6318        }
6319
6320        if (!normalMode) {
6321            Slog.i(TAG, "Launching preboot mode app: " + app);
6322        }
6323
6324        if (DEBUG_ALL) Slog.v(
6325            TAG, "New app record " + app
6326            + " thread=" + thread.asBinder() + " pid=" + pid);
6327        try {
6328            int testMode = IApplicationThread.DEBUG_OFF;
6329            if (mDebugApp != null && mDebugApp.equals(processName)) {
6330                testMode = mWaitForDebugger
6331                    ? IApplicationThread.DEBUG_WAIT
6332                    : IApplicationThread.DEBUG_ON;
6333                app.debugging = true;
6334                if (mDebugTransient) {
6335                    mDebugApp = mOrigDebugApp;
6336                    mWaitForDebugger = mOrigWaitForDebugger;
6337                }
6338            }
6339            String profileFile = app.instrumentationProfileFile;
6340            ParcelFileDescriptor profileFd = null;
6341            int samplingInterval = 0;
6342            boolean profileAutoStop = false;
6343            if (mProfileApp != null && mProfileApp.equals(processName)) {
6344                mProfileProc = app;
6345                profileFile = mProfileFile;
6346                profileFd = mProfileFd;
6347                samplingInterval = mSamplingInterval;
6348                profileAutoStop = mAutoStopProfiler;
6349            }
6350            boolean enableTrackAllocation = false;
6351            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6352                enableTrackAllocation = true;
6353                mTrackAllocationApp = null;
6354            }
6355
6356            // If the app is being launched for restore or full backup, set it up specially
6357            boolean isRestrictedBackupMode = false;
6358            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6359                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6360                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6361                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6362                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6363            }
6364
6365            if (app.instrumentationClass != null) {
6366                notifyPackageUse(app.instrumentationClass.getPackageName(),
6367                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6368            }
6369            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6370                    + processName + " with config " + mConfiguration);
6371            ApplicationInfo appInfo = app.instrumentationInfo != null
6372                    ? app.instrumentationInfo : app.info;
6373            app.compat = compatibilityInfoForPackageLocked(appInfo);
6374            if (profileFd != null) {
6375                profileFd = profileFd.dup();
6376            }
6377            ProfilerInfo profilerInfo = profileFile == null ? null
6378                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6379            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6380                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6381                    app.instrumentationUiAutomationConnection, testMode,
6382                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6383                    isRestrictedBackupMode || !normalMode, app.persistent,
6384                    new Configuration(mConfiguration), app.compat,
6385                    getCommonServicesLocked(app.isolated),
6386                    mCoreSettingsObserver.getCoreSettingsLocked());
6387            updateLruProcessLocked(app, false, null);
6388            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6389        } catch (Exception e) {
6390            // todo: Yikes!  What should we do?  For now we will try to
6391            // start another process, but that could easily get us in
6392            // an infinite loop of restarting processes...
6393            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6394
6395            app.resetPackageList(mProcessStats);
6396            app.unlinkDeathRecipient();
6397            startProcessLocked(app, "bind fail", processName);
6398            return false;
6399        }
6400
6401        // Remove this record from the list of starting applications.
6402        mPersistentStartingProcesses.remove(app);
6403        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6404                "Attach application locked removing on hold: " + app);
6405        mProcessesOnHold.remove(app);
6406
6407        boolean badApp = false;
6408        boolean didSomething = false;
6409
6410        // See if the top visible activity is waiting to run in this process...
6411        if (normalMode) {
6412            try {
6413                if (mStackSupervisor.attachApplicationLocked(app)) {
6414                    didSomething = true;
6415                }
6416            } catch (Exception e) {
6417                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6418                badApp = true;
6419            }
6420        }
6421
6422        // Find any services that should be running in this process...
6423        if (!badApp) {
6424            try {
6425                didSomething |= mServices.attachApplicationLocked(app, processName);
6426            } catch (Exception e) {
6427                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6428                badApp = true;
6429            }
6430        }
6431
6432        // Check if a next-broadcast receiver is in this process...
6433        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6434            try {
6435                didSomething |= sendPendingBroadcastsLocked(app);
6436            } catch (Exception e) {
6437                // If the app died trying to launch the receiver we declare it 'bad'
6438                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6439                badApp = true;
6440            }
6441        }
6442
6443        // Check whether the next backup agent is in this process...
6444        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6445            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6446                    "New app is backup target, launching agent for " + app);
6447            notifyPackageUse(mBackupTarget.appInfo.packageName,
6448                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6449            try {
6450                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6451                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6452                        mBackupTarget.backupMode);
6453            } catch (Exception e) {
6454                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6455                badApp = true;
6456            }
6457        }
6458
6459        if (badApp) {
6460            app.kill("error during init", true);
6461            handleAppDiedLocked(app, false, true);
6462            return false;
6463        }
6464
6465        if (!didSomething) {
6466            updateOomAdjLocked();
6467        }
6468
6469        return true;
6470    }
6471
6472    @Override
6473    public final void attachApplication(IApplicationThread thread) {
6474        synchronized (this) {
6475            int callingPid = Binder.getCallingPid();
6476            final long origId = Binder.clearCallingIdentity();
6477            attachApplicationLocked(thread, callingPid);
6478            Binder.restoreCallingIdentity(origId);
6479        }
6480    }
6481
6482    @Override
6483    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6484        final long origId = Binder.clearCallingIdentity();
6485        synchronized (this) {
6486            ActivityStack stack = ActivityRecord.getStackLocked(token);
6487            if (stack != null) {
6488                ActivityRecord r =
6489                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6490                if (stopProfiling) {
6491                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6492                        try {
6493                            mProfileFd.close();
6494                        } catch (IOException e) {
6495                        }
6496                        clearProfilerLocked();
6497                    }
6498                }
6499            }
6500        }
6501        Binder.restoreCallingIdentity(origId);
6502    }
6503
6504    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6505        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6506                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6507    }
6508
6509    void enableScreenAfterBoot() {
6510        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6511                SystemClock.uptimeMillis());
6512        mWindowManager.enableScreenAfterBoot();
6513
6514        synchronized (this) {
6515            updateEventDispatchingLocked();
6516        }
6517    }
6518
6519    @Override
6520    public void showBootMessage(final CharSequence msg, final boolean always) {
6521        if (Binder.getCallingUid() != Process.myUid()) {
6522            // These days only the core system can call this, so apps can't get in
6523            // the way of what we show about running them.
6524        }
6525        mWindowManager.showBootMessage(msg, always);
6526    }
6527
6528    @Override
6529    public void keyguardWaitingForActivityDrawn() {
6530        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6531        final long token = Binder.clearCallingIdentity();
6532        try {
6533            synchronized (this) {
6534                if (DEBUG_LOCKSCREEN) logLockScreen("");
6535                mWindowManager.keyguardWaitingForActivityDrawn();
6536                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6537                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6538                    updateSleepIfNeededLocked();
6539                }
6540            }
6541        } finally {
6542            Binder.restoreCallingIdentity(token);
6543        }
6544    }
6545
6546    @Override
6547    public void keyguardGoingAway(int flags) {
6548        enforceNotIsolatedCaller("keyguardGoingAway");
6549        final long token = Binder.clearCallingIdentity();
6550        try {
6551            synchronized (this) {
6552                if (DEBUG_LOCKSCREEN) logLockScreen("");
6553                mWindowManager.keyguardGoingAway(flags);
6554                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6555                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6556                    updateSleepIfNeededLocked();
6557
6558                    // Some stack visibility might change (e.g. docked stack)
6559                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6560                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6561                }
6562            }
6563        } finally {
6564            Binder.restoreCallingIdentity(token);
6565        }
6566    }
6567
6568    final void finishBooting() {
6569        synchronized (this) {
6570            if (!mBootAnimationComplete) {
6571                mCallFinishBooting = true;
6572                return;
6573            }
6574            mCallFinishBooting = false;
6575        }
6576
6577        ArraySet<String> completedIsas = new ArraySet<String>();
6578        for (String abi : Build.SUPPORTED_ABIS) {
6579            Process.establishZygoteConnectionForAbi(abi);
6580            final String instructionSet = VMRuntime.getInstructionSet(abi);
6581            if (!completedIsas.contains(instructionSet)) {
6582                try {
6583                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6584                } catch (InstallerException e) {
6585                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6586                }
6587                completedIsas.add(instructionSet);
6588            }
6589        }
6590
6591        IntentFilter pkgFilter = new IntentFilter();
6592        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6593        pkgFilter.addDataScheme("package");
6594        mContext.registerReceiver(new BroadcastReceiver() {
6595            @Override
6596            public void onReceive(Context context, Intent intent) {
6597                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6598                if (pkgs != null) {
6599                    for (String pkg : pkgs) {
6600                        synchronized (ActivityManagerService.this) {
6601                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6602                                    0, "query restart")) {
6603                                setResultCode(Activity.RESULT_OK);
6604                                return;
6605                            }
6606                        }
6607                    }
6608                }
6609            }
6610        }, pkgFilter);
6611
6612        IntentFilter dumpheapFilter = new IntentFilter();
6613        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6614        mContext.registerReceiver(new BroadcastReceiver() {
6615            @Override
6616            public void onReceive(Context context, Intent intent) {
6617                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6618                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6619                } else {
6620                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6621                }
6622            }
6623        }, dumpheapFilter);
6624
6625        // Let system services know.
6626        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6627
6628        synchronized (this) {
6629            // Ensure that any processes we had put on hold are now started
6630            // up.
6631            final int NP = mProcessesOnHold.size();
6632            if (NP > 0) {
6633                ArrayList<ProcessRecord> procs =
6634                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6635                for (int ip=0; ip<NP; ip++) {
6636                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6637                            + procs.get(ip));
6638                    startProcessLocked(procs.get(ip), "on-hold", null);
6639                }
6640            }
6641
6642            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6643                // Start looking for apps that are abusing wake locks.
6644                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6645                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6646                // Tell anyone interested that we are done booting!
6647                SystemProperties.set("sys.boot_completed", "1");
6648
6649                // And trigger dev.bootcomplete if we are not showing encryption progress
6650                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6651                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6652                    SystemProperties.set("dev.bootcomplete", "1");
6653                }
6654                mUserController.sendBootCompletedLocked(
6655                        new IIntentReceiver.Stub() {
6656                            @Override
6657                            public void performReceive(Intent intent, int resultCode,
6658                                    String data, Bundle extras, boolean ordered,
6659                                    boolean sticky, int sendingUser) {
6660                                synchronized (ActivityManagerService.this) {
6661                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6662                                            true, false);
6663                                }
6664                            }
6665                        });
6666                scheduleStartProfilesLocked();
6667            }
6668        }
6669    }
6670
6671    @Override
6672    public void bootAnimationComplete() {
6673        final boolean callFinishBooting;
6674        synchronized (this) {
6675            callFinishBooting = mCallFinishBooting;
6676            mBootAnimationComplete = true;
6677        }
6678        if (callFinishBooting) {
6679            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6680            finishBooting();
6681            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6682        }
6683    }
6684
6685    final void ensureBootCompleted() {
6686        boolean booting;
6687        boolean enableScreen;
6688        synchronized (this) {
6689            booting = mBooting;
6690            mBooting = false;
6691            enableScreen = !mBooted;
6692            mBooted = true;
6693        }
6694
6695        if (booting) {
6696            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6697            finishBooting();
6698            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6699        }
6700
6701        if (enableScreen) {
6702            enableScreenAfterBoot();
6703        }
6704    }
6705
6706    @Override
6707    public final void activityResumed(IBinder token) {
6708        final long origId = Binder.clearCallingIdentity();
6709        synchronized(this) {
6710            ActivityStack stack = ActivityRecord.getStackLocked(token);
6711            if (stack != null) {
6712                stack.activityResumedLocked(token);
6713            }
6714        }
6715        Binder.restoreCallingIdentity(origId);
6716    }
6717
6718    @Override
6719    public final void activityPaused(IBinder token) {
6720        final long origId = Binder.clearCallingIdentity();
6721        synchronized(this) {
6722            ActivityStack stack = ActivityRecord.getStackLocked(token);
6723            if (stack != null) {
6724                stack.activityPausedLocked(token, false);
6725            }
6726        }
6727        Binder.restoreCallingIdentity(origId);
6728    }
6729
6730    @Override
6731    public final void activityStopped(IBinder token, Bundle icicle,
6732            PersistableBundle persistentState, CharSequence description) {
6733        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6734
6735        // Refuse possible leaked file descriptors
6736        if (icicle != null && icicle.hasFileDescriptors()) {
6737            throw new IllegalArgumentException("File descriptors passed in Bundle");
6738        }
6739
6740        final long origId = Binder.clearCallingIdentity();
6741
6742        synchronized (this) {
6743            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6744            if (r != null) {
6745                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6746            }
6747        }
6748
6749        trimApplications();
6750
6751        Binder.restoreCallingIdentity(origId);
6752    }
6753
6754    @Override
6755    public final void activityDestroyed(IBinder token) {
6756        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6757        synchronized (this) {
6758            ActivityStack stack = ActivityRecord.getStackLocked(token);
6759            if (stack != null) {
6760                stack.activityDestroyedLocked(token, "activityDestroyed");
6761            }
6762        }
6763    }
6764
6765    @Override
6766    public final void activityRelaunched(IBinder token) {
6767        final long origId = Binder.clearCallingIdentity();
6768        synchronized (this) {
6769            mStackSupervisor.activityRelaunchedLocked(token);
6770        }
6771        Binder.restoreCallingIdentity(origId);
6772    }
6773
6774    @Override
6775    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6776            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6777        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6778                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6779        synchronized (this) {
6780            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6781            if (record == null) {
6782                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6783                        + "found for: " + token);
6784            }
6785            record.setSizeConfigurations(horizontalSizeConfiguration,
6786                    verticalSizeConfigurations, smallestSizeConfigurations);
6787        }
6788    }
6789
6790    @Override
6791    public final void backgroundResourcesReleased(IBinder token) {
6792        final long origId = Binder.clearCallingIdentity();
6793        try {
6794            synchronized (this) {
6795                ActivityStack stack = ActivityRecord.getStackLocked(token);
6796                if (stack != null) {
6797                    stack.backgroundResourcesReleased();
6798                }
6799            }
6800        } finally {
6801            Binder.restoreCallingIdentity(origId);
6802        }
6803    }
6804
6805    @Override
6806    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6807        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6808    }
6809
6810    @Override
6811    public final void notifyEnterAnimationComplete(IBinder token) {
6812        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6813    }
6814
6815    @Override
6816    public String getCallingPackage(IBinder token) {
6817        synchronized (this) {
6818            ActivityRecord r = getCallingRecordLocked(token);
6819            return r != null ? r.info.packageName : null;
6820        }
6821    }
6822
6823    @Override
6824    public ComponentName getCallingActivity(IBinder token) {
6825        synchronized (this) {
6826            ActivityRecord r = getCallingRecordLocked(token);
6827            return r != null ? r.intent.getComponent() : null;
6828        }
6829    }
6830
6831    private ActivityRecord getCallingRecordLocked(IBinder token) {
6832        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6833        if (r == null) {
6834            return null;
6835        }
6836        return r.resultTo;
6837    }
6838
6839    @Override
6840    public ComponentName getActivityClassForToken(IBinder token) {
6841        synchronized(this) {
6842            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6843            if (r == null) {
6844                return null;
6845            }
6846            return r.intent.getComponent();
6847        }
6848    }
6849
6850    @Override
6851    public String getPackageForToken(IBinder token) {
6852        synchronized(this) {
6853            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6854            if (r == null) {
6855                return null;
6856            }
6857            return r.packageName;
6858        }
6859    }
6860
6861    @Override
6862    public boolean isRootVoiceInteraction(IBinder token) {
6863        synchronized(this) {
6864            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6865            if (r == null) {
6866                return false;
6867            }
6868            return r.rootVoiceInteraction;
6869        }
6870    }
6871
6872    @Override
6873    public IIntentSender getIntentSender(int type,
6874            String packageName, IBinder token, String resultWho,
6875            int requestCode, Intent[] intents, String[] resolvedTypes,
6876            int flags, Bundle bOptions, int userId) {
6877        enforceNotIsolatedCaller("getIntentSender");
6878        // Refuse possible leaked file descriptors
6879        if (intents != null) {
6880            if (intents.length < 1) {
6881                throw new IllegalArgumentException("Intents array length must be >= 1");
6882            }
6883            for (int i=0; i<intents.length; i++) {
6884                Intent intent = intents[i];
6885                if (intent != null) {
6886                    if (intent.hasFileDescriptors()) {
6887                        throw new IllegalArgumentException("File descriptors passed in Intent");
6888                    }
6889                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6890                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6891                        throw new IllegalArgumentException(
6892                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6893                    }
6894                    intents[i] = new Intent(intent);
6895                }
6896            }
6897            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6898                throw new IllegalArgumentException(
6899                        "Intent array length does not match resolvedTypes length");
6900            }
6901        }
6902        if (bOptions != null) {
6903            if (bOptions.hasFileDescriptors()) {
6904                throw new IllegalArgumentException("File descriptors passed in options");
6905            }
6906        }
6907
6908        synchronized(this) {
6909            int callingUid = Binder.getCallingUid();
6910            int origUserId = userId;
6911            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6912                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6913                    ALLOW_NON_FULL, "getIntentSender", null);
6914            if (origUserId == UserHandle.USER_CURRENT) {
6915                // We don't want to evaluate this until the pending intent is
6916                // actually executed.  However, we do want to always do the
6917                // security checking for it above.
6918                userId = UserHandle.USER_CURRENT;
6919            }
6920            try {
6921                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6922                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6923                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6924                    if (!UserHandle.isSameApp(callingUid, uid)) {
6925                        String msg = "Permission Denial: getIntentSender() from pid="
6926                            + Binder.getCallingPid()
6927                            + ", uid=" + Binder.getCallingUid()
6928                            + ", (need uid=" + uid + ")"
6929                            + " is not allowed to send as package " + packageName;
6930                        Slog.w(TAG, msg);
6931                        throw new SecurityException(msg);
6932                    }
6933                }
6934
6935                return getIntentSenderLocked(type, packageName, callingUid, userId,
6936                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6937
6938            } catch (RemoteException e) {
6939                throw new SecurityException(e);
6940            }
6941        }
6942    }
6943
6944    IIntentSender getIntentSenderLocked(int type, String packageName,
6945            int callingUid, int userId, IBinder token, String resultWho,
6946            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6947            Bundle bOptions) {
6948        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6949        ActivityRecord activity = null;
6950        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6951            activity = ActivityRecord.isInStackLocked(token);
6952            if (activity == null) {
6953                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6954                return null;
6955            }
6956            if (activity.finishing) {
6957                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6958                return null;
6959            }
6960        }
6961
6962        // We're going to be splicing together extras before sending, so we're
6963        // okay poking into any contained extras.
6964        if (intents != null) {
6965            for (int i = 0; i < intents.length; i++) {
6966                intents[i].setDefusable(true);
6967            }
6968        }
6969        Bundle.setDefusable(bOptions, true);
6970
6971        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6972        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6973        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6974        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6975                |PendingIntent.FLAG_UPDATE_CURRENT);
6976
6977        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6978                type, packageName, activity, resultWho,
6979                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6980        WeakReference<PendingIntentRecord> ref;
6981        ref = mIntentSenderRecords.get(key);
6982        PendingIntentRecord rec = ref != null ? ref.get() : null;
6983        if (rec != null) {
6984            if (!cancelCurrent) {
6985                if (updateCurrent) {
6986                    if (rec.key.requestIntent != null) {
6987                        rec.key.requestIntent.replaceExtras(intents != null ?
6988                                intents[intents.length - 1] : null);
6989                    }
6990                    if (intents != null) {
6991                        intents[intents.length-1] = rec.key.requestIntent;
6992                        rec.key.allIntents = intents;
6993                        rec.key.allResolvedTypes = resolvedTypes;
6994                    } else {
6995                        rec.key.allIntents = null;
6996                        rec.key.allResolvedTypes = null;
6997                    }
6998                }
6999                return rec;
7000            }
7001            rec.canceled = true;
7002            mIntentSenderRecords.remove(key);
7003        }
7004        if (noCreate) {
7005            return rec;
7006        }
7007        rec = new PendingIntentRecord(this, key, callingUid);
7008        mIntentSenderRecords.put(key, rec.ref);
7009        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7010            if (activity.pendingResults == null) {
7011                activity.pendingResults
7012                        = new HashSet<WeakReference<PendingIntentRecord>>();
7013            }
7014            activity.pendingResults.add(rec.ref);
7015        }
7016        return rec;
7017    }
7018
7019    @Override
7020    public void cancelIntentSender(IIntentSender sender) {
7021        if (!(sender instanceof PendingIntentRecord)) {
7022            return;
7023        }
7024        synchronized(this) {
7025            PendingIntentRecord rec = (PendingIntentRecord)sender;
7026            try {
7027                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7028                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7029                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7030                    String msg = "Permission Denial: cancelIntentSender() from pid="
7031                        + Binder.getCallingPid()
7032                        + ", uid=" + Binder.getCallingUid()
7033                        + " is not allowed to cancel packges "
7034                        + rec.key.packageName;
7035                    Slog.w(TAG, msg);
7036                    throw new SecurityException(msg);
7037                }
7038            } catch (RemoteException e) {
7039                throw new SecurityException(e);
7040            }
7041            cancelIntentSenderLocked(rec, true);
7042        }
7043    }
7044
7045    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7046        rec.canceled = true;
7047        mIntentSenderRecords.remove(rec.key);
7048        if (cleanActivity && rec.key.activity != null) {
7049            rec.key.activity.pendingResults.remove(rec.ref);
7050        }
7051    }
7052
7053    @Override
7054    public String getPackageForIntentSender(IIntentSender pendingResult) {
7055        if (!(pendingResult instanceof PendingIntentRecord)) {
7056            return null;
7057        }
7058        try {
7059            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7060            return res.key.packageName;
7061        } catch (ClassCastException e) {
7062        }
7063        return null;
7064    }
7065
7066    @Override
7067    public int getUidForIntentSender(IIntentSender sender) {
7068        if (sender instanceof PendingIntentRecord) {
7069            try {
7070                PendingIntentRecord res = (PendingIntentRecord)sender;
7071                return res.uid;
7072            } catch (ClassCastException e) {
7073            }
7074        }
7075        return -1;
7076    }
7077
7078    @Override
7079    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7080        if (!(pendingResult instanceof PendingIntentRecord)) {
7081            return false;
7082        }
7083        try {
7084            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7085            if (res.key.allIntents == null) {
7086                return false;
7087            }
7088            for (int i=0; i<res.key.allIntents.length; i++) {
7089                Intent intent = res.key.allIntents[i];
7090                if (intent.getPackage() != null && intent.getComponent() != null) {
7091                    return false;
7092                }
7093            }
7094            return true;
7095        } catch (ClassCastException e) {
7096        }
7097        return false;
7098    }
7099
7100    @Override
7101    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7102        if (!(pendingResult instanceof PendingIntentRecord)) {
7103            return false;
7104        }
7105        try {
7106            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7107            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7108                return true;
7109            }
7110            return false;
7111        } catch (ClassCastException e) {
7112        }
7113        return false;
7114    }
7115
7116    @Override
7117    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7118        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7119                "getIntentForIntentSender()");
7120        if (!(pendingResult instanceof PendingIntentRecord)) {
7121            return null;
7122        }
7123        try {
7124            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7125            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7126        } catch (ClassCastException e) {
7127        }
7128        return null;
7129    }
7130
7131    @Override
7132    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7133        if (!(pendingResult instanceof PendingIntentRecord)) {
7134            return null;
7135        }
7136        try {
7137            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7138            synchronized (this) {
7139                return getTagForIntentSenderLocked(res, prefix);
7140            }
7141        } catch (ClassCastException e) {
7142        }
7143        return null;
7144    }
7145
7146    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7147        final Intent intent = res.key.requestIntent;
7148        if (intent != null) {
7149            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7150                    || res.lastTagPrefix.equals(prefix))) {
7151                return res.lastTag;
7152            }
7153            res.lastTagPrefix = prefix;
7154            final StringBuilder sb = new StringBuilder(128);
7155            if (prefix != null) {
7156                sb.append(prefix);
7157            }
7158            if (intent.getAction() != null) {
7159                sb.append(intent.getAction());
7160            } else if (intent.getComponent() != null) {
7161                intent.getComponent().appendShortString(sb);
7162            } else {
7163                sb.append("?");
7164            }
7165            return res.lastTag = sb.toString();
7166        }
7167        return null;
7168    }
7169
7170    @Override
7171    public void setProcessLimit(int max) {
7172        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7173                "setProcessLimit()");
7174        synchronized (this) {
7175            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7176            mProcessLimitOverride = max;
7177        }
7178        trimApplications();
7179    }
7180
7181    @Override
7182    public int getProcessLimit() {
7183        synchronized (this) {
7184            return mProcessLimitOverride;
7185        }
7186    }
7187
7188    void foregroundTokenDied(ForegroundToken token) {
7189        synchronized (ActivityManagerService.this) {
7190            synchronized (mPidsSelfLocked) {
7191                ForegroundToken cur
7192                    = mForegroundProcesses.get(token.pid);
7193                if (cur != token) {
7194                    return;
7195                }
7196                mForegroundProcesses.remove(token.pid);
7197                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7198                if (pr == null) {
7199                    return;
7200                }
7201                pr.forcingToForeground = null;
7202                updateProcessForegroundLocked(pr, false, false);
7203            }
7204            updateOomAdjLocked();
7205        }
7206    }
7207
7208    @Override
7209    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7210        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7211                "setProcessForeground()");
7212        synchronized(this) {
7213            boolean changed = false;
7214
7215            synchronized (mPidsSelfLocked) {
7216                ProcessRecord pr = mPidsSelfLocked.get(pid);
7217                if (pr == null && isForeground) {
7218                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7219                    return;
7220                }
7221                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7222                if (oldToken != null) {
7223                    oldToken.token.unlinkToDeath(oldToken, 0);
7224                    mForegroundProcesses.remove(pid);
7225                    if (pr != null) {
7226                        pr.forcingToForeground = null;
7227                    }
7228                    changed = true;
7229                }
7230                if (isForeground && token != null) {
7231                    ForegroundToken newToken = new ForegroundToken() {
7232                        @Override
7233                        public void binderDied() {
7234                            foregroundTokenDied(this);
7235                        }
7236                    };
7237                    newToken.pid = pid;
7238                    newToken.token = token;
7239                    try {
7240                        token.linkToDeath(newToken, 0);
7241                        mForegroundProcesses.put(pid, newToken);
7242                        pr.forcingToForeground = token;
7243                        changed = true;
7244                    } catch (RemoteException e) {
7245                        // If the process died while doing this, we will later
7246                        // do the cleanup with the process death link.
7247                    }
7248                }
7249            }
7250
7251            if (changed) {
7252                updateOomAdjLocked();
7253            }
7254        }
7255    }
7256
7257    @Override
7258    public boolean isAppForeground(int uid) throws RemoteException {
7259        synchronized (this) {
7260            UidRecord uidRec = mActiveUids.get(uid);
7261            if (uidRec == null || uidRec.idle) {
7262                return false;
7263            }
7264            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7265        }
7266    }
7267
7268    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7269    // be guarded by permission checking.
7270    int getUidState(int uid) {
7271        synchronized (this) {
7272            UidRecord uidRec = mActiveUids.get(uid);
7273            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7274        }
7275    }
7276
7277    @Override
7278    public boolean isInMultiWindowMode(IBinder token) {
7279        final long origId = Binder.clearCallingIdentity();
7280        try {
7281            synchronized(this) {
7282                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7283                if (r == null) {
7284                    return false;
7285                }
7286                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7287                return !r.task.mFullscreen;
7288            }
7289        } finally {
7290            Binder.restoreCallingIdentity(origId);
7291        }
7292    }
7293
7294    @Override
7295    public boolean isInPictureInPictureMode(IBinder token) {
7296        final long origId = Binder.clearCallingIdentity();
7297        try {
7298            synchronized(this) {
7299                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7300                if (stack == null) {
7301                    return false;
7302                }
7303                return stack.mStackId == PINNED_STACK_ID;
7304            }
7305        } finally {
7306            Binder.restoreCallingIdentity(origId);
7307        }
7308    }
7309
7310    @Override
7311    public void enterPictureInPictureMode(IBinder token) {
7312        final long origId = Binder.clearCallingIdentity();
7313        try {
7314            synchronized(this) {
7315                if (!mSupportsPictureInPicture) {
7316                    throw new IllegalStateException("enterPictureInPictureMode: "
7317                            + "Device doesn't support picture-in-picture mode.");
7318                }
7319
7320                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7321
7322                if (r == null) {
7323                    throw new IllegalStateException("enterPictureInPictureMode: "
7324                            + "Can't find activity for token=" + token);
7325                }
7326
7327                if (!r.supportsPictureInPicture()) {
7328                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7329                            + "Picture-In-Picture not supported for r=" + r);
7330                }
7331
7332                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7333                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7334                        ? mDefaultPinnedStackBounds : null;
7335
7336                mStackSupervisor.moveActivityToPinnedStackLocked(
7337                        r, "enterPictureInPictureMode", bounds);
7338            }
7339        } finally {
7340            Binder.restoreCallingIdentity(origId);
7341        }
7342    }
7343
7344    // =========================================================
7345    // PROCESS INFO
7346    // =========================================================
7347
7348    static class ProcessInfoService extends IProcessInfoService.Stub {
7349        final ActivityManagerService mActivityManagerService;
7350        ProcessInfoService(ActivityManagerService activityManagerService) {
7351            mActivityManagerService = activityManagerService;
7352        }
7353
7354        @Override
7355        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7356            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7357                    /*in*/ pids, /*out*/ states, null);
7358        }
7359
7360        @Override
7361        public void getProcessStatesAndOomScoresFromPids(
7362                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7363            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7364                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7365        }
7366    }
7367
7368    /**
7369     * For each PID in the given input array, write the current process state
7370     * for that process into the states array, or -1 to indicate that no
7371     * process with the given PID exists. If scores array is provided, write
7372     * the oom score for the process into the scores array, with INVALID_ADJ
7373     * indicating the PID doesn't exist.
7374     */
7375    public void getProcessStatesAndOomScoresForPIDs(
7376            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7377        if (scores != null) {
7378            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7379                    "getProcessStatesAndOomScoresForPIDs()");
7380        }
7381
7382        if (pids == null) {
7383            throw new NullPointerException("pids");
7384        } else if (states == null) {
7385            throw new NullPointerException("states");
7386        } else if (pids.length != states.length) {
7387            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7388        } else if (scores != null && pids.length != scores.length) {
7389            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7390        }
7391
7392        synchronized (mPidsSelfLocked) {
7393            for (int i = 0; i < pids.length; i++) {
7394                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7395                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7396                        pr.curProcState;
7397                if (scores != null) {
7398                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7399                }
7400            }
7401        }
7402    }
7403
7404    // =========================================================
7405    // PERMISSIONS
7406    // =========================================================
7407
7408    static class PermissionController extends IPermissionController.Stub {
7409        ActivityManagerService mActivityManagerService;
7410        PermissionController(ActivityManagerService activityManagerService) {
7411            mActivityManagerService = activityManagerService;
7412        }
7413
7414        @Override
7415        public boolean checkPermission(String permission, int pid, int uid) {
7416            return mActivityManagerService.checkPermission(permission, pid,
7417                    uid) == PackageManager.PERMISSION_GRANTED;
7418        }
7419
7420        @Override
7421        public String[] getPackagesForUid(int uid) {
7422            return mActivityManagerService.mContext.getPackageManager()
7423                    .getPackagesForUid(uid);
7424        }
7425
7426        @Override
7427        public boolean isRuntimePermission(String permission) {
7428            try {
7429                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7430                        .getPermissionInfo(permission, 0);
7431                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7432            } catch (NameNotFoundException nnfe) {
7433                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7434            }
7435            return false;
7436        }
7437    }
7438
7439    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7440        @Override
7441        public int checkComponentPermission(String permission, int pid, int uid,
7442                int owningUid, boolean exported) {
7443            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7444                    owningUid, exported);
7445        }
7446
7447        @Override
7448        public Object getAMSLock() {
7449            return ActivityManagerService.this;
7450        }
7451    }
7452
7453    /**
7454     * This can be called with or without the global lock held.
7455     */
7456    int checkComponentPermission(String permission, int pid, int uid,
7457            int owningUid, boolean exported) {
7458        if (pid == MY_PID) {
7459            return PackageManager.PERMISSION_GRANTED;
7460        }
7461        return ActivityManager.checkComponentPermission(permission, uid,
7462                owningUid, exported);
7463    }
7464
7465    /**
7466     * As the only public entry point for permissions checking, this method
7467     * can enforce the semantic that requesting a check on a null global
7468     * permission is automatically denied.  (Internally a null permission
7469     * string is used when calling {@link #checkComponentPermission} in cases
7470     * when only uid-based security is needed.)
7471     *
7472     * This can be called with or without the global lock held.
7473     */
7474    @Override
7475    public int checkPermission(String permission, int pid, int uid) {
7476        if (permission == null) {
7477            return PackageManager.PERMISSION_DENIED;
7478        }
7479        return checkComponentPermission(permission, pid, uid, -1, true);
7480    }
7481
7482    @Override
7483    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7484        if (permission == null) {
7485            return PackageManager.PERMISSION_DENIED;
7486        }
7487
7488        // We might be performing an operation on behalf of an indirect binder
7489        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7490        // client identity accordingly before proceeding.
7491        Identity tlsIdentity = sCallerIdentity.get();
7492        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7493            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7494                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7495            uid = tlsIdentity.uid;
7496            pid = tlsIdentity.pid;
7497        }
7498
7499        return checkComponentPermission(permission, pid, uid, -1, true);
7500    }
7501
7502    /**
7503     * Binder IPC calls go through the public entry point.
7504     * This can be called with or without the global lock held.
7505     */
7506    int checkCallingPermission(String permission) {
7507        return checkPermission(permission,
7508                Binder.getCallingPid(),
7509                UserHandle.getAppId(Binder.getCallingUid()));
7510    }
7511
7512    /**
7513     * This can be called with or without the global lock held.
7514     */
7515    void enforceCallingPermission(String permission, String func) {
7516        if (checkCallingPermission(permission)
7517                == PackageManager.PERMISSION_GRANTED) {
7518            return;
7519        }
7520
7521        String msg = "Permission Denial: " + func + " from pid="
7522                + Binder.getCallingPid()
7523                + ", uid=" + Binder.getCallingUid()
7524                + " requires " + permission;
7525        Slog.w(TAG, msg);
7526        throw new SecurityException(msg);
7527    }
7528
7529    /**
7530     * Determine if UID is holding permissions required to access {@link Uri} in
7531     * the given {@link ProviderInfo}. Final permission checking is always done
7532     * in {@link ContentProvider}.
7533     */
7534    private final boolean checkHoldingPermissionsLocked(
7535            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7536        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7537                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7538        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7539            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7540                    != PERMISSION_GRANTED) {
7541                return false;
7542            }
7543        }
7544        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7545    }
7546
7547    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7548            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7549        if (pi.applicationInfo.uid == uid) {
7550            return true;
7551        } else if (!pi.exported) {
7552            return false;
7553        }
7554
7555        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7556        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7557        try {
7558            // check if target holds top-level <provider> permissions
7559            if (!readMet && pi.readPermission != null && considerUidPermissions
7560                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7561                readMet = true;
7562            }
7563            if (!writeMet && pi.writePermission != null && considerUidPermissions
7564                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7565                writeMet = true;
7566            }
7567
7568            // track if unprotected read/write is allowed; any denied
7569            // <path-permission> below removes this ability
7570            boolean allowDefaultRead = pi.readPermission == null;
7571            boolean allowDefaultWrite = pi.writePermission == null;
7572
7573            // check if target holds any <path-permission> that match uri
7574            final PathPermission[] pps = pi.pathPermissions;
7575            if (pps != null) {
7576                final String path = grantUri.uri.getPath();
7577                int i = pps.length;
7578                while (i > 0 && (!readMet || !writeMet)) {
7579                    i--;
7580                    PathPermission pp = pps[i];
7581                    if (pp.match(path)) {
7582                        if (!readMet) {
7583                            final String pprperm = pp.getReadPermission();
7584                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7585                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7586                                    + ": match=" + pp.match(path)
7587                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7588                            if (pprperm != null) {
7589                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7590                                        == PERMISSION_GRANTED) {
7591                                    readMet = true;
7592                                } else {
7593                                    allowDefaultRead = false;
7594                                }
7595                            }
7596                        }
7597                        if (!writeMet) {
7598                            final String ppwperm = pp.getWritePermission();
7599                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7600                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7601                                    + ": match=" + pp.match(path)
7602                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7603                            if (ppwperm != null) {
7604                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7605                                        == PERMISSION_GRANTED) {
7606                                    writeMet = true;
7607                                } else {
7608                                    allowDefaultWrite = false;
7609                                }
7610                            }
7611                        }
7612                    }
7613                }
7614            }
7615
7616            // grant unprotected <provider> read/write, if not blocked by
7617            // <path-permission> above
7618            if (allowDefaultRead) readMet = true;
7619            if (allowDefaultWrite) writeMet = true;
7620
7621        } catch (RemoteException e) {
7622            return false;
7623        }
7624
7625        return readMet && writeMet;
7626    }
7627
7628    public int getAppStartMode(int uid, String packageName) {
7629        synchronized (this) {
7630            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7631        }
7632    }
7633
7634    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7635            boolean allowWhenForeground) {
7636        UidRecord uidRec = mActiveUids.get(uid);
7637        if (!mLenientBackgroundCheck) {
7638            if (!allowWhenForeground || uidRec == null
7639                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7640                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7641                        packageName) != AppOpsManager.MODE_ALLOWED) {
7642                    return ActivityManager.APP_START_MODE_DELAYED;
7643                }
7644            }
7645
7646        } else if (uidRec == null || uidRec.idle) {
7647            if (callingPid >= 0) {
7648                ProcessRecord proc;
7649                synchronized (mPidsSelfLocked) {
7650                    proc = mPidsSelfLocked.get(callingPid);
7651                }
7652                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7653                    // Whoever is instigating this is in the foreground, so we will allow it
7654                    // to go through.
7655                    return ActivityManager.APP_START_MODE_NORMAL;
7656                }
7657            }
7658            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7659                    != AppOpsManager.MODE_ALLOWED) {
7660                return ActivityManager.APP_START_MODE_DELAYED;
7661            }
7662        }
7663        return ActivityManager.APP_START_MODE_NORMAL;
7664    }
7665
7666    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7667        ProviderInfo pi = null;
7668        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7669        if (cpr != null) {
7670            pi = cpr.info;
7671        } else {
7672            try {
7673                pi = AppGlobals.getPackageManager().resolveContentProvider(
7674                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7675            } catch (RemoteException ex) {
7676            }
7677        }
7678        return pi;
7679    }
7680
7681    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7682        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7683        if (targetUris != null) {
7684            return targetUris.get(grantUri);
7685        }
7686        return null;
7687    }
7688
7689    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7690            String targetPkg, int targetUid, GrantUri grantUri) {
7691        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7692        if (targetUris == null) {
7693            targetUris = Maps.newArrayMap();
7694            mGrantedUriPermissions.put(targetUid, targetUris);
7695        }
7696
7697        UriPermission perm = targetUris.get(grantUri);
7698        if (perm == null) {
7699            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7700            targetUris.put(grantUri, perm);
7701        }
7702
7703        return perm;
7704    }
7705
7706    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7707            final int modeFlags) {
7708        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7709        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7710                : UriPermission.STRENGTH_OWNED;
7711
7712        // Root gets to do everything.
7713        if (uid == 0) {
7714            return true;
7715        }
7716
7717        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7718        if (perms == null) return false;
7719
7720        // First look for exact match
7721        final UriPermission exactPerm = perms.get(grantUri);
7722        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7723            return true;
7724        }
7725
7726        // No exact match, look for prefixes
7727        final int N = perms.size();
7728        for (int i = 0; i < N; i++) {
7729            final UriPermission perm = perms.valueAt(i);
7730            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7731                    && perm.getStrength(modeFlags) >= minStrength) {
7732                return true;
7733            }
7734        }
7735
7736        return false;
7737    }
7738
7739    /**
7740     * @param uri This uri must NOT contain an embedded userId.
7741     * @param userId The userId in which the uri is to be resolved.
7742     */
7743    @Override
7744    public int checkUriPermission(Uri uri, int pid, int uid,
7745            final int modeFlags, int userId, IBinder callerToken) {
7746        enforceNotIsolatedCaller("checkUriPermission");
7747
7748        // Another redirected-binder-call permissions check as in
7749        // {@link checkPermissionWithToken}.
7750        Identity tlsIdentity = sCallerIdentity.get();
7751        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7752            uid = tlsIdentity.uid;
7753            pid = tlsIdentity.pid;
7754        }
7755
7756        // Our own process gets to do everything.
7757        if (pid == MY_PID) {
7758            return PackageManager.PERMISSION_GRANTED;
7759        }
7760        synchronized (this) {
7761            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7762                    ? PackageManager.PERMISSION_GRANTED
7763                    : PackageManager.PERMISSION_DENIED;
7764        }
7765    }
7766
7767    /**
7768     * Check if the targetPkg can be granted permission to access uri by
7769     * the callingUid using the given modeFlags.  Throws a security exception
7770     * if callingUid is not allowed to do this.  Returns the uid of the target
7771     * if the URI permission grant should be performed; returns -1 if it is not
7772     * needed (for example targetPkg already has permission to access the URI).
7773     * If you already know the uid of the target, you can supply it in
7774     * lastTargetUid else set that to -1.
7775     */
7776    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7777            final int modeFlags, int lastTargetUid) {
7778        if (!Intent.isAccessUriMode(modeFlags)) {
7779            return -1;
7780        }
7781
7782        if (targetPkg != null) {
7783            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7784                    "Checking grant " + targetPkg + " permission to " + grantUri);
7785        }
7786
7787        final IPackageManager pm = AppGlobals.getPackageManager();
7788
7789        // If this is not a content: uri, we can't do anything with it.
7790        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7791            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7792                    "Can't grant URI permission for non-content URI: " + grantUri);
7793            return -1;
7794        }
7795
7796        final String authority = grantUri.uri.getAuthority();
7797        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7798        if (pi == null) {
7799            Slog.w(TAG, "No content provider found for permission check: " +
7800                    grantUri.uri.toSafeString());
7801            return -1;
7802        }
7803
7804        int targetUid = lastTargetUid;
7805        if (targetUid < 0 && targetPkg != null) {
7806            try {
7807                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7808                        UserHandle.getUserId(callingUid));
7809                if (targetUid < 0) {
7810                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7811                            "Can't grant URI permission no uid for: " + targetPkg);
7812                    return -1;
7813                }
7814            } catch (RemoteException ex) {
7815                return -1;
7816            }
7817        }
7818
7819        if (targetUid >= 0) {
7820            // First...  does the target actually need this permission?
7821            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7822                // No need to grant the target this permission.
7823                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7824                        "Target " + targetPkg + " already has full permission to " + grantUri);
7825                return -1;
7826            }
7827        } else {
7828            // First...  there is no target package, so can anyone access it?
7829            boolean allowed = pi.exported;
7830            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7831                if (pi.readPermission != null) {
7832                    allowed = false;
7833                }
7834            }
7835            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7836                if (pi.writePermission != null) {
7837                    allowed = false;
7838                }
7839            }
7840            if (allowed) {
7841                return -1;
7842            }
7843        }
7844
7845        /* There is a special cross user grant if:
7846         * - The target is on another user.
7847         * - Apps on the current user can access the uri without any uid permissions.
7848         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7849         * grant uri permissions.
7850         */
7851        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7852                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7853                modeFlags, false /*without considering the uid permissions*/);
7854
7855        // Second...  is the provider allowing granting of URI permissions?
7856        if (!specialCrossUserGrant) {
7857            if (!pi.grantUriPermissions) {
7858                throw new SecurityException("Provider " + pi.packageName
7859                        + "/" + pi.name
7860                        + " does not allow granting of Uri permissions (uri "
7861                        + grantUri + ")");
7862            }
7863            if (pi.uriPermissionPatterns != null) {
7864                final int N = pi.uriPermissionPatterns.length;
7865                boolean allowed = false;
7866                for (int i=0; i<N; i++) {
7867                    if (pi.uriPermissionPatterns[i] != null
7868                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7869                        allowed = true;
7870                        break;
7871                    }
7872                }
7873                if (!allowed) {
7874                    throw new SecurityException("Provider " + pi.packageName
7875                            + "/" + pi.name
7876                            + " does not allow granting of permission to path of Uri "
7877                            + grantUri);
7878                }
7879            }
7880        }
7881
7882        // Third...  does the caller itself have permission to access
7883        // this uri?
7884        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7885            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7886                // Require they hold a strong enough Uri permission
7887                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7888                    throw new SecurityException("Uid " + callingUid
7889                            + " does not have permission to uri " + grantUri);
7890                }
7891            }
7892        }
7893        return targetUid;
7894    }
7895
7896    /**
7897     * @param uri This uri must NOT contain an embedded userId.
7898     * @param userId The userId in which the uri is to be resolved.
7899     */
7900    @Override
7901    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7902            final int modeFlags, int userId) {
7903        enforceNotIsolatedCaller("checkGrantUriPermission");
7904        synchronized(this) {
7905            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7906                    new GrantUri(userId, uri, false), modeFlags, -1);
7907        }
7908    }
7909
7910    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7911            final int modeFlags, UriPermissionOwner owner) {
7912        if (!Intent.isAccessUriMode(modeFlags)) {
7913            return;
7914        }
7915
7916        // So here we are: the caller has the assumed permission
7917        // to the uri, and the target doesn't.  Let's now give this to
7918        // the target.
7919
7920        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7921                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7922
7923        final String authority = grantUri.uri.getAuthority();
7924        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7925        if (pi == null) {
7926            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7927            return;
7928        }
7929
7930        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7931            grantUri.prefix = true;
7932        }
7933        final UriPermission perm = findOrCreateUriPermissionLocked(
7934                pi.packageName, targetPkg, targetUid, grantUri);
7935        perm.grantModes(modeFlags, owner);
7936    }
7937
7938    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7939            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7940        if (targetPkg == null) {
7941            throw new NullPointerException("targetPkg");
7942        }
7943        int targetUid;
7944        final IPackageManager pm = AppGlobals.getPackageManager();
7945        try {
7946            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7947        } catch (RemoteException ex) {
7948            return;
7949        }
7950
7951        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7952                targetUid);
7953        if (targetUid < 0) {
7954            return;
7955        }
7956
7957        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7958                owner);
7959    }
7960
7961    static class NeededUriGrants extends ArrayList<GrantUri> {
7962        final String targetPkg;
7963        final int targetUid;
7964        final int flags;
7965
7966        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7967            this.targetPkg = targetPkg;
7968            this.targetUid = targetUid;
7969            this.flags = flags;
7970        }
7971    }
7972
7973    /**
7974     * Like checkGrantUriPermissionLocked, but takes an Intent.
7975     */
7976    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7977            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7978        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7979                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7980                + " clip=" + (intent != null ? intent.getClipData() : null)
7981                + " from " + intent + "; flags=0x"
7982                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7983
7984        if (targetPkg == null) {
7985            throw new NullPointerException("targetPkg");
7986        }
7987
7988        if (intent == null) {
7989            return null;
7990        }
7991        Uri data = intent.getData();
7992        ClipData clip = intent.getClipData();
7993        if (data == null && clip == null) {
7994            return null;
7995        }
7996        // Default userId for uris in the intent (if they don't specify it themselves)
7997        int contentUserHint = intent.getContentUserHint();
7998        if (contentUserHint == UserHandle.USER_CURRENT) {
7999            contentUserHint = UserHandle.getUserId(callingUid);
8000        }
8001        final IPackageManager pm = AppGlobals.getPackageManager();
8002        int targetUid;
8003        if (needed != null) {
8004            targetUid = needed.targetUid;
8005        } else {
8006            try {
8007                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8008                        targetUserId);
8009            } catch (RemoteException ex) {
8010                return null;
8011            }
8012            if (targetUid < 0) {
8013                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8014                        "Can't grant URI permission no uid for: " + targetPkg
8015                        + " on user " + targetUserId);
8016                return null;
8017            }
8018        }
8019        if (data != null) {
8020            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8021            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8022                    targetUid);
8023            if (targetUid > 0) {
8024                if (needed == null) {
8025                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8026                }
8027                needed.add(grantUri);
8028            }
8029        }
8030        if (clip != null) {
8031            for (int i=0; i<clip.getItemCount(); i++) {
8032                Uri uri = clip.getItemAt(i).getUri();
8033                if (uri != null) {
8034                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8035                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8036                            targetUid);
8037                    if (targetUid > 0) {
8038                        if (needed == null) {
8039                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8040                        }
8041                        needed.add(grantUri);
8042                    }
8043                } else {
8044                    Intent clipIntent = clip.getItemAt(i).getIntent();
8045                    if (clipIntent != null) {
8046                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8047                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8048                        if (newNeeded != null) {
8049                            needed = newNeeded;
8050                        }
8051                    }
8052                }
8053            }
8054        }
8055
8056        return needed;
8057    }
8058
8059    /**
8060     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8061     */
8062    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8063            UriPermissionOwner owner) {
8064        if (needed != null) {
8065            for (int i=0; i<needed.size(); i++) {
8066                GrantUri grantUri = needed.get(i);
8067                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8068                        grantUri, needed.flags, owner);
8069            }
8070        }
8071    }
8072
8073    void grantUriPermissionFromIntentLocked(int callingUid,
8074            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8075        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8076                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8077        if (needed == null) {
8078            return;
8079        }
8080
8081        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8082    }
8083
8084    /**
8085     * @param uri This uri must NOT contain an embedded userId.
8086     * @param userId The userId in which the uri is to be resolved.
8087     */
8088    @Override
8089    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8090            final int modeFlags, int userId) {
8091        enforceNotIsolatedCaller("grantUriPermission");
8092        GrantUri grantUri = new GrantUri(userId, uri, false);
8093        synchronized(this) {
8094            final ProcessRecord r = getRecordForAppLocked(caller);
8095            if (r == null) {
8096                throw new SecurityException("Unable to find app for caller "
8097                        + caller
8098                        + " when granting permission to uri " + grantUri);
8099            }
8100            if (targetPkg == null) {
8101                throw new IllegalArgumentException("null target");
8102            }
8103            if (grantUri == null) {
8104                throw new IllegalArgumentException("null uri");
8105            }
8106
8107            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8108                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8109                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8110                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8111
8112            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8113                    UserHandle.getUserId(r.uid));
8114        }
8115    }
8116
8117    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8118        if (perm.modeFlags == 0) {
8119            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8120                    perm.targetUid);
8121            if (perms != null) {
8122                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8123                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8124
8125                perms.remove(perm.uri);
8126                if (perms.isEmpty()) {
8127                    mGrantedUriPermissions.remove(perm.targetUid);
8128                }
8129            }
8130        }
8131    }
8132
8133    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8134        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8135                "Revoking all granted permissions to " + grantUri);
8136
8137        final IPackageManager pm = AppGlobals.getPackageManager();
8138        final String authority = grantUri.uri.getAuthority();
8139        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8140        if (pi == null) {
8141            Slog.w(TAG, "No content provider found for permission revoke: "
8142                    + grantUri.toSafeString());
8143            return;
8144        }
8145
8146        // Does the caller have this permission on the URI?
8147        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8148            // If they don't have direct access to the URI, then revoke any
8149            // ownerless URI permissions that have been granted to them.
8150            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8151            if (perms != null) {
8152                boolean persistChanged = false;
8153                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8154                    final UriPermission perm = it.next();
8155                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8156                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8157                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8158                                "Revoking non-owned " + perm.targetUid
8159                                + " permission to " + perm.uri);
8160                        persistChanged |= perm.revokeModes(
8161                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8162                        if (perm.modeFlags == 0) {
8163                            it.remove();
8164                        }
8165                    }
8166                }
8167                if (perms.isEmpty()) {
8168                    mGrantedUriPermissions.remove(callingUid);
8169                }
8170                if (persistChanged) {
8171                    schedulePersistUriGrants();
8172                }
8173            }
8174            return;
8175        }
8176
8177        boolean persistChanged = false;
8178
8179        // Go through all of the permissions and remove any that match.
8180        int N = mGrantedUriPermissions.size();
8181        for (int i = 0; i < N; i++) {
8182            final int targetUid = mGrantedUriPermissions.keyAt(i);
8183            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8184
8185            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8186                final UriPermission perm = it.next();
8187                if (perm.uri.sourceUserId == grantUri.sourceUserId
8188                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8189                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8190                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8191                    persistChanged |= perm.revokeModes(
8192                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8193                    if (perm.modeFlags == 0) {
8194                        it.remove();
8195                    }
8196                }
8197            }
8198
8199            if (perms.isEmpty()) {
8200                mGrantedUriPermissions.remove(targetUid);
8201                N--;
8202                i--;
8203            }
8204        }
8205
8206        if (persistChanged) {
8207            schedulePersistUriGrants();
8208        }
8209    }
8210
8211    /**
8212     * @param uri This uri must NOT contain an embedded userId.
8213     * @param userId The userId in which the uri is to be resolved.
8214     */
8215    @Override
8216    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8217            int userId) {
8218        enforceNotIsolatedCaller("revokeUriPermission");
8219        synchronized(this) {
8220            final ProcessRecord r = getRecordForAppLocked(caller);
8221            if (r == null) {
8222                throw new SecurityException("Unable to find app for caller "
8223                        + caller
8224                        + " when revoking permission to uri " + uri);
8225            }
8226            if (uri == null) {
8227                Slog.w(TAG, "revokeUriPermission: null uri");
8228                return;
8229            }
8230
8231            if (!Intent.isAccessUriMode(modeFlags)) {
8232                return;
8233            }
8234
8235            final String authority = uri.getAuthority();
8236            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8237            if (pi == null) {
8238                Slog.w(TAG, "No content provider found for permission revoke: "
8239                        + uri.toSafeString());
8240                return;
8241            }
8242
8243            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8244        }
8245    }
8246
8247    /**
8248     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8249     * given package.
8250     *
8251     * @param packageName Package name to match, or {@code null} to apply to all
8252     *            packages.
8253     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8254     *            to all users.
8255     * @param persistable If persistable grants should be removed.
8256     */
8257    private void removeUriPermissionsForPackageLocked(
8258            String packageName, int userHandle, boolean persistable) {
8259        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8260            throw new IllegalArgumentException("Must narrow by either package or user");
8261        }
8262
8263        boolean persistChanged = false;
8264
8265        int N = mGrantedUriPermissions.size();
8266        for (int i = 0; i < N; i++) {
8267            final int targetUid = mGrantedUriPermissions.keyAt(i);
8268            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8269
8270            // Only inspect grants matching user
8271            if (userHandle == UserHandle.USER_ALL
8272                    || userHandle == UserHandle.getUserId(targetUid)) {
8273                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8274                    final UriPermission perm = it.next();
8275
8276                    // Only inspect grants matching package
8277                    if (packageName == null || perm.sourcePkg.equals(packageName)
8278                            || perm.targetPkg.equals(packageName)) {
8279                        persistChanged |= perm.revokeModes(persistable
8280                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8281
8282                        // Only remove when no modes remain; any persisted grants
8283                        // will keep this alive.
8284                        if (perm.modeFlags == 0) {
8285                            it.remove();
8286                        }
8287                    }
8288                }
8289
8290                if (perms.isEmpty()) {
8291                    mGrantedUriPermissions.remove(targetUid);
8292                    N--;
8293                    i--;
8294                }
8295            }
8296        }
8297
8298        if (persistChanged) {
8299            schedulePersistUriGrants();
8300        }
8301    }
8302
8303    @Override
8304    public IBinder newUriPermissionOwner(String name) {
8305        enforceNotIsolatedCaller("newUriPermissionOwner");
8306        synchronized(this) {
8307            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8308            return owner.getExternalTokenLocked();
8309        }
8310    }
8311
8312    @Override
8313    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8314        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8315        synchronized(this) {
8316            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8317            if (r == null) {
8318                throw new IllegalArgumentException("Activity does not exist; token="
8319                        + activityToken);
8320            }
8321            return r.getUriPermissionsLocked().getExternalTokenLocked();
8322        }
8323    }
8324    /**
8325     * @param uri This uri must NOT contain an embedded userId.
8326     * @param sourceUserId The userId in which the uri is to be resolved.
8327     * @param targetUserId The userId of the app that receives the grant.
8328     */
8329    @Override
8330    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8331            final int modeFlags, int sourceUserId, int targetUserId) {
8332        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8333                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8334                "grantUriPermissionFromOwner", null);
8335        synchronized(this) {
8336            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8337            if (owner == null) {
8338                throw new IllegalArgumentException("Unknown owner: " + token);
8339            }
8340            if (fromUid != Binder.getCallingUid()) {
8341                if (Binder.getCallingUid() != Process.myUid()) {
8342                    // Only system code can grant URI permissions on behalf
8343                    // of other users.
8344                    throw new SecurityException("nice try");
8345                }
8346            }
8347            if (targetPkg == null) {
8348                throw new IllegalArgumentException("null target");
8349            }
8350            if (uri == null) {
8351                throw new IllegalArgumentException("null uri");
8352            }
8353
8354            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8355                    modeFlags, owner, targetUserId);
8356        }
8357    }
8358
8359    /**
8360     * @param uri This uri must NOT contain an embedded userId.
8361     * @param userId The userId in which the uri is to be resolved.
8362     */
8363    @Override
8364    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8365        synchronized(this) {
8366            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8367            if (owner == null) {
8368                throw new IllegalArgumentException("Unknown owner: " + token);
8369            }
8370
8371            if (uri == null) {
8372                owner.removeUriPermissionsLocked(mode);
8373            } else {
8374                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8375            }
8376        }
8377    }
8378
8379    private void schedulePersistUriGrants() {
8380        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8381            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8382                    10 * DateUtils.SECOND_IN_MILLIS);
8383        }
8384    }
8385
8386    private void writeGrantedUriPermissions() {
8387        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8388
8389        // Snapshot permissions so we can persist without lock
8390        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8391        synchronized (this) {
8392            final int size = mGrantedUriPermissions.size();
8393            for (int i = 0; i < size; i++) {
8394                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8395                for (UriPermission perm : perms.values()) {
8396                    if (perm.persistedModeFlags != 0) {
8397                        persist.add(perm.snapshot());
8398                    }
8399                }
8400            }
8401        }
8402
8403        FileOutputStream fos = null;
8404        try {
8405            fos = mGrantFile.startWrite();
8406
8407            XmlSerializer out = new FastXmlSerializer();
8408            out.setOutput(fos, StandardCharsets.UTF_8.name());
8409            out.startDocument(null, true);
8410            out.startTag(null, TAG_URI_GRANTS);
8411            for (UriPermission.Snapshot perm : persist) {
8412                out.startTag(null, TAG_URI_GRANT);
8413                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8414                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8415                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8416                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8417                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8418                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8419                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8420                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8421                out.endTag(null, TAG_URI_GRANT);
8422            }
8423            out.endTag(null, TAG_URI_GRANTS);
8424            out.endDocument();
8425
8426            mGrantFile.finishWrite(fos);
8427        } catch (IOException e) {
8428            if (fos != null) {
8429                mGrantFile.failWrite(fos);
8430            }
8431        }
8432    }
8433
8434    private void readGrantedUriPermissionsLocked() {
8435        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8436
8437        final long now = System.currentTimeMillis();
8438
8439        FileInputStream fis = null;
8440        try {
8441            fis = mGrantFile.openRead();
8442            final XmlPullParser in = Xml.newPullParser();
8443            in.setInput(fis, StandardCharsets.UTF_8.name());
8444
8445            int type;
8446            while ((type = in.next()) != END_DOCUMENT) {
8447                final String tag = in.getName();
8448                if (type == START_TAG) {
8449                    if (TAG_URI_GRANT.equals(tag)) {
8450                        final int sourceUserId;
8451                        final int targetUserId;
8452                        final int userHandle = readIntAttribute(in,
8453                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8454                        if (userHandle != UserHandle.USER_NULL) {
8455                            // For backwards compatibility.
8456                            sourceUserId = userHandle;
8457                            targetUserId = userHandle;
8458                        } else {
8459                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8460                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8461                        }
8462                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8463                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8464                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8465                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8466                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8467                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8468
8469                        // Sanity check that provider still belongs to source package
8470                        final ProviderInfo pi = getProviderInfoLocked(
8471                                uri.getAuthority(), sourceUserId);
8472                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8473                            int targetUid = -1;
8474                            try {
8475                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8476                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8477                            } catch (RemoteException e) {
8478                            }
8479                            if (targetUid != -1) {
8480                                final UriPermission perm = findOrCreateUriPermissionLocked(
8481                                        sourcePkg, targetPkg, targetUid,
8482                                        new GrantUri(sourceUserId, uri, prefix));
8483                                perm.initPersistedModes(modeFlags, createdTime);
8484                            }
8485                        } else {
8486                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8487                                    + " but instead found " + pi);
8488                        }
8489                    }
8490                }
8491            }
8492        } catch (FileNotFoundException e) {
8493            // Missing grants is okay
8494        } catch (IOException e) {
8495            Slog.wtf(TAG, "Failed reading Uri grants", e);
8496        } catch (XmlPullParserException e) {
8497            Slog.wtf(TAG, "Failed reading Uri grants", e);
8498        } finally {
8499            IoUtils.closeQuietly(fis);
8500        }
8501    }
8502
8503    /**
8504     * @param uri This uri must NOT contain an embedded userId.
8505     * @param userId The userId in which the uri is to be resolved.
8506     */
8507    @Override
8508    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8509        enforceNotIsolatedCaller("takePersistableUriPermission");
8510
8511        Preconditions.checkFlagsArgument(modeFlags,
8512                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8513
8514        synchronized (this) {
8515            final int callingUid = Binder.getCallingUid();
8516            boolean persistChanged = false;
8517            GrantUri grantUri = new GrantUri(userId, uri, false);
8518
8519            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8520                    new GrantUri(userId, uri, false));
8521            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8522                    new GrantUri(userId, uri, true));
8523
8524            final boolean exactValid = (exactPerm != null)
8525                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8526            final boolean prefixValid = (prefixPerm != null)
8527                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8528
8529            if (!(exactValid || prefixValid)) {
8530                throw new SecurityException("No persistable permission grants found for UID "
8531                        + callingUid + " and Uri " + grantUri.toSafeString());
8532            }
8533
8534            if (exactValid) {
8535                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8536            }
8537            if (prefixValid) {
8538                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8539            }
8540
8541            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8542
8543            if (persistChanged) {
8544                schedulePersistUriGrants();
8545            }
8546        }
8547    }
8548
8549    /**
8550     * @param uri This uri must NOT contain an embedded userId.
8551     * @param userId The userId in which the uri is to be resolved.
8552     */
8553    @Override
8554    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8555        enforceNotIsolatedCaller("releasePersistableUriPermission");
8556
8557        Preconditions.checkFlagsArgument(modeFlags,
8558                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8559
8560        synchronized (this) {
8561            final int callingUid = Binder.getCallingUid();
8562            boolean persistChanged = false;
8563
8564            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8565                    new GrantUri(userId, uri, false));
8566            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8567                    new GrantUri(userId, uri, true));
8568            if (exactPerm == null && prefixPerm == null) {
8569                throw new SecurityException("No permission grants found for UID " + callingUid
8570                        + " and Uri " + uri.toSafeString());
8571            }
8572
8573            if (exactPerm != null) {
8574                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8575                removeUriPermissionIfNeededLocked(exactPerm);
8576            }
8577            if (prefixPerm != null) {
8578                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8579                removeUriPermissionIfNeededLocked(prefixPerm);
8580            }
8581
8582            if (persistChanged) {
8583                schedulePersistUriGrants();
8584            }
8585        }
8586    }
8587
8588    /**
8589     * Prune any older {@link UriPermission} for the given UID until outstanding
8590     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8591     *
8592     * @return if any mutations occured that require persisting.
8593     */
8594    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8595        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8596        if (perms == null) return false;
8597        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8598
8599        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8600        for (UriPermission perm : perms.values()) {
8601            if (perm.persistedModeFlags != 0) {
8602                persisted.add(perm);
8603            }
8604        }
8605
8606        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8607        if (trimCount <= 0) return false;
8608
8609        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8610        for (int i = 0; i < trimCount; i++) {
8611            final UriPermission perm = persisted.get(i);
8612
8613            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8614                    "Trimming grant created at " + perm.persistedCreateTime);
8615
8616            perm.releasePersistableModes(~0);
8617            removeUriPermissionIfNeededLocked(perm);
8618        }
8619
8620        return true;
8621    }
8622
8623    @Override
8624    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8625            String packageName, boolean incoming) {
8626        enforceNotIsolatedCaller("getPersistedUriPermissions");
8627        Preconditions.checkNotNull(packageName, "packageName");
8628
8629        final int callingUid = Binder.getCallingUid();
8630        final IPackageManager pm = AppGlobals.getPackageManager();
8631        try {
8632            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8633                    UserHandle.getUserId(callingUid));
8634            if (packageUid != callingUid) {
8635                throw new SecurityException(
8636                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8637            }
8638        } catch (RemoteException e) {
8639            throw new SecurityException("Failed to verify package name ownership");
8640        }
8641
8642        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8643        synchronized (this) {
8644            if (incoming) {
8645                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8646                        callingUid);
8647                if (perms == null) {
8648                    Slog.w(TAG, "No permission grants found for " + packageName);
8649                } else {
8650                    for (UriPermission perm : perms.values()) {
8651                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8652                            result.add(perm.buildPersistedPublicApiObject());
8653                        }
8654                    }
8655                }
8656            } else {
8657                final int size = mGrantedUriPermissions.size();
8658                for (int i = 0; i < size; i++) {
8659                    final ArrayMap<GrantUri, UriPermission> perms =
8660                            mGrantedUriPermissions.valueAt(i);
8661                    for (UriPermission perm : perms.values()) {
8662                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8663                            result.add(perm.buildPersistedPublicApiObject());
8664                        }
8665                    }
8666                }
8667            }
8668        }
8669        return new ParceledListSlice<android.content.UriPermission>(result);
8670    }
8671
8672    @Override
8673    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8674            String packageName, int userId) {
8675        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8676                "getGrantedUriPermissions");
8677
8678        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8679        synchronized (this) {
8680            final int size = mGrantedUriPermissions.size();
8681            for (int i = 0; i < size; i++) {
8682                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8683                for (UriPermission perm : perms.values()) {
8684                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8685                            && perm.persistedModeFlags != 0) {
8686                        result.add(perm.buildPersistedPublicApiObject());
8687                    }
8688                }
8689            }
8690        }
8691        return new ParceledListSlice<android.content.UriPermission>(result);
8692    }
8693
8694    @Override
8695    public void clearGrantedUriPermissions(String packageName, int userId) {
8696        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8697                "clearGrantedUriPermissions");
8698        removeUriPermissionsForPackageLocked(packageName, userId, true);
8699    }
8700
8701    @Override
8702    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8703        synchronized (this) {
8704            ProcessRecord app =
8705                who != null ? getRecordForAppLocked(who) : null;
8706            if (app == null) return;
8707
8708            Message msg = Message.obtain();
8709            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8710            msg.obj = app;
8711            msg.arg1 = waiting ? 1 : 0;
8712            mUiHandler.sendMessage(msg);
8713        }
8714    }
8715
8716    @Override
8717    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8718        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8719        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8720        outInfo.availMem = Process.getFreeMemory();
8721        outInfo.totalMem = Process.getTotalMemory();
8722        outInfo.threshold = homeAppMem;
8723        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8724        outInfo.hiddenAppThreshold = cachedAppMem;
8725        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8726                ProcessList.SERVICE_ADJ);
8727        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8728                ProcessList.VISIBLE_APP_ADJ);
8729        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8730                ProcessList.FOREGROUND_APP_ADJ);
8731    }
8732
8733    // =========================================================
8734    // TASK MANAGEMENT
8735    // =========================================================
8736
8737    @Override
8738    public List<IAppTask> getAppTasks(String callingPackage) {
8739        int callingUid = Binder.getCallingUid();
8740        long ident = Binder.clearCallingIdentity();
8741
8742        synchronized(this) {
8743            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8744            try {
8745                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8746
8747                final int N = mRecentTasks.size();
8748                for (int i = 0; i < N; i++) {
8749                    TaskRecord tr = mRecentTasks.get(i);
8750                    // Skip tasks that do not match the caller.  We don't need to verify
8751                    // callingPackage, because we are also limiting to callingUid and know
8752                    // that will limit to the correct security sandbox.
8753                    if (tr.effectiveUid != callingUid) {
8754                        continue;
8755                    }
8756                    Intent intent = tr.getBaseIntent();
8757                    if (intent == null ||
8758                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8759                        continue;
8760                    }
8761                    ActivityManager.RecentTaskInfo taskInfo =
8762                            createRecentTaskInfoFromTaskRecord(tr);
8763                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8764                    list.add(taskImpl);
8765                }
8766            } finally {
8767                Binder.restoreCallingIdentity(ident);
8768            }
8769            return list;
8770        }
8771    }
8772
8773    @Override
8774    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8775        final int callingUid = Binder.getCallingUid();
8776        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8777
8778        synchronized(this) {
8779            if (DEBUG_ALL) Slog.v(
8780                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8781
8782            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8783                    callingUid);
8784
8785            // TODO: Improve with MRU list from all ActivityStacks.
8786            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8787        }
8788
8789        return list;
8790    }
8791
8792    /**
8793     * Creates a new RecentTaskInfo from a TaskRecord.
8794     */
8795    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8796        // Update the task description to reflect any changes in the task stack
8797        tr.updateTaskDescription();
8798
8799        // Compose the recent task info
8800        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8801        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8802        rti.persistentId = tr.taskId;
8803        rti.baseIntent = new Intent(tr.getBaseIntent());
8804        rti.origActivity = tr.origActivity;
8805        rti.realActivity = tr.realActivity;
8806        rti.description = tr.lastDescription;
8807        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8808        rti.userId = tr.userId;
8809        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8810        rti.firstActiveTime = tr.firstActiveTime;
8811        rti.lastActiveTime = tr.lastActiveTime;
8812        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8813        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8814        rti.numActivities = 0;
8815        if (tr.mBounds != null) {
8816            rti.bounds = new Rect(tr.mBounds);
8817        }
8818        rti.isDockable = tr.canGoInDockedStack();
8819        rti.resizeMode = tr.mResizeMode;
8820
8821        ActivityRecord base = null;
8822        ActivityRecord top = null;
8823        ActivityRecord tmp;
8824
8825        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8826            tmp = tr.mActivities.get(i);
8827            if (tmp.finishing) {
8828                continue;
8829            }
8830            base = tmp;
8831            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8832                top = base;
8833            }
8834            rti.numActivities++;
8835        }
8836
8837        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8838        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8839
8840        return rti;
8841    }
8842
8843    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8844        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8845                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8846        if (!allowed) {
8847            if (checkPermission(android.Manifest.permission.GET_TASKS,
8848                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8849                // Temporary compatibility: some existing apps on the system image may
8850                // still be requesting the old permission and not switched to the new
8851                // one; if so, we'll still allow them full access.  This means we need
8852                // to see if they are holding the old permission and are a system app.
8853                try {
8854                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8855                        allowed = true;
8856                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8857                                + " is using old GET_TASKS but privileged; allowing");
8858                    }
8859                } catch (RemoteException e) {
8860                }
8861            }
8862        }
8863        if (!allowed) {
8864            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8865                    + " does not hold REAL_GET_TASKS; limiting output");
8866        }
8867        return allowed;
8868    }
8869
8870    @Override
8871    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8872        final int callingUid = Binder.getCallingUid();
8873        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8874                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8875
8876        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8877        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8878        synchronized (this) {
8879            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8880                    callingUid);
8881            final boolean detailed = checkCallingPermission(
8882                    android.Manifest.permission.GET_DETAILED_TASKS)
8883                    == PackageManager.PERMISSION_GRANTED;
8884
8885            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8886                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8887                return Collections.emptyList();
8888            }
8889            mRecentTasks.loadUserRecentsLocked(userId);
8890
8891            final int recentsCount = mRecentTasks.size();
8892            ArrayList<ActivityManager.RecentTaskInfo> res =
8893                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8894
8895            final Set<Integer> includedUsers;
8896            if (includeProfiles) {
8897                includedUsers = mUserController.getProfileIds(userId);
8898            } else {
8899                includedUsers = new HashSet<>();
8900            }
8901            includedUsers.add(Integer.valueOf(userId));
8902
8903            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8904                TaskRecord tr = mRecentTasks.get(i);
8905                // Only add calling user or related users recent tasks
8906                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8907                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8908                    continue;
8909                }
8910
8911                if (tr.realActivitySuspended) {
8912                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8913                    continue;
8914                }
8915
8916                // Return the entry if desired by the caller.  We always return
8917                // the first entry, because callers always expect this to be the
8918                // foreground app.  We may filter others if the caller has
8919                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8920                // we should exclude the entry.
8921
8922                if (i == 0
8923                        || withExcluded
8924                        || (tr.intent == null)
8925                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8926                                == 0)) {
8927                    if (!allowed) {
8928                        // If the caller doesn't have the GET_TASKS permission, then only
8929                        // allow them to see a small subset of tasks -- their own and home.
8930                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8931                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8932                            continue;
8933                        }
8934                    }
8935                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8936                        if (tr.stack != null && tr.stack.isHomeStack()) {
8937                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8938                                    "Skipping, home stack task: " + tr);
8939                            continue;
8940                        }
8941                    }
8942                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8943                        final ActivityStack stack = tr.stack;
8944                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8945                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8946                                    "Skipping, top task in docked stack: " + tr);
8947                            continue;
8948                        }
8949                    }
8950                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8951                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8952                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8953                                    "Skipping, pinned stack task: " + tr);
8954                            continue;
8955                        }
8956                    }
8957                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8958                        // Don't include auto remove tasks that are finished or finishing.
8959                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8960                                "Skipping, auto-remove without activity: " + tr);
8961                        continue;
8962                    }
8963                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8964                            && !tr.isAvailable) {
8965                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8966                                "Skipping, unavail real act: " + tr);
8967                        continue;
8968                    }
8969
8970                    if (!tr.mUserSetupComplete) {
8971                        // Don't include task launched while user is not done setting-up.
8972                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8973                                "Skipping, user setup not complete: " + tr);
8974                        continue;
8975                    }
8976
8977                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8978                    if (!detailed) {
8979                        rti.baseIntent.replaceExtras((Bundle)null);
8980                    }
8981
8982                    res.add(rti);
8983                    maxNum--;
8984                }
8985            }
8986            return res;
8987        }
8988    }
8989
8990    @Override
8991    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8992        synchronized (this) {
8993            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8994                    "getTaskThumbnail()");
8995            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8996                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8997            if (tr != null) {
8998                return tr.getTaskThumbnailLocked();
8999            }
9000        }
9001        return null;
9002    }
9003
9004    @Override
9005    public int addAppTask(IBinder activityToken, Intent intent,
9006            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9007        final int callingUid = Binder.getCallingUid();
9008        final long callingIdent = Binder.clearCallingIdentity();
9009
9010        try {
9011            synchronized (this) {
9012                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9013                if (r == null) {
9014                    throw new IllegalArgumentException("Activity does not exist; token="
9015                            + activityToken);
9016                }
9017                ComponentName comp = intent.getComponent();
9018                if (comp == null) {
9019                    throw new IllegalArgumentException("Intent " + intent
9020                            + " must specify explicit component");
9021                }
9022                if (thumbnail.getWidth() != mThumbnailWidth
9023                        || thumbnail.getHeight() != mThumbnailHeight) {
9024                    throw new IllegalArgumentException("Bad thumbnail size: got "
9025                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9026                            + mThumbnailWidth + "x" + mThumbnailHeight);
9027                }
9028                if (intent.getSelector() != null) {
9029                    intent.setSelector(null);
9030                }
9031                if (intent.getSourceBounds() != null) {
9032                    intent.setSourceBounds(null);
9033                }
9034                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9035                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9036                        // The caller has added this as an auto-remove task...  that makes no
9037                        // sense, so turn off auto-remove.
9038                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9039                    }
9040                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9041                    // Must be a new task.
9042                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9043                }
9044                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9045                    mLastAddedTaskActivity = null;
9046                }
9047                ActivityInfo ainfo = mLastAddedTaskActivity;
9048                if (ainfo == null) {
9049                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9050                            comp, 0, UserHandle.getUserId(callingUid));
9051                    if (ainfo.applicationInfo.uid != callingUid) {
9052                        throw new SecurityException(
9053                                "Can't add task for another application: target uid="
9054                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9055                    }
9056                }
9057
9058                // Use the full screen as the context for the task thumbnail
9059                final Point displaySize = new Point();
9060                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9061                r.task.stack.getDisplaySize(displaySize);
9062                thumbnailInfo.taskWidth = displaySize.x;
9063                thumbnailInfo.taskHeight = displaySize.y;
9064                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9065
9066                TaskRecord task = new TaskRecord(this,
9067                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9068                        ainfo, intent, description, thumbnailInfo);
9069
9070                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9071                if (trimIdx >= 0) {
9072                    // If this would have caused a trim, then we'll abort because that
9073                    // means it would be added at the end of the list but then just removed.
9074                    return INVALID_TASK_ID;
9075                }
9076
9077                final int N = mRecentTasks.size();
9078                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9079                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9080                    tr.removedFromRecents();
9081                }
9082
9083                task.inRecents = true;
9084                mRecentTasks.add(task);
9085                r.task.stack.addTask(task, false, "addAppTask");
9086
9087                task.setLastThumbnailLocked(thumbnail);
9088                task.freeLastThumbnail();
9089
9090                return task.taskId;
9091            }
9092        } finally {
9093            Binder.restoreCallingIdentity(callingIdent);
9094        }
9095    }
9096
9097    @Override
9098    public Point getAppTaskThumbnailSize() {
9099        synchronized (this) {
9100            return new Point(mThumbnailWidth,  mThumbnailHeight);
9101        }
9102    }
9103
9104    @Override
9105    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9106        synchronized (this) {
9107            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9108            if (r != null) {
9109                r.setTaskDescription(td);
9110                r.task.updateTaskDescription();
9111            }
9112        }
9113    }
9114
9115    @Override
9116    public void setTaskResizeable(int taskId, int resizeableMode) {
9117        synchronized (this) {
9118            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9119                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9120            if (task == null) {
9121                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9122                return;
9123            }
9124            if (task.mResizeMode != resizeableMode) {
9125                task.mResizeMode = resizeableMode;
9126                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9127                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9128                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9129            }
9130        }
9131    }
9132
9133    @Override
9134    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9135        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9136        long ident = Binder.clearCallingIdentity();
9137        try {
9138            synchronized (this) {
9139                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9140                if (task == null) {
9141                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9142                    return;
9143                }
9144                int stackId = task.stack.mStackId;
9145                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9146                // in crop windows resize mode or if the task size is affected by the docked stack
9147                // changing size. No need to update configuration.
9148                if (bounds != null && task.inCropWindowsResizeMode()
9149                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9150                    mWindowManager.scrollTask(task.taskId, bounds);
9151                    return;
9152                }
9153
9154                // Place the task in the right stack if it isn't there already based on
9155                // the requested bounds.
9156                // The stack transition logic is:
9157                // - a null bounds on a freeform task moves that task to fullscreen
9158                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9159                //   that task to freeform
9160                // - otherwise the task is not moved
9161                if (!StackId.isTaskResizeAllowed(stackId)) {
9162                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9163                }
9164                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9165                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9166                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9167                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9168                }
9169                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9170                if (stackId != task.stack.mStackId) {
9171                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9172                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9173                    preserveWindow = false;
9174                }
9175
9176                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9177                        false /* deferResume */);
9178            }
9179        } finally {
9180            Binder.restoreCallingIdentity(ident);
9181        }
9182    }
9183
9184    @Override
9185    public Rect getTaskBounds(int taskId) {
9186        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9187        long ident = Binder.clearCallingIdentity();
9188        Rect rect = new Rect();
9189        try {
9190            synchronized (this) {
9191                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9192                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9193                if (task == null) {
9194                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9195                    return rect;
9196                }
9197                if (task.stack != null) {
9198                    // Return the bounds from window manager since it will be adjusted for various
9199                    // things like the presense of a docked stack for tasks that aren't resizeable.
9200                    mWindowManager.getTaskBounds(task.taskId, rect);
9201                } else {
9202                    // Task isn't in window manager yet since it isn't associated with a stack.
9203                    // Return the persist value from activity manager
9204                    if (task.mBounds != null) {
9205                        rect.set(task.mBounds);
9206                    } else if (task.mLastNonFullscreenBounds != null) {
9207                        rect.set(task.mLastNonFullscreenBounds);
9208                    }
9209                }
9210            }
9211        } finally {
9212            Binder.restoreCallingIdentity(ident);
9213        }
9214        return rect;
9215    }
9216
9217    @Override
9218    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9219        if (userId != UserHandle.getCallingUserId()) {
9220            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9221                    "getTaskDescriptionIcon");
9222        }
9223        final File passedIconFile = new File(filePath);
9224        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9225                passedIconFile.getName());
9226        if (!legitIconFile.getPath().equals(filePath)
9227                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9228            throw new IllegalArgumentException("Bad file path: " + filePath
9229                    + " passed for userId " + userId);
9230        }
9231        return mRecentTasks.getTaskDescriptionIcon(filePath);
9232    }
9233
9234    @Override
9235    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9236            throws RemoteException {
9237        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9238                opts.getCustomInPlaceResId() == 0) {
9239            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9240                    "with valid animation");
9241        }
9242        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9243        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9244                opts.getCustomInPlaceResId());
9245        mWindowManager.executeAppTransition();
9246    }
9247
9248    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9249            boolean removeFromRecents) {
9250        if (removeFromRecents) {
9251            mRecentTasks.remove(tr);
9252            tr.removedFromRecents();
9253        }
9254        ComponentName component = tr.getBaseIntent().getComponent();
9255        if (component == null) {
9256            Slog.w(TAG, "No component for base intent of task: " + tr);
9257            return;
9258        }
9259
9260        // Find any running services associated with this app and stop if needed.
9261        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9262
9263        if (!killProcess) {
9264            return;
9265        }
9266
9267        // Determine if the process(es) for this task should be killed.
9268        final String pkg = component.getPackageName();
9269        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9270        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9271        for (int i = 0; i < pmap.size(); i++) {
9272
9273            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9274            for (int j = 0; j < uids.size(); j++) {
9275                ProcessRecord proc = uids.valueAt(j);
9276                if (proc.userId != tr.userId) {
9277                    // Don't kill process for a different user.
9278                    continue;
9279                }
9280                if (proc == mHomeProcess) {
9281                    // Don't kill the home process along with tasks from the same package.
9282                    continue;
9283                }
9284                if (!proc.pkgList.containsKey(pkg)) {
9285                    // Don't kill process that is not associated with this task.
9286                    continue;
9287                }
9288
9289                for (int k = 0; k < proc.activities.size(); k++) {
9290                    TaskRecord otherTask = proc.activities.get(k).task;
9291                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9292                        // Don't kill process(es) that has an activity in a different task that is
9293                        // also in recents.
9294                        return;
9295                    }
9296                }
9297
9298                if (proc.foregroundServices) {
9299                    // Don't kill process(es) with foreground service.
9300                    return;
9301                }
9302
9303                // Add process to kill list.
9304                procsToKill.add(proc);
9305            }
9306        }
9307
9308        // Kill the running processes.
9309        for (int i = 0; i < procsToKill.size(); i++) {
9310            ProcessRecord pr = procsToKill.get(i);
9311            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9312                    && pr.curReceiver == null) {
9313                pr.kill("remove task", true);
9314            } else {
9315                // We delay killing processes that are not in the background or running a receiver.
9316                pr.waitingToKill = "remove task";
9317            }
9318        }
9319    }
9320
9321    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9322        // Remove all tasks with activities in the specified package from the list of recent tasks
9323        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9324            TaskRecord tr = mRecentTasks.get(i);
9325            if (tr.userId != userId) continue;
9326
9327            ComponentName cn = tr.intent.getComponent();
9328            if (cn != null && cn.getPackageName().equals(packageName)) {
9329                // If the package name matches, remove the task.
9330                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9331            }
9332        }
9333    }
9334
9335    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9336            int userId) {
9337
9338        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9339            TaskRecord tr = mRecentTasks.get(i);
9340            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9341                continue;
9342            }
9343
9344            ComponentName cn = tr.intent.getComponent();
9345            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9346                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9347            if (sameComponent) {
9348                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9349            }
9350        }
9351    }
9352
9353    /**
9354     * Removes the task with the specified task id.
9355     *
9356     * @param taskId Identifier of the task to be removed.
9357     * @param killProcess Kill any process associated with the task if possible.
9358     * @param removeFromRecents Whether to also remove the task from recents.
9359     * @return Returns true if the given task was found and removed.
9360     */
9361    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9362            boolean removeFromRecents) {
9363        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9364                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9365        if (tr != null) {
9366            tr.removeTaskActivitiesLocked();
9367            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9368            if (tr.isPersistable) {
9369                notifyTaskPersisterLocked(null, true);
9370            }
9371            return true;
9372        }
9373        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9374        return false;
9375    }
9376
9377    @Override
9378    public void removeStack(int stackId) {
9379        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9380        if (stackId == HOME_STACK_ID) {
9381            throw new IllegalArgumentException("Removing home stack is not allowed.");
9382        }
9383
9384        synchronized (this) {
9385            final long ident = Binder.clearCallingIdentity();
9386            try {
9387                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9388                if (stack == null) {
9389                    return;
9390                }
9391                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9392                for (int i = tasks.size() - 1; i >= 0; i--) {
9393                    removeTaskByIdLocked(
9394                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9395                }
9396            } finally {
9397                Binder.restoreCallingIdentity(ident);
9398            }
9399        }
9400    }
9401
9402    @Override
9403    public boolean removeTask(int taskId) {
9404        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9405        synchronized (this) {
9406            final long ident = Binder.clearCallingIdentity();
9407            try {
9408                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9409            } finally {
9410                Binder.restoreCallingIdentity(ident);
9411            }
9412        }
9413    }
9414
9415    /**
9416     * TODO: Add mController hook
9417     */
9418    @Override
9419    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9420        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9421
9422        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9423        synchronized(this) {
9424            moveTaskToFrontLocked(taskId, flags, bOptions);
9425        }
9426    }
9427
9428    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9429        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9430
9431        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9432                Binder.getCallingUid(), -1, -1, "Task to front")) {
9433            ActivityOptions.abort(options);
9434            return;
9435        }
9436        final long origId = Binder.clearCallingIdentity();
9437        try {
9438            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9439            if (task == null) {
9440                Slog.d(TAG, "Could not find task for id: "+ taskId);
9441                return;
9442            }
9443            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9444                mStackSupervisor.showLockTaskToast();
9445                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9446                return;
9447            }
9448            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9449            if (prev != null && prev.isRecentsActivity()) {
9450                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9451            }
9452            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9453                    false /* forceNonResizable */);
9454        } finally {
9455            Binder.restoreCallingIdentity(origId);
9456        }
9457        ActivityOptions.abort(options);
9458    }
9459
9460    /**
9461     * Moves an activity, and all of the other activities within the same task, to the bottom
9462     * of the history stack.  The activity's order within the task is unchanged.
9463     *
9464     * @param token A reference to the activity we wish to move
9465     * @param nonRoot If false then this only works if the activity is the root
9466     *                of a task; if true it will work for any activity in a task.
9467     * @return Returns true if the move completed, false if not.
9468     */
9469    @Override
9470    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9471        enforceNotIsolatedCaller("moveActivityTaskToBack");
9472        synchronized(this) {
9473            final long origId = Binder.clearCallingIdentity();
9474            try {
9475                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9476                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9477                if (task != null) {
9478                    if (mStackSupervisor.isLockedTask(task)) {
9479                        mStackSupervisor.showLockTaskToast();
9480                        return false;
9481                    }
9482                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9483                }
9484            } finally {
9485                Binder.restoreCallingIdentity(origId);
9486            }
9487        }
9488        return false;
9489    }
9490
9491    @Override
9492    public void moveTaskBackwards(int task) {
9493        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9494                "moveTaskBackwards()");
9495
9496        synchronized(this) {
9497            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9498                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9499                return;
9500            }
9501            final long origId = Binder.clearCallingIdentity();
9502            moveTaskBackwardsLocked(task);
9503            Binder.restoreCallingIdentity(origId);
9504        }
9505    }
9506
9507    private final void moveTaskBackwardsLocked(int task) {
9508        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9509    }
9510
9511    @Override
9512    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9513            IActivityContainerCallback callback) throws RemoteException {
9514        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9515        synchronized (this) {
9516            if (parentActivityToken == null) {
9517                throw new IllegalArgumentException("parent token must not be null");
9518            }
9519            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9520            if (r == null) {
9521                return null;
9522            }
9523            if (callback == null) {
9524                throw new IllegalArgumentException("callback must not be null");
9525            }
9526            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9527        }
9528    }
9529
9530    @Override
9531    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9532        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9533        synchronized (this) {
9534            mStackSupervisor.deleteActivityContainer(container);
9535        }
9536    }
9537
9538    @Override
9539    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9540        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9541        synchronized (this) {
9542            final int stackId = mStackSupervisor.getNextStackId();
9543            final ActivityStack stack =
9544                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9545            if (stack == null) {
9546                return null;
9547            }
9548            return stack.mActivityContainer;
9549        }
9550    }
9551
9552    @Override
9553    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9554        synchronized (this) {
9555            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9556            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9557                return stack.mActivityContainer.getDisplayId();
9558            }
9559            return Display.DEFAULT_DISPLAY;
9560        }
9561    }
9562
9563    @Override
9564    public int getActivityStackId(IBinder token) throws RemoteException {
9565        synchronized (this) {
9566            ActivityStack stack = ActivityRecord.getStackLocked(token);
9567            if (stack == null) {
9568                return INVALID_STACK_ID;
9569            }
9570            return stack.mStackId;
9571        }
9572    }
9573
9574    @Override
9575    public void exitFreeformMode(IBinder token) throws RemoteException {
9576        synchronized (this) {
9577            long ident = Binder.clearCallingIdentity();
9578            try {
9579                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9580                if (r == null) {
9581                    throw new IllegalArgumentException(
9582                            "exitFreeformMode: No activity record matching token=" + token);
9583                }
9584                final ActivityStack stack = r.getStackLocked(token);
9585                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9586                    throw new IllegalStateException(
9587                            "exitFreeformMode: You can only go fullscreen from freeform.");
9588                }
9589                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9590                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9591                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9592            } finally {
9593                Binder.restoreCallingIdentity(ident);
9594            }
9595        }
9596    }
9597
9598    @Override
9599    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9600        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9601        if (stackId == HOME_STACK_ID) {
9602            throw new IllegalArgumentException(
9603                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9604        }
9605        synchronized (this) {
9606            long ident = Binder.clearCallingIdentity();
9607            try {
9608                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9609                        + " to stackId=" + stackId + " toTop=" + toTop);
9610                if (stackId == DOCKED_STACK_ID) {
9611                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9612                            null /* initialBounds */);
9613                }
9614                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9615                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9616                if (result && stackId == DOCKED_STACK_ID) {
9617                    // If task moved to docked stack - show recents if needed.
9618                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9619                            "moveTaskToDockedStack");
9620                }
9621            } finally {
9622                Binder.restoreCallingIdentity(ident);
9623            }
9624        }
9625    }
9626
9627    @Override
9628    public void swapDockedAndFullscreenStack() throws RemoteException {
9629        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9630        synchronized (this) {
9631            long ident = Binder.clearCallingIdentity();
9632            try {
9633                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9634                        FULLSCREEN_WORKSPACE_STACK_ID);
9635                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9636                        : null;
9637                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9638                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9639                        : null;
9640                if (topTask == null || tasks == null || tasks.size() == 0) {
9641                    Slog.w(TAG,
9642                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9643                    return;
9644                }
9645
9646                // TODO: App transition
9647                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9648
9649                // Defer the resume so resume/pausing while moving stacks is dangerous.
9650                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9651                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9652                        ANIMATE, true /* deferResume */);
9653                final int size = tasks.size();
9654                for (int i = 0; i < size; i++) {
9655                    final int id = tasks.get(i).taskId;
9656                    if (id == topTask.taskId) {
9657                        continue;
9658                    }
9659                    mStackSupervisor.moveTaskToStackLocked(id,
9660                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9661                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9662                }
9663
9664                // Because we deferred the resume, to avoid conflicts with stack switches while
9665                // resuming, we need to do it after all the tasks are moved.
9666                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9667                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9668
9669                mWindowManager.executeAppTransition();
9670            } finally {
9671                Binder.restoreCallingIdentity(ident);
9672            }
9673        }
9674    }
9675
9676    /**
9677     * Moves the input task to the docked stack.
9678     *
9679     * @param taskId Id of task to move.
9680     * @param createMode The mode the docked stack should be created in if it doesn't exist
9681     *                   already. See
9682     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9683     *                   and
9684     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9685     * @param toTop If the task and stack should be moved to the top.
9686     * @param animate Whether we should play an animation for the moving the task
9687     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9688     *                      docked stack. Pass {@code null} to use default bounds.
9689     */
9690    @Override
9691    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9692            Rect initialBounds) {
9693        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9694        synchronized (this) {
9695            long ident = Binder.clearCallingIdentity();
9696            try {
9697                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9698                        + " to createMode=" + createMode + " toTop=" + toTop);
9699                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9700                return mStackSupervisor.moveTaskToStackLocked(
9701                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9702                        "moveTaskToDockedStack", animate);
9703            } finally {
9704                Binder.restoreCallingIdentity(ident);
9705            }
9706        }
9707    }
9708
9709    /**
9710     * Moves the top activity in the input stackId to the pinned stack.
9711     *
9712     * @param stackId Id of stack to move the top activity to pinned stack.
9713     * @param bounds Bounds to use for pinned stack.
9714     *
9715     * @return True if the top activity of the input stack was successfully moved to the pinned
9716     *          stack.
9717     */
9718    @Override
9719    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9720        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9721        synchronized (this) {
9722            if (!mSupportsPictureInPicture) {
9723                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9724                        + "Device doesn't support picture-in-pciture mode");
9725            }
9726
9727            long ident = Binder.clearCallingIdentity();
9728            try {
9729                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9730            } finally {
9731                Binder.restoreCallingIdentity(ident);
9732            }
9733        }
9734    }
9735
9736    @Override
9737    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9738            boolean preserveWindows, boolean animate, int animationDuration) {
9739        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9740        long ident = Binder.clearCallingIdentity();
9741        try {
9742            synchronized (this) {
9743                if (animate) {
9744                    if (stackId == PINNED_STACK_ID) {
9745                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9746                    } else {
9747                        throw new IllegalArgumentException("Stack: " + stackId
9748                                + " doesn't support animated resize.");
9749                    }
9750                } else {
9751                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9752                            null /* tempTaskInsetBounds */, preserveWindows,
9753                            allowResizeInDockedMode, !DEFER_RESUME);
9754                }
9755            }
9756        } finally {
9757            Binder.restoreCallingIdentity(ident);
9758        }
9759    }
9760
9761    @Override
9762    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9763            Rect tempDockedTaskInsetBounds,
9764            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9765        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9766                "resizeDockedStack()");
9767        long ident = Binder.clearCallingIdentity();
9768        try {
9769            synchronized (this) {
9770                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9771                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9772                        PRESERVE_WINDOWS);
9773            }
9774        } finally {
9775            Binder.restoreCallingIdentity(ident);
9776        }
9777    }
9778
9779    @Override
9780    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9781        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9782                "resizePinnedStack()");
9783        final long ident = Binder.clearCallingIdentity();
9784        try {
9785            synchronized (this) {
9786                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9787            }
9788        } finally {
9789            Binder.restoreCallingIdentity(ident);
9790        }
9791    }
9792
9793    @Override
9794    public void positionTaskInStack(int taskId, int stackId, int position) {
9795        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9796        if (stackId == HOME_STACK_ID) {
9797            throw new IllegalArgumentException(
9798                    "positionTaskInStack: Attempt to change the position of task "
9799                    + taskId + " in/to home stack");
9800        }
9801        synchronized (this) {
9802            long ident = Binder.clearCallingIdentity();
9803            try {
9804                if (DEBUG_STACK) Slog.d(TAG_STACK,
9805                        "positionTaskInStack: positioning task=" + taskId
9806                        + " in stackId=" + stackId + " at position=" + position);
9807                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9808            } finally {
9809                Binder.restoreCallingIdentity(ident);
9810            }
9811        }
9812    }
9813
9814    @Override
9815    public List<StackInfo> getAllStackInfos() {
9816        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9817        long ident = Binder.clearCallingIdentity();
9818        try {
9819            synchronized (this) {
9820                return mStackSupervisor.getAllStackInfosLocked();
9821            }
9822        } finally {
9823            Binder.restoreCallingIdentity(ident);
9824        }
9825    }
9826
9827    @Override
9828    public StackInfo getStackInfo(int stackId) {
9829        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9830        long ident = Binder.clearCallingIdentity();
9831        try {
9832            synchronized (this) {
9833                return mStackSupervisor.getStackInfoLocked(stackId);
9834            }
9835        } finally {
9836            Binder.restoreCallingIdentity(ident);
9837        }
9838    }
9839
9840    @Override
9841    public boolean isInHomeStack(int taskId) {
9842        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9843        long ident = Binder.clearCallingIdentity();
9844        try {
9845            synchronized (this) {
9846                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9847                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9848                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9849            }
9850        } finally {
9851            Binder.restoreCallingIdentity(ident);
9852        }
9853    }
9854
9855    @Override
9856    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9857        synchronized(this) {
9858            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9859        }
9860    }
9861
9862    @Override
9863    public void updateDeviceOwner(String packageName) {
9864        final int callingUid = Binder.getCallingUid();
9865        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9866            throw new SecurityException("updateDeviceOwner called from non-system process");
9867        }
9868        synchronized (this) {
9869            mDeviceOwnerName = packageName;
9870        }
9871    }
9872
9873    @Override
9874    public void updateLockTaskPackages(int userId, String[] packages) {
9875        final int callingUid = Binder.getCallingUid();
9876        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9877            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9878                    "updateLockTaskPackages()");
9879        }
9880        synchronized (this) {
9881            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9882                    Arrays.toString(packages));
9883            mLockTaskPackages.put(userId, packages);
9884            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9885        }
9886    }
9887
9888
9889    void startLockTaskModeLocked(TaskRecord task) {
9890        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9891        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9892            return;
9893        }
9894
9895        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9896        // is initiated by system after the pinning request was shown and locked mode is initiated
9897        // by an authorized app directly
9898        final int callingUid = Binder.getCallingUid();
9899        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9900        long ident = Binder.clearCallingIdentity();
9901        try {
9902            if (!isSystemInitiated) {
9903                task.mLockTaskUid = callingUid;
9904                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9905                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9906                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9907                    StatusBarManagerInternal statusBarManager =
9908                            LocalServices.getService(StatusBarManagerInternal.class);
9909                    if (statusBarManager != null) {
9910                        statusBarManager.showScreenPinningRequest(task.taskId);
9911                    }
9912                    return;
9913                }
9914
9915                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9916                if (stack == null || task != stack.topTask()) {
9917                    throw new IllegalArgumentException("Invalid task, not in foreground");
9918                }
9919            }
9920            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9921                    "Locking fully");
9922            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9923                    ActivityManager.LOCK_TASK_MODE_PINNED :
9924                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9925                    "startLockTask", true);
9926        } finally {
9927            Binder.restoreCallingIdentity(ident);
9928        }
9929    }
9930
9931    @Override
9932    public void startLockTaskMode(int taskId) {
9933        synchronized (this) {
9934            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9935            if (task != null) {
9936                startLockTaskModeLocked(task);
9937            }
9938        }
9939    }
9940
9941    @Override
9942    public void startLockTaskMode(IBinder token) {
9943        synchronized (this) {
9944            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9945            if (r == null) {
9946                return;
9947            }
9948            final TaskRecord task = r.task;
9949            if (task != null) {
9950                startLockTaskModeLocked(task);
9951            }
9952        }
9953    }
9954
9955    @Override
9956    public void startSystemLockTaskMode(int taskId) throws RemoteException {
9957        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
9958        // This makes inner call to look as if it was initiated by system.
9959        long ident = Binder.clearCallingIdentity();
9960        try {
9961            synchronized (this) {
9962                startLockTaskMode(taskId);
9963            }
9964        } finally {
9965            Binder.restoreCallingIdentity(ident);
9966        }
9967    }
9968
9969    @Override
9970    public void stopLockTaskMode() {
9971        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9972        if (lockTask == null) {
9973            // Our work here is done.
9974            return;
9975        }
9976
9977        final int callingUid = Binder.getCallingUid();
9978        final int lockTaskUid = lockTask.mLockTaskUid;
9979        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
9980        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
9981            // Done.
9982            return;
9983        } else {
9984            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9985            // It is possible lockTaskMode was started by the system process because
9986            // android:lockTaskMode is set to a locking value in the application manifest
9987            // instead of the app calling startLockTaskMode. In this case
9988            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
9989            // {@link TaskRecord.effectiveUid} instead. Also caller with
9990            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
9991            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
9992                    && callingUid != lockTaskUid
9993                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
9994                throw new SecurityException("Invalid uid, expected " + lockTaskUid
9995                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9996            }
9997        }
9998        long ident = Binder.clearCallingIdentity();
9999        try {
10000            Log.d(TAG, "stopLockTaskMode");
10001            // Stop lock task
10002            synchronized (this) {
10003                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10004                        "stopLockTask", true);
10005            }
10006        } finally {
10007            Binder.restoreCallingIdentity(ident);
10008        }
10009    }
10010
10011    /**
10012     * This API should be called by SystemUI only when user perform certain action to dismiss
10013     * lock task mode. We should only dismiss pinned lock task mode in this case.
10014     */
10015    @Override
10016    public void stopSystemLockTaskMode() throws RemoteException {
10017        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10018            stopLockTaskMode();
10019        } else {
10020            mStackSupervisor.showLockTaskToast();
10021        }
10022    }
10023
10024    @Override
10025    public boolean isInLockTaskMode() {
10026        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10027    }
10028
10029    @Override
10030    public int getLockTaskModeState() {
10031        synchronized (this) {
10032            return mStackSupervisor.getLockTaskModeState();
10033        }
10034    }
10035
10036    @Override
10037    public void showLockTaskEscapeMessage(IBinder token) {
10038        synchronized (this) {
10039            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10040            if (r == null) {
10041                return;
10042            }
10043            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10044        }
10045    }
10046
10047    // =========================================================
10048    // CONTENT PROVIDERS
10049    // =========================================================
10050
10051    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10052        List<ProviderInfo> providers = null;
10053        try {
10054            providers = AppGlobals.getPackageManager()
10055                    .queryContentProviders(app.processName, app.uid,
10056                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10057                                    | MATCH_DEBUG_TRIAGED_MISSING)
10058                    .getList();
10059        } catch (RemoteException ex) {
10060        }
10061        if (DEBUG_MU) Slog.v(TAG_MU,
10062                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10063        int userId = app.userId;
10064        if (providers != null) {
10065            int N = providers.size();
10066            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10067            for (int i=0; i<N; i++) {
10068                ProviderInfo cpi =
10069                    (ProviderInfo)providers.get(i);
10070                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10071                        cpi.name, cpi.flags);
10072                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10073                    // This is a singleton provider, but a user besides the
10074                    // default user is asking to initialize a process it runs
10075                    // in...  well, no, it doesn't actually run in this process,
10076                    // it runs in the process of the default user.  Get rid of it.
10077                    providers.remove(i);
10078                    N--;
10079                    i--;
10080                    continue;
10081                }
10082
10083                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10084                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10085                if (cpr == null) {
10086                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10087                    mProviderMap.putProviderByClass(comp, cpr);
10088                }
10089                if (DEBUG_MU) Slog.v(TAG_MU,
10090                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10091                app.pubProviders.put(cpi.name, cpr);
10092                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10093                    // Don't add this if it is a platform component that is marked
10094                    // to run in multiple processes, because this is actually
10095                    // part of the framework so doesn't make sense to track as a
10096                    // separate apk in the process.
10097                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10098                            mProcessStats);
10099                }
10100                notifyPackageUse(cpi.applicationInfo.packageName,
10101                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10102            }
10103        }
10104        return providers;
10105    }
10106
10107    /**
10108     * Check if {@link ProcessRecord} has a possible chance at accessing the
10109     * given {@link ProviderInfo}. Final permission checking is always done
10110     * in {@link ContentProvider}.
10111     */
10112    private final String checkContentProviderPermissionLocked(
10113            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10114        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10115        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10116        boolean checkedGrants = false;
10117        if (checkUser) {
10118            // Looking for cross-user grants before enforcing the typical cross-users permissions
10119            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10120            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10121                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10122                    return null;
10123                }
10124                checkedGrants = true;
10125            }
10126            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10127                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10128            if (userId != tmpTargetUserId) {
10129                // When we actually went to determine the final targer user ID, this ended
10130                // up different than our initial check for the authority.  This is because
10131                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10132                // SELF.  So we need to re-check the grants again.
10133                checkedGrants = false;
10134            }
10135        }
10136        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10137                cpi.applicationInfo.uid, cpi.exported)
10138                == PackageManager.PERMISSION_GRANTED) {
10139            return null;
10140        }
10141        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10142                cpi.applicationInfo.uid, cpi.exported)
10143                == PackageManager.PERMISSION_GRANTED) {
10144            return null;
10145        }
10146
10147        PathPermission[] pps = cpi.pathPermissions;
10148        if (pps != null) {
10149            int i = pps.length;
10150            while (i > 0) {
10151                i--;
10152                PathPermission pp = pps[i];
10153                String pprperm = pp.getReadPermission();
10154                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10155                        cpi.applicationInfo.uid, cpi.exported)
10156                        == PackageManager.PERMISSION_GRANTED) {
10157                    return null;
10158                }
10159                String ppwperm = pp.getWritePermission();
10160                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10161                        cpi.applicationInfo.uid, cpi.exported)
10162                        == PackageManager.PERMISSION_GRANTED) {
10163                    return null;
10164                }
10165            }
10166        }
10167        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10168            return null;
10169        }
10170
10171        String msg;
10172        if (!cpi.exported) {
10173            msg = "Permission Denial: opening provider " + cpi.name
10174                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10175                    + ", uid=" + callingUid + ") that is not exported from uid "
10176                    + cpi.applicationInfo.uid;
10177        } else {
10178            msg = "Permission Denial: opening provider " + cpi.name
10179                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10180                    + ", uid=" + callingUid + ") requires "
10181                    + cpi.readPermission + " or " + cpi.writePermission;
10182        }
10183        Slog.w(TAG, msg);
10184        return msg;
10185    }
10186
10187    /**
10188     * Returns if the ContentProvider has granted a uri to callingUid
10189     */
10190    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10191        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10192        if (perms != null) {
10193            for (int i=perms.size()-1; i>=0; i--) {
10194                GrantUri grantUri = perms.keyAt(i);
10195                if (grantUri.sourceUserId == userId || !checkUser) {
10196                    if (matchesProvider(grantUri.uri, cpi)) {
10197                        return true;
10198                    }
10199                }
10200            }
10201        }
10202        return false;
10203    }
10204
10205    /**
10206     * Returns true if the uri authority is one of the authorities specified in the provider.
10207     */
10208    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10209        String uriAuth = uri.getAuthority();
10210        String cpiAuth = cpi.authority;
10211        if (cpiAuth.indexOf(';') == -1) {
10212            return cpiAuth.equals(uriAuth);
10213        }
10214        String[] cpiAuths = cpiAuth.split(";");
10215        int length = cpiAuths.length;
10216        for (int i = 0; i < length; i++) {
10217            if (cpiAuths[i].equals(uriAuth)) return true;
10218        }
10219        return false;
10220    }
10221
10222    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10223            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10224        if (r != null) {
10225            for (int i=0; i<r.conProviders.size(); i++) {
10226                ContentProviderConnection conn = r.conProviders.get(i);
10227                if (conn.provider == cpr) {
10228                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10229                            "Adding provider requested by "
10230                            + r.processName + " from process "
10231                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10232                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10233                    if (stable) {
10234                        conn.stableCount++;
10235                        conn.numStableIncs++;
10236                    } else {
10237                        conn.unstableCount++;
10238                        conn.numUnstableIncs++;
10239                    }
10240                    return conn;
10241                }
10242            }
10243            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10244            if (stable) {
10245                conn.stableCount = 1;
10246                conn.numStableIncs = 1;
10247            } else {
10248                conn.unstableCount = 1;
10249                conn.numUnstableIncs = 1;
10250            }
10251            cpr.connections.add(conn);
10252            r.conProviders.add(conn);
10253            startAssociationLocked(r.uid, r.processName, r.curProcState,
10254                    cpr.uid, cpr.name, cpr.info.processName);
10255            return conn;
10256        }
10257        cpr.addExternalProcessHandleLocked(externalProcessToken);
10258        return null;
10259    }
10260
10261    boolean decProviderCountLocked(ContentProviderConnection conn,
10262            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10263        if (conn != null) {
10264            cpr = conn.provider;
10265            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10266                    "Removing provider requested by "
10267                    + conn.client.processName + " from process "
10268                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10269                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10270            if (stable) {
10271                conn.stableCount--;
10272            } else {
10273                conn.unstableCount--;
10274            }
10275            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10276                cpr.connections.remove(conn);
10277                conn.client.conProviders.remove(conn);
10278                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10279                    // The client is more important than last activity -- note the time this
10280                    // is happening, so we keep the old provider process around a bit as last
10281                    // activity to avoid thrashing it.
10282                    if (cpr.proc != null) {
10283                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10284                    }
10285                }
10286                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10287                return true;
10288            }
10289            return false;
10290        }
10291        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10292        return false;
10293    }
10294
10295    private void checkTime(long startTime, String where) {
10296        long now = SystemClock.elapsedRealtime();
10297        if ((now-startTime) > 1000) {
10298            // If we are taking more than a second, log about it.
10299            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10300        }
10301    }
10302
10303    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10304            String name, IBinder token, boolean stable, int userId) {
10305        ContentProviderRecord cpr;
10306        ContentProviderConnection conn = null;
10307        ProviderInfo cpi = null;
10308
10309        synchronized(this) {
10310            long startTime = SystemClock.elapsedRealtime();
10311
10312            ProcessRecord r = null;
10313            if (caller != null) {
10314                r = getRecordForAppLocked(caller);
10315                if (r == null) {
10316                    throw new SecurityException(
10317                            "Unable to find app for caller " + caller
10318                          + " (pid=" + Binder.getCallingPid()
10319                          + ") when getting content provider " + name);
10320                }
10321            }
10322
10323            boolean checkCrossUser = true;
10324
10325            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10326
10327            // First check if this content provider has been published...
10328            cpr = mProviderMap.getProviderByName(name, userId);
10329            // If that didn't work, check if it exists for user 0 and then
10330            // verify that it's a singleton provider before using it.
10331            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10332                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10333                if (cpr != null) {
10334                    cpi = cpr.info;
10335                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10336                            cpi.name, cpi.flags)
10337                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10338                        userId = UserHandle.USER_SYSTEM;
10339                        checkCrossUser = false;
10340                    } else {
10341                        cpr = null;
10342                        cpi = null;
10343                    }
10344                }
10345            }
10346
10347            boolean providerRunning = cpr != null;
10348            if (providerRunning) {
10349                cpi = cpr.info;
10350                String msg;
10351                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10352                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10353                        != null) {
10354                    throw new SecurityException(msg);
10355                }
10356                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10357
10358                if (r != null && cpr.canRunHere(r)) {
10359                    // This provider has been published or is in the process
10360                    // of being published...  but it is also allowed to run
10361                    // in the caller's process, so don't make a connection
10362                    // and just let the caller instantiate its own instance.
10363                    ContentProviderHolder holder = cpr.newHolder(null);
10364                    // don't give caller the provider object, it needs
10365                    // to make its own.
10366                    holder.provider = null;
10367                    return holder;
10368                }
10369
10370                final long origId = Binder.clearCallingIdentity();
10371
10372                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10373
10374                // In this case the provider instance already exists, so we can
10375                // return it right away.
10376                conn = incProviderCountLocked(r, cpr, token, stable);
10377                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10378                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10379                        // If this is a perceptible app accessing the provider,
10380                        // make sure to count it as being accessed and thus
10381                        // back up on the LRU list.  This is good because
10382                        // content providers are often expensive to start.
10383                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10384                        updateLruProcessLocked(cpr.proc, false, null);
10385                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10386                    }
10387                }
10388
10389                if (cpr.proc != null) {
10390                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10391                    boolean success = updateOomAdjLocked(cpr.proc);
10392                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10393                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10394                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10395                    // NOTE: there is still a race here where a signal could be
10396                    // pending on the process even though we managed to update its
10397                    // adj level.  Not sure what to do about this, but at least
10398                    // the race is now smaller.
10399                    if (!success) {
10400                        // Uh oh...  it looks like the provider's process
10401                        // has been killed on us.  We need to wait for a new
10402                        // process to be started, and make sure its death
10403                        // doesn't kill our process.
10404                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10405                                + " is crashing; detaching " + r);
10406                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10407                        checkTime(startTime, "getContentProviderImpl: before appDied");
10408                        appDiedLocked(cpr.proc);
10409                        checkTime(startTime, "getContentProviderImpl: after appDied");
10410                        if (!lastRef) {
10411                            // This wasn't the last ref our process had on
10412                            // the provider...  we have now been killed, bail.
10413                            return null;
10414                        }
10415                        providerRunning = false;
10416                        conn = null;
10417                    }
10418                }
10419
10420                Binder.restoreCallingIdentity(origId);
10421            }
10422
10423            if (!providerRunning) {
10424                try {
10425                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10426                    cpi = AppGlobals.getPackageManager().
10427                        resolveContentProvider(name,
10428                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10429                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10430                } catch (RemoteException ex) {
10431                }
10432                if (cpi == null) {
10433                    return null;
10434                }
10435                // If the provider is a singleton AND
10436                // (it's a call within the same user || the provider is a
10437                // privileged app)
10438                // Then allow connecting to the singleton provider
10439                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10440                        cpi.name, cpi.flags)
10441                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10442                if (singleton) {
10443                    userId = UserHandle.USER_SYSTEM;
10444                }
10445                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10446                checkTime(startTime, "getContentProviderImpl: got app info for user");
10447
10448                String msg;
10449                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10450                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10451                        != null) {
10452                    throw new SecurityException(msg);
10453                }
10454                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10455
10456                if (!mProcessesReady
10457                        && !cpi.processName.equals("system")) {
10458                    // If this content provider does not run in the system
10459                    // process, and the system is not yet ready to run other
10460                    // processes, then fail fast instead of hanging.
10461                    throw new IllegalArgumentException(
10462                            "Attempt to launch content provider before system ready");
10463                }
10464
10465                // Make sure that the user who owns this provider is running.  If not,
10466                // we don't want to allow it to run.
10467                if (!mUserController.isUserRunningLocked(userId, 0)) {
10468                    Slog.w(TAG, "Unable to launch app "
10469                            + cpi.applicationInfo.packageName + "/"
10470                            + cpi.applicationInfo.uid + " for provider "
10471                            + name + ": user " + userId + " is stopped");
10472                    return null;
10473                }
10474
10475                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10476                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10477                cpr = mProviderMap.getProviderByClass(comp, userId);
10478                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10479                final boolean firstClass = cpr == null;
10480                if (firstClass) {
10481                    final long ident = Binder.clearCallingIdentity();
10482
10483                    // If permissions need a review before any of the app components can run,
10484                    // we return no provider and launch a review activity if the calling app
10485                    // is in the foreground.
10486                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10487                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10488                            return null;
10489                        }
10490                    }
10491
10492                    try {
10493                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10494                        ApplicationInfo ai =
10495                            AppGlobals.getPackageManager().
10496                                getApplicationInfo(
10497                                        cpi.applicationInfo.packageName,
10498                                        STOCK_PM_FLAGS, userId);
10499                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10500                        if (ai == null) {
10501                            Slog.w(TAG, "No package info for content provider "
10502                                    + cpi.name);
10503                            return null;
10504                        }
10505                        ai = getAppInfoForUser(ai, userId);
10506                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10507                    } catch (RemoteException ex) {
10508                        // pm is in same process, this will never happen.
10509                    } finally {
10510                        Binder.restoreCallingIdentity(ident);
10511                    }
10512                }
10513
10514                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10515
10516                if (r != null && cpr.canRunHere(r)) {
10517                    // If this is a multiprocess provider, then just return its
10518                    // info and allow the caller to instantiate it.  Only do
10519                    // this if the provider is the same user as the caller's
10520                    // process, or can run as root (so can be in any process).
10521                    return cpr.newHolder(null);
10522                }
10523
10524                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10525                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10526                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10527
10528                // This is single process, and our app is now connecting to it.
10529                // See if we are already in the process of launching this
10530                // provider.
10531                final int N = mLaunchingProviders.size();
10532                int i;
10533                for (i = 0; i < N; i++) {
10534                    if (mLaunchingProviders.get(i) == cpr) {
10535                        break;
10536                    }
10537                }
10538
10539                // If the provider is not already being launched, then get it
10540                // started.
10541                if (i >= N) {
10542                    final long origId = Binder.clearCallingIdentity();
10543
10544                    try {
10545                        // Content provider is now in use, its package can't be stopped.
10546                        try {
10547                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10548                            AppGlobals.getPackageManager().setPackageStoppedState(
10549                                    cpr.appInfo.packageName, false, userId);
10550                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10551                        } catch (RemoteException e) {
10552                        } catch (IllegalArgumentException e) {
10553                            Slog.w(TAG, "Failed trying to unstop package "
10554                                    + cpr.appInfo.packageName + ": " + e);
10555                        }
10556
10557                        // Use existing process if already started
10558                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10559                        ProcessRecord proc = getProcessRecordLocked(
10560                                cpi.processName, cpr.appInfo.uid, false);
10561                        if (proc != null && proc.thread != null) {
10562                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10563                                    "Installing in existing process " + proc);
10564                            if (!proc.pubProviders.containsKey(cpi.name)) {
10565                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10566                                proc.pubProviders.put(cpi.name, cpr);
10567                                try {
10568                                    proc.thread.scheduleInstallProvider(cpi);
10569                                } catch (RemoteException e) {
10570                                }
10571                            }
10572                        } else {
10573                            checkTime(startTime, "getContentProviderImpl: before start process");
10574                            proc = startProcessLocked(cpi.processName,
10575                                    cpr.appInfo, false, 0, "content provider",
10576                                    new ComponentName(cpi.applicationInfo.packageName,
10577                                            cpi.name), false, false, false);
10578                            checkTime(startTime, "getContentProviderImpl: after start process");
10579                            if (proc == null) {
10580                                Slog.w(TAG, "Unable to launch app "
10581                                        + cpi.applicationInfo.packageName + "/"
10582                                        + cpi.applicationInfo.uid + " for provider "
10583                                        + name + ": process is bad");
10584                                return null;
10585                            }
10586                        }
10587                        cpr.launchingApp = proc;
10588                        mLaunchingProviders.add(cpr);
10589                    } finally {
10590                        Binder.restoreCallingIdentity(origId);
10591                    }
10592                }
10593
10594                checkTime(startTime, "getContentProviderImpl: updating data structures");
10595
10596                // Make sure the provider is published (the same provider class
10597                // may be published under multiple names).
10598                if (firstClass) {
10599                    mProviderMap.putProviderByClass(comp, cpr);
10600                }
10601
10602                mProviderMap.putProviderByName(name, cpr);
10603                conn = incProviderCountLocked(r, cpr, token, stable);
10604                if (conn != null) {
10605                    conn.waiting = true;
10606                }
10607            }
10608            checkTime(startTime, "getContentProviderImpl: done!");
10609        }
10610
10611        // Wait for the provider to be published...
10612        synchronized (cpr) {
10613            while (cpr.provider == null) {
10614                if (cpr.launchingApp == null) {
10615                    Slog.w(TAG, "Unable to launch app "
10616                            + cpi.applicationInfo.packageName + "/"
10617                            + cpi.applicationInfo.uid + " for provider "
10618                            + name + ": launching app became null");
10619                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10620                            UserHandle.getUserId(cpi.applicationInfo.uid),
10621                            cpi.applicationInfo.packageName,
10622                            cpi.applicationInfo.uid, name);
10623                    return null;
10624                }
10625                try {
10626                    if (DEBUG_MU) Slog.v(TAG_MU,
10627                            "Waiting to start provider " + cpr
10628                            + " launchingApp=" + cpr.launchingApp);
10629                    if (conn != null) {
10630                        conn.waiting = true;
10631                    }
10632                    cpr.wait();
10633                } catch (InterruptedException ex) {
10634                } finally {
10635                    if (conn != null) {
10636                        conn.waiting = false;
10637                    }
10638                }
10639            }
10640        }
10641        return cpr != null ? cpr.newHolder(conn) : null;
10642    }
10643
10644    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10645            ProcessRecord r, final int userId) {
10646        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10647                cpi.packageName, userId)) {
10648
10649            final boolean callerForeground = r == null || r.setSchedGroup
10650                    != ProcessList.SCHED_GROUP_BACKGROUND;
10651
10652            // Show a permission review UI only for starting from a foreground app
10653            if (!callerForeground) {
10654                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10655                        + cpi.packageName + " requires a permissions review");
10656                return false;
10657            }
10658
10659            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10660            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10661                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10662            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10663
10664            if (DEBUG_PERMISSIONS_REVIEW) {
10665                Slog.i(TAG, "u" + userId + " Launching permission review "
10666                        + "for package " + cpi.packageName);
10667            }
10668
10669            final UserHandle userHandle = new UserHandle(userId);
10670            mHandler.post(new Runnable() {
10671                @Override
10672                public void run() {
10673                    mContext.startActivityAsUser(intent, userHandle);
10674                }
10675            });
10676
10677            return false;
10678        }
10679
10680        return true;
10681    }
10682
10683    PackageManagerInternal getPackageManagerInternalLocked() {
10684        if (mPackageManagerInt == null) {
10685            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10686        }
10687        return mPackageManagerInt;
10688    }
10689
10690    @Override
10691    public final ContentProviderHolder getContentProvider(
10692            IApplicationThread caller, String name, int userId, boolean stable) {
10693        enforceNotIsolatedCaller("getContentProvider");
10694        if (caller == null) {
10695            String msg = "null IApplicationThread when getting content provider "
10696                    + name;
10697            Slog.w(TAG, msg);
10698            throw new SecurityException(msg);
10699        }
10700        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10701        // with cross-user grant.
10702        return getContentProviderImpl(caller, name, null, stable, userId);
10703    }
10704
10705    public ContentProviderHolder getContentProviderExternal(
10706            String name, int userId, IBinder token) {
10707        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10708            "Do not have permission in call getContentProviderExternal()");
10709        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10710                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10711        return getContentProviderExternalUnchecked(name, token, userId);
10712    }
10713
10714    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10715            IBinder token, int userId) {
10716        return getContentProviderImpl(null, name, token, true, userId);
10717    }
10718
10719    /**
10720     * Drop a content provider from a ProcessRecord's bookkeeping
10721     */
10722    public void removeContentProvider(IBinder connection, boolean stable) {
10723        enforceNotIsolatedCaller("removeContentProvider");
10724        long ident = Binder.clearCallingIdentity();
10725        try {
10726            synchronized (this) {
10727                ContentProviderConnection conn;
10728                try {
10729                    conn = (ContentProviderConnection)connection;
10730                } catch (ClassCastException e) {
10731                    String msg ="removeContentProvider: " + connection
10732                            + " not a ContentProviderConnection";
10733                    Slog.w(TAG, msg);
10734                    throw new IllegalArgumentException(msg);
10735                }
10736                if (conn == null) {
10737                    throw new NullPointerException("connection is null");
10738                }
10739                if (decProviderCountLocked(conn, null, null, stable)) {
10740                    updateOomAdjLocked();
10741                }
10742            }
10743        } finally {
10744            Binder.restoreCallingIdentity(ident);
10745        }
10746    }
10747
10748    public void removeContentProviderExternal(String name, IBinder token) {
10749        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10750            "Do not have permission in call removeContentProviderExternal()");
10751        int userId = UserHandle.getCallingUserId();
10752        long ident = Binder.clearCallingIdentity();
10753        try {
10754            removeContentProviderExternalUnchecked(name, token, userId);
10755        } finally {
10756            Binder.restoreCallingIdentity(ident);
10757        }
10758    }
10759
10760    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10761        synchronized (this) {
10762            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10763            if(cpr == null) {
10764                //remove from mProvidersByClass
10765                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10766                return;
10767            }
10768
10769            //update content provider record entry info
10770            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10771            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10772            if (localCpr.hasExternalProcessHandles()) {
10773                if (localCpr.removeExternalProcessHandleLocked(token)) {
10774                    updateOomAdjLocked();
10775                } else {
10776                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10777                            + " with no external reference for token: "
10778                            + token + ".");
10779                }
10780            } else {
10781                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10782                        + " with no external references.");
10783            }
10784        }
10785    }
10786
10787    public final void publishContentProviders(IApplicationThread caller,
10788            List<ContentProviderHolder> providers) {
10789        if (providers == null) {
10790            return;
10791        }
10792
10793        enforceNotIsolatedCaller("publishContentProviders");
10794        synchronized (this) {
10795            final ProcessRecord r = getRecordForAppLocked(caller);
10796            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10797            if (r == null) {
10798                throw new SecurityException(
10799                        "Unable to find app for caller " + caller
10800                      + " (pid=" + Binder.getCallingPid()
10801                      + ") when publishing content providers");
10802            }
10803
10804            final long origId = Binder.clearCallingIdentity();
10805
10806            final int N = providers.size();
10807            for (int i = 0; i < N; i++) {
10808                ContentProviderHolder src = providers.get(i);
10809                if (src == null || src.info == null || src.provider == null) {
10810                    continue;
10811                }
10812                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10813                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10814                if (dst != null) {
10815                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10816                    mProviderMap.putProviderByClass(comp, dst);
10817                    String names[] = dst.info.authority.split(";");
10818                    for (int j = 0; j < names.length; j++) {
10819                        mProviderMap.putProviderByName(names[j], dst);
10820                    }
10821
10822                    int launchingCount = mLaunchingProviders.size();
10823                    int j;
10824                    boolean wasInLaunchingProviders = false;
10825                    for (j = 0; j < launchingCount; j++) {
10826                        if (mLaunchingProviders.get(j) == dst) {
10827                            mLaunchingProviders.remove(j);
10828                            wasInLaunchingProviders = true;
10829                            j--;
10830                            launchingCount--;
10831                        }
10832                    }
10833                    if (wasInLaunchingProviders) {
10834                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10835                    }
10836                    synchronized (dst) {
10837                        dst.provider = src.provider;
10838                        dst.proc = r;
10839                        dst.notifyAll();
10840                    }
10841                    updateOomAdjLocked(r);
10842                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10843                            src.info.authority);
10844                }
10845            }
10846
10847            Binder.restoreCallingIdentity(origId);
10848        }
10849    }
10850
10851    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10852        ContentProviderConnection conn;
10853        try {
10854            conn = (ContentProviderConnection)connection;
10855        } catch (ClassCastException e) {
10856            String msg ="refContentProvider: " + connection
10857                    + " not a ContentProviderConnection";
10858            Slog.w(TAG, msg);
10859            throw new IllegalArgumentException(msg);
10860        }
10861        if (conn == null) {
10862            throw new NullPointerException("connection is null");
10863        }
10864
10865        synchronized (this) {
10866            if (stable > 0) {
10867                conn.numStableIncs += stable;
10868            }
10869            stable = conn.stableCount + stable;
10870            if (stable < 0) {
10871                throw new IllegalStateException("stableCount < 0: " + stable);
10872            }
10873
10874            if (unstable > 0) {
10875                conn.numUnstableIncs += unstable;
10876            }
10877            unstable = conn.unstableCount + unstable;
10878            if (unstable < 0) {
10879                throw new IllegalStateException("unstableCount < 0: " + unstable);
10880            }
10881
10882            if ((stable+unstable) <= 0) {
10883                throw new IllegalStateException("ref counts can't go to zero here: stable="
10884                        + stable + " unstable=" + unstable);
10885            }
10886            conn.stableCount = stable;
10887            conn.unstableCount = unstable;
10888            return !conn.dead;
10889        }
10890    }
10891
10892    public void unstableProviderDied(IBinder connection) {
10893        ContentProviderConnection conn;
10894        try {
10895            conn = (ContentProviderConnection)connection;
10896        } catch (ClassCastException e) {
10897            String msg ="refContentProvider: " + connection
10898                    + " not a ContentProviderConnection";
10899            Slog.w(TAG, msg);
10900            throw new IllegalArgumentException(msg);
10901        }
10902        if (conn == null) {
10903            throw new NullPointerException("connection is null");
10904        }
10905
10906        // Safely retrieve the content provider associated with the connection.
10907        IContentProvider provider;
10908        synchronized (this) {
10909            provider = conn.provider.provider;
10910        }
10911
10912        if (provider == null) {
10913            // Um, yeah, we're way ahead of you.
10914            return;
10915        }
10916
10917        // Make sure the caller is being honest with us.
10918        if (provider.asBinder().pingBinder()) {
10919            // Er, no, still looks good to us.
10920            synchronized (this) {
10921                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10922                        + " says " + conn + " died, but we don't agree");
10923                return;
10924            }
10925        }
10926
10927        // Well look at that!  It's dead!
10928        synchronized (this) {
10929            if (conn.provider.provider != provider) {
10930                // But something changed...  good enough.
10931                return;
10932            }
10933
10934            ProcessRecord proc = conn.provider.proc;
10935            if (proc == null || proc.thread == null) {
10936                // Seems like the process is already cleaned up.
10937                return;
10938            }
10939
10940            // As far as we're concerned, this is just like receiving a
10941            // death notification...  just a bit prematurely.
10942            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10943                    + ") early provider death");
10944            final long ident = Binder.clearCallingIdentity();
10945            try {
10946                appDiedLocked(proc);
10947            } finally {
10948                Binder.restoreCallingIdentity(ident);
10949            }
10950        }
10951    }
10952
10953    @Override
10954    public void appNotRespondingViaProvider(IBinder connection) {
10955        enforceCallingPermission(
10956                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10957
10958        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10959        if (conn == null) {
10960            Slog.w(TAG, "ContentProviderConnection is null");
10961            return;
10962        }
10963
10964        final ProcessRecord host = conn.provider.proc;
10965        if (host == null) {
10966            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10967            return;
10968        }
10969
10970        mHandler.post(new Runnable() {
10971            @Override
10972            public void run() {
10973                mAppErrors.appNotResponding(host, null, null, false,
10974                        "ContentProvider not responding");
10975            }
10976        });
10977    }
10978
10979    public final void installSystemProviders() {
10980        List<ProviderInfo> providers;
10981        synchronized (this) {
10982            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10983            providers = generateApplicationProvidersLocked(app);
10984            if (providers != null) {
10985                for (int i=providers.size()-1; i>=0; i--) {
10986                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10987                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10988                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10989                                + ": not system .apk");
10990                        providers.remove(i);
10991                    }
10992                }
10993            }
10994        }
10995        if (providers != null) {
10996            mSystemThread.installSystemProviders(providers);
10997        }
10998
10999        mCoreSettingsObserver = new CoreSettingsObserver(this);
11000        mFontScaleSettingObserver = new FontScaleSettingObserver();
11001
11002        //mUsageStatsService.monitorPackages();
11003    }
11004
11005    private void startPersistentApps(int matchFlags) {
11006        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11007
11008        synchronized (this) {
11009            try {
11010                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11011                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11012                for (ApplicationInfo app : apps) {
11013                    if (!"android".equals(app.packageName)) {
11014                        addAppLocked(app, false, null /* ABI override */);
11015                    }
11016                }
11017            } catch (RemoteException ex) {
11018            }
11019        }
11020    }
11021
11022    /**
11023     * When a user is unlocked, we need to install encryption-unaware providers
11024     * belonging to any running apps.
11025     */
11026    private void installEncryptionUnawareProviders(int userId) {
11027        if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
11028            // TODO: eventually pivot this back to look at current user state,
11029            // similar to the comment in UserManager.isUserUnlocked(), but for
11030            // now, if we started apps when "unlocked" then unaware providers
11031            // have already been spun up.
11032            return;
11033        }
11034
11035        // We're only interested in providers that are encryption unaware, and
11036        // we don't care about uninstalled apps, since there's no way they're
11037        // running at this point.
11038        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11039
11040        synchronized (this) {
11041            final int NP = mProcessNames.getMap().size();
11042            for (int ip = 0; ip < NP; ip++) {
11043                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11044                final int NA = apps.size();
11045                for (int ia = 0; ia < NA; ia++) {
11046                    final ProcessRecord app = apps.valueAt(ia);
11047                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11048
11049                    final int NG = app.pkgList.size();
11050                    for (int ig = 0; ig < NG; ig++) {
11051                        try {
11052                            final String pkgName = app.pkgList.keyAt(ig);
11053                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11054                                    .getPackageInfo(pkgName, matchFlags, userId);
11055                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11056                                for (ProviderInfo provInfo : pkgInfo.providers) {
11057                                    Log.v(TAG, "Installing " + provInfo);
11058                                    app.thread.scheduleInstallProvider(provInfo);
11059                                }
11060                            }
11061                        } catch (RemoteException ignored) {
11062                        }
11063                    }
11064                }
11065            }
11066        }
11067    }
11068
11069    /**
11070     * Allows apps to retrieve the MIME type of a URI.
11071     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11072     * users, then it does not need permission to access the ContentProvider.
11073     * Either, it needs cross-user uri grants.
11074     *
11075     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11076     *
11077     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11078     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11079     */
11080    public String getProviderMimeType(Uri uri, int userId) {
11081        enforceNotIsolatedCaller("getProviderMimeType");
11082        final String name = uri.getAuthority();
11083        int callingUid = Binder.getCallingUid();
11084        int callingPid = Binder.getCallingPid();
11085        long ident = 0;
11086        boolean clearedIdentity = false;
11087        synchronized (this) {
11088            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11089        }
11090        if (canClearIdentity(callingPid, callingUid, userId)) {
11091            clearedIdentity = true;
11092            ident = Binder.clearCallingIdentity();
11093        }
11094        ContentProviderHolder holder = null;
11095        try {
11096            holder = getContentProviderExternalUnchecked(name, null, userId);
11097            if (holder != null) {
11098                return holder.provider.getType(uri);
11099            }
11100        } catch (RemoteException e) {
11101            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11102            return null;
11103        } finally {
11104            // We need to clear the identity to call removeContentProviderExternalUnchecked
11105            if (!clearedIdentity) {
11106                ident = Binder.clearCallingIdentity();
11107            }
11108            try {
11109                if (holder != null) {
11110                    removeContentProviderExternalUnchecked(name, null, userId);
11111                }
11112            } finally {
11113                Binder.restoreCallingIdentity(ident);
11114            }
11115        }
11116
11117        return null;
11118    }
11119
11120    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11121        if (UserHandle.getUserId(callingUid) == userId) {
11122            return true;
11123        }
11124        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11125                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11126                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11127                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11128                return true;
11129        }
11130        return false;
11131    }
11132
11133    // =========================================================
11134    // GLOBAL MANAGEMENT
11135    // =========================================================
11136
11137    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11138            boolean isolated, int isolatedUid) {
11139        String proc = customProcess != null ? customProcess : info.processName;
11140        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11141        final int userId = UserHandle.getUserId(info.uid);
11142        int uid = info.uid;
11143        if (isolated) {
11144            if (isolatedUid == 0) {
11145                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11146                while (true) {
11147                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11148                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11149                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11150                    }
11151                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11152                    mNextIsolatedProcessUid++;
11153                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11154                        // No process for this uid, use it.
11155                        break;
11156                    }
11157                    stepsLeft--;
11158                    if (stepsLeft <= 0) {
11159                        return null;
11160                    }
11161                }
11162            } else {
11163                // Special case for startIsolatedProcess (internal only), where
11164                // the uid of the isolated process is specified by the caller.
11165                uid = isolatedUid;
11166            }
11167        }
11168        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11169        if (!mBooted && !mBooting
11170                && userId == UserHandle.USER_SYSTEM
11171                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11172            r.persistent = true;
11173        }
11174        addProcessNameLocked(r);
11175        return r;
11176    }
11177
11178    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11179            String abiOverride) {
11180        ProcessRecord app;
11181        if (!isolated) {
11182            app = getProcessRecordLocked(info.processName, info.uid, true);
11183        } else {
11184            app = null;
11185        }
11186
11187        if (app == null) {
11188            app = newProcessRecordLocked(info, null, isolated, 0);
11189            updateLruProcessLocked(app, false, null);
11190            updateOomAdjLocked();
11191        }
11192
11193        // This package really, really can not be stopped.
11194        try {
11195            AppGlobals.getPackageManager().setPackageStoppedState(
11196                    info.packageName, false, UserHandle.getUserId(app.uid));
11197        } catch (RemoteException e) {
11198        } catch (IllegalArgumentException e) {
11199            Slog.w(TAG, "Failed trying to unstop package "
11200                    + info.packageName + ": " + e);
11201        }
11202
11203        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11204            app.persistent = true;
11205            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11206        }
11207        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11208            mPersistentStartingProcesses.add(app);
11209            startProcessLocked(app, "added application", app.processName, abiOverride,
11210                    null /* entryPoint */, null /* entryPointArgs */);
11211        }
11212
11213        return app;
11214    }
11215
11216    public void unhandledBack() {
11217        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11218                "unhandledBack()");
11219
11220        synchronized(this) {
11221            final long origId = Binder.clearCallingIdentity();
11222            try {
11223                getFocusedStack().unhandledBackLocked();
11224            } finally {
11225                Binder.restoreCallingIdentity(origId);
11226            }
11227        }
11228    }
11229
11230    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11231        enforceNotIsolatedCaller("openContentUri");
11232        final int userId = UserHandle.getCallingUserId();
11233        String name = uri.getAuthority();
11234        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11235        ParcelFileDescriptor pfd = null;
11236        if (cph != null) {
11237            // We record the binder invoker's uid in thread-local storage before
11238            // going to the content provider to open the file.  Later, in the code
11239            // that handles all permissions checks, we look for this uid and use
11240            // that rather than the Activity Manager's own uid.  The effect is that
11241            // we do the check against the caller's permissions even though it looks
11242            // to the content provider like the Activity Manager itself is making
11243            // the request.
11244            Binder token = new Binder();
11245            sCallerIdentity.set(new Identity(
11246                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11247            try {
11248                pfd = cph.provider.openFile(null, uri, "r", null, token);
11249            } catch (FileNotFoundException e) {
11250                // do nothing; pfd will be returned null
11251            } finally {
11252                // Ensure that whatever happens, we clean up the identity state
11253                sCallerIdentity.remove();
11254                // Ensure we're done with the provider.
11255                removeContentProviderExternalUnchecked(name, null, userId);
11256            }
11257        } else {
11258            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11259        }
11260        return pfd;
11261    }
11262
11263    // Actually is sleeping or shutting down or whatever else in the future
11264    // is an inactive state.
11265    public boolean isSleepingOrShuttingDown() {
11266        return isSleeping() || mShuttingDown;
11267    }
11268
11269    public boolean isSleeping() {
11270        return mSleeping;
11271    }
11272
11273    void onWakefulnessChanged(int wakefulness) {
11274        synchronized(this) {
11275            mWakefulness = wakefulness;
11276            updateSleepIfNeededLocked();
11277        }
11278    }
11279
11280    void finishRunningVoiceLocked() {
11281        if (mRunningVoice != null) {
11282            mRunningVoice = null;
11283            mVoiceWakeLock.release();
11284            updateSleepIfNeededLocked();
11285        }
11286    }
11287
11288    void startTimeTrackingFocusedActivityLocked() {
11289        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11290            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11291        }
11292    }
11293
11294    void updateSleepIfNeededLocked() {
11295        if (mSleeping && !shouldSleepLocked()) {
11296            mSleeping = false;
11297            startTimeTrackingFocusedActivityLocked();
11298            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11299            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11300            updateOomAdjLocked();
11301        } else if (!mSleeping && shouldSleepLocked()) {
11302            mSleeping = true;
11303            if (mCurAppTimeTracker != null) {
11304                mCurAppTimeTracker.stop();
11305            }
11306            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11307            mStackSupervisor.goingToSleepLocked();
11308            updateOomAdjLocked();
11309
11310            // Initialize the wake times of all processes.
11311            checkExcessivePowerUsageLocked(false);
11312            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11313            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11314            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11315        }
11316    }
11317
11318    private boolean shouldSleepLocked() {
11319        // Resume applications while running a voice interactor.
11320        if (mRunningVoice != null) {
11321            return false;
11322        }
11323
11324        // TODO: Transform the lock screen state into a sleep token instead.
11325        switch (mWakefulness) {
11326            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11327            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11328            case PowerManagerInternal.WAKEFULNESS_DOZING:
11329                // Pause applications whenever the lock screen is shown or any sleep
11330                // tokens have been acquired.
11331                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11332            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11333            default:
11334                // If we're asleep then pause applications unconditionally.
11335                return true;
11336        }
11337    }
11338
11339    /** Pokes the task persister. */
11340    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11341        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11342    }
11343
11344    /** Notifies all listeners when the task stack has changed. */
11345    void notifyTaskStackChangedLocked() {
11346        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11347        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11348        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11349        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11350    }
11351
11352    /** Notifies all listeners when an Activity is pinned. */
11353    void notifyActivityPinnedLocked() {
11354        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11355        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11356    }
11357
11358    /**
11359     * Notifies all listeners when an attempt was made to start an an activity that is already
11360     * running in the pinned stack and the activity was not actually started, but the task is
11361     * either brought to the front or a new Intent is delivered to it.
11362     */
11363    void notifyPinnedActivityRestartAttemptLocked() {
11364        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11365        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11366    }
11367
11368    /** Notifies all listeners when the pinned stack animation ends. */
11369    @Override
11370    public void notifyPinnedStackAnimationEnded() {
11371        synchronized (this) {
11372            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11373            mHandler.obtainMessage(
11374                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11375        }
11376    }
11377
11378    @Override
11379    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11380        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11381    }
11382
11383    @Override
11384    public boolean shutdown(int timeout) {
11385        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11386                != PackageManager.PERMISSION_GRANTED) {
11387            throw new SecurityException("Requires permission "
11388                    + android.Manifest.permission.SHUTDOWN);
11389        }
11390
11391        boolean timedout = false;
11392
11393        synchronized(this) {
11394            mShuttingDown = true;
11395            updateEventDispatchingLocked();
11396            timedout = mStackSupervisor.shutdownLocked(timeout);
11397        }
11398
11399        mAppOpsService.shutdown();
11400        if (mUsageStatsService != null) {
11401            mUsageStatsService.prepareShutdown();
11402        }
11403        mBatteryStatsService.shutdown();
11404        synchronized (this) {
11405            mProcessStats.shutdownLocked();
11406            notifyTaskPersisterLocked(null, true);
11407        }
11408
11409        return timedout;
11410    }
11411
11412    public final void activitySlept(IBinder token) {
11413        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11414
11415        final long origId = Binder.clearCallingIdentity();
11416
11417        synchronized (this) {
11418            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11419            if (r != null) {
11420                mStackSupervisor.activitySleptLocked(r);
11421            }
11422        }
11423
11424        Binder.restoreCallingIdentity(origId);
11425    }
11426
11427    private String lockScreenShownToString() {
11428        switch (mLockScreenShown) {
11429            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11430            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11431            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11432            default: return "Unknown=" + mLockScreenShown;
11433        }
11434    }
11435
11436    void logLockScreen(String msg) {
11437        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11438                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11439                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11440                + " mSleeping=" + mSleeping);
11441    }
11442
11443    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11444        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11445        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11446        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11447            boolean wasRunningVoice = mRunningVoice != null;
11448            mRunningVoice = session;
11449            if (!wasRunningVoice) {
11450                mVoiceWakeLock.acquire();
11451                updateSleepIfNeededLocked();
11452            }
11453        }
11454    }
11455
11456    private void updateEventDispatchingLocked() {
11457        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11458    }
11459
11460    public void setLockScreenShown(boolean shown) {
11461        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11462                != PackageManager.PERMISSION_GRANTED) {
11463            throw new SecurityException("Requires permission "
11464                    + android.Manifest.permission.DEVICE_POWER);
11465        }
11466
11467        synchronized(this) {
11468            long ident = Binder.clearCallingIdentity();
11469            try {
11470                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11471                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11472                updateSleepIfNeededLocked();
11473            } finally {
11474                Binder.restoreCallingIdentity(ident);
11475            }
11476        }
11477    }
11478
11479    @Override
11480    public void notifyLockedProfile(@UserIdInt int userId) {
11481        try {
11482            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11483                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11484            }
11485        } catch (RemoteException ex) {
11486            throw new SecurityException("Fail to check is caller a privileged app", ex);
11487        }
11488
11489        synchronized (this) {
11490            if (mStackSupervisor.isUserLockedProfile(userId)) {
11491                final long ident = Binder.clearCallingIdentity();
11492                try {
11493                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11494                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11495                        // If there is no device lock, we will show the profile's credential page.
11496                        mActivityStarter.showConfirmDeviceCredential(userId);
11497                    } else {
11498                        // Showing launcher to avoid user entering credential twice.
11499                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11500                    }
11501                } finally {
11502                    Binder.restoreCallingIdentity(ident);
11503                }
11504            }
11505        }
11506    }
11507
11508    @Override
11509    public void startConfirmDeviceCredentialIntent(Intent intent) {
11510        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11511        synchronized (this) {
11512            final long ident = Binder.clearCallingIdentity();
11513            try {
11514                mActivityStarter.startConfirmCredentialIntent(intent);
11515            } finally {
11516                Binder.restoreCallingIdentity(ident);
11517            }
11518        }
11519    }
11520
11521    @Override
11522    public void stopAppSwitches() {
11523        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11524                != PackageManager.PERMISSION_GRANTED) {
11525            throw new SecurityException("viewquires permission "
11526                    + android.Manifest.permission.STOP_APP_SWITCHES);
11527        }
11528
11529        synchronized(this) {
11530            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11531                    + APP_SWITCH_DELAY_TIME;
11532            mDidAppSwitch = false;
11533            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11534            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11535            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11536        }
11537    }
11538
11539    public void resumeAppSwitches() {
11540        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11541                != PackageManager.PERMISSION_GRANTED) {
11542            throw new SecurityException("Requires permission "
11543                    + android.Manifest.permission.STOP_APP_SWITCHES);
11544        }
11545
11546        synchronized(this) {
11547            // Note that we don't execute any pending app switches... we will
11548            // let those wait until either the timeout, or the next start
11549            // activity request.
11550            mAppSwitchesAllowedTime = 0;
11551        }
11552    }
11553
11554    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11555            int callingPid, int callingUid, String name) {
11556        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11557            return true;
11558        }
11559
11560        int perm = checkComponentPermission(
11561                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11562                sourceUid, -1, true);
11563        if (perm == PackageManager.PERMISSION_GRANTED) {
11564            return true;
11565        }
11566
11567        // If the actual IPC caller is different from the logical source, then
11568        // also see if they are allowed to control app switches.
11569        if (callingUid != -1 && callingUid != sourceUid) {
11570            perm = checkComponentPermission(
11571                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11572                    callingUid, -1, true);
11573            if (perm == PackageManager.PERMISSION_GRANTED) {
11574                return true;
11575            }
11576        }
11577
11578        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11579        return false;
11580    }
11581
11582    public void setDebugApp(String packageName, boolean waitForDebugger,
11583            boolean persistent) {
11584        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11585                "setDebugApp()");
11586
11587        long ident = Binder.clearCallingIdentity();
11588        try {
11589            // Note that this is not really thread safe if there are multiple
11590            // callers into it at the same time, but that's not a situation we
11591            // care about.
11592            if (persistent) {
11593                final ContentResolver resolver = mContext.getContentResolver();
11594                Settings.Global.putString(
11595                    resolver, Settings.Global.DEBUG_APP,
11596                    packageName);
11597                Settings.Global.putInt(
11598                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11599                    waitForDebugger ? 1 : 0);
11600            }
11601
11602            synchronized (this) {
11603                if (!persistent) {
11604                    mOrigDebugApp = mDebugApp;
11605                    mOrigWaitForDebugger = mWaitForDebugger;
11606                }
11607                mDebugApp = packageName;
11608                mWaitForDebugger = waitForDebugger;
11609                mDebugTransient = !persistent;
11610                if (packageName != null) {
11611                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11612                            false, UserHandle.USER_ALL, "set debug app");
11613                }
11614            }
11615        } finally {
11616            Binder.restoreCallingIdentity(ident);
11617        }
11618    }
11619
11620    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11621        synchronized (this) {
11622            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11623            if (!isDebuggable) {
11624                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11625                    throw new SecurityException("Process not debuggable: " + app.packageName);
11626                }
11627            }
11628
11629            mTrackAllocationApp = processName;
11630        }
11631    }
11632
11633    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11634        synchronized (this) {
11635            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11636            if (!isDebuggable) {
11637                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11638                    throw new SecurityException("Process not debuggable: " + app.packageName);
11639                }
11640            }
11641            mProfileApp = processName;
11642            mProfileFile = profilerInfo.profileFile;
11643            if (mProfileFd != null) {
11644                try {
11645                    mProfileFd.close();
11646                } catch (IOException e) {
11647                }
11648                mProfileFd = null;
11649            }
11650            mProfileFd = profilerInfo.profileFd;
11651            mSamplingInterval = profilerInfo.samplingInterval;
11652            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11653            mProfileType = 0;
11654        }
11655    }
11656
11657    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11658        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11659        if (!isDebuggable) {
11660            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11661                throw new SecurityException("Process not debuggable: " + app.packageName);
11662            }
11663        }
11664        mNativeDebuggingApp = processName;
11665    }
11666
11667    @Override
11668    public void setAlwaysFinish(boolean enabled) {
11669        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11670                "setAlwaysFinish()");
11671
11672        long ident = Binder.clearCallingIdentity();
11673        try {
11674            Settings.Global.putInt(
11675                    mContext.getContentResolver(),
11676                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11677
11678            synchronized (this) {
11679                mAlwaysFinishActivities = enabled;
11680            }
11681        } finally {
11682            Binder.restoreCallingIdentity(ident);
11683        }
11684    }
11685
11686    @Override
11687    public void setLenientBackgroundCheck(boolean enabled) {
11688        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11689                "setLenientBackgroundCheck()");
11690
11691        long ident = Binder.clearCallingIdentity();
11692        try {
11693            Settings.Global.putInt(
11694                    mContext.getContentResolver(),
11695                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11696
11697            synchronized (this) {
11698                mLenientBackgroundCheck = enabled;
11699            }
11700        } finally {
11701            Binder.restoreCallingIdentity(ident);
11702        }
11703    }
11704
11705    @Override
11706    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11707        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11708                "setActivityController()");
11709        synchronized (this) {
11710            mController = controller;
11711            mControllerIsAMonkey = imAMonkey;
11712            Watchdog.getInstance().setActivityController(controller);
11713        }
11714    }
11715
11716    @Override
11717    public void setUserIsMonkey(boolean userIsMonkey) {
11718        synchronized (this) {
11719            synchronized (mPidsSelfLocked) {
11720                final int callingPid = Binder.getCallingPid();
11721                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11722                if (precessRecord == null) {
11723                    throw new SecurityException("Unknown process: " + callingPid);
11724                }
11725                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11726                    throw new SecurityException("Only an instrumentation process "
11727                            + "with a UiAutomation can call setUserIsMonkey");
11728                }
11729            }
11730            mUserIsMonkey = userIsMonkey;
11731        }
11732    }
11733
11734    @Override
11735    public boolean isUserAMonkey() {
11736        synchronized (this) {
11737            // If there is a controller also implies the user is a monkey.
11738            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11739        }
11740    }
11741
11742    public void requestBugReport(int bugreportType) {
11743        String service = null;
11744        switch (bugreportType) {
11745            case ActivityManager.BUGREPORT_OPTION_FULL:
11746                service = "bugreport";
11747                break;
11748            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11749                service = "bugreportplus";
11750                break;
11751            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11752                service = "bugreportremote";
11753                break;
11754        }
11755        if (service == null) {
11756            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11757                    + bugreportType);
11758        }
11759        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11760        SystemProperties.set("ctl.start", service);
11761    }
11762
11763    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11764        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11765    }
11766
11767    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11768        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11769            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11770        }
11771        return KEY_DISPATCHING_TIMEOUT;
11772    }
11773
11774    @Override
11775    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11776        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11777                != PackageManager.PERMISSION_GRANTED) {
11778            throw new SecurityException("Requires permission "
11779                    + android.Manifest.permission.FILTER_EVENTS);
11780        }
11781        ProcessRecord proc;
11782        long timeout;
11783        synchronized (this) {
11784            synchronized (mPidsSelfLocked) {
11785                proc = mPidsSelfLocked.get(pid);
11786            }
11787            timeout = getInputDispatchingTimeoutLocked(proc);
11788        }
11789
11790        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11791            return -1;
11792        }
11793
11794        return timeout;
11795    }
11796
11797    /**
11798     * Handle input dispatching timeouts.
11799     * Returns whether input dispatching should be aborted or not.
11800     */
11801    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11802            final ActivityRecord activity, final ActivityRecord parent,
11803            final boolean aboveSystem, String reason) {
11804        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11805                != PackageManager.PERMISSION_GRANTED) {
11806            throw new SecurityException("Requires permission "
11807                    + android.Manifest.permission.FILTER_EVENTS);
11808        }
11809
11810        final String annotation;
11811        if (reason == null) {
11812            annotation = "Input dispatching timed out";
11813        } else {
11814            annotation = "Input dispatching timed out (" + reason + ")";
11815        }
11816
11817        if (proc != null) {
11818            synchronized (this) {
11819                if (proc.debugging) {
11820                    return false;
11821                }
11822
11823                if (mDidDexOpt) {
11824                    // Give more time since we were dexopting.
11825                    mDidDexOpt = false;
11826                    return false;
11827                }
11828
11829                if (proc.instrumentationClass != null) {
11830                    Bundle info = new Bundle();
11831                    info.putString("shortMsg", "keyDispatchingTimedOut");
11832                    info.putString("longMsg", annotation);
11833                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11834                    return true;
11835                }
11836            }
11837            mHandler.post(new Runnable() {
11838                @Override
11839                public void run() {
11840                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11841                }
11842            });
11843        }
11844
11845        return true;
11846    }
11847
11848    @Override
11849    public Bundle getAssistContextExtras(int requestType) {
11850        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11851                null, null, true, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11852        if (pae == null) {
11853            return null;
11854        }
11855        synchronized (pae) {
11856            while (!pae.haveResult) {
11857                try {
11858                    pae.wait();
11859                } catch (InterruptedException e) {
11860                }
11861            }
11862        }
11863        synchronized (this) {
11864            buildAssistBundleLocked(pae, pae.result);
11865            mPendingAssistExtras.remove(pae);
11866            mUiHandler.removeCallbacks(pae);
11867        }
11868        return pae.extras;
11869    }
11870
11871    @Override
11872    public boolean isAssistDataAllowedOnCurrentActivity() {
11873        int userId;
11874        synchronized (this) {
11875            userId = mUserController.getCurrentUserIdLocked();
11876            ActivityRecord activity = getFocusedStack().topActivity();
11877            if (activity == null) {
11878                return false;
11879            }
11880            userId = activity.userId;
11881        }
11882        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11883                Context.DEVICE_POLICY_SERVICE);
11884        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11885    }
11886
11887    @Override
11888    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11889        long ident = Binder.clearCallingIdentity();
11890        try {
11891            synchronized (this) {
11892                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11893                ActivityRecord top = getFocusedStack().topActivity();
11894                if (top != caller) {
11895                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11896                            + " is not current top " + top);
11897                    return false;
11898                }
11899                if (!top.nowVisible) {
11900                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11901                            + " is not visible");
11902                    return false;
11903                }
11904            }
11905            AssistUtils utils = new AssistUtils(mContext);
11906            return utils.showSessionForActiveService(args,
11907                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11908        } finally {
11909            Binder.restoreCallingIdentity(ident);
11910        }
11911    }
11912
11913    @Override
11914    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11915            Bundle receiverExtras,
11916            IBinder activityToken, boolean focused) {
11917        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11918                activityToken, focused,
11919                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11920                != null;
11921    }
11922
11923    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11924            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused,
11925            int userHandle, Bundle args, long timeout) {
11926        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11927                "enqueueAssistContext()");
11928        synchronized (this) {
11929            ActivityRecord activity = getFocusedStack().topActivity();
11930            if (activity == null) {
11931                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11932                return null;
11933            }
11934            if (activity.app == null || activity.app.thread == null) {
11935                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11936                return null;
11937            }
11938            if (focused) {
11939                if (activityToken != null) {
11940                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11941                    if (activity != caller) {
11942                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11943                                + " is not current top " + activity);
11944                        return null;
11945                    }
11946                }
11947            } else {
11948                activity = ActivityRecord.forTokenLocked(activityToken);
11949                if (activity == null) {
11950                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
11951                            + " couldn't be found");
11952                    return null;
11953                }
11954            }
11955
11956            PendingAssistExtras pae;
11957            Bundle extras = new Bundle();
11958            if (args != null) {
11959                extras.putAll(args);
11960            }
11961            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11962            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11963            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
11964                    userHandle);
11965            try {
11966                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11967                        requestType);
11968                mPendingAssistExtras.add(pae);
11969                mUiHandler.postDelayed(pae, timeout);
11970            } catch (RemoteException e) {
11971                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11972                return null;
11973            }
11974            return pae;
11975        }
11976    }
11977
11978    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11979        IResultReceiver receiver;
11980        synchronized (this) {
11981            mPendingAssistExtras.remove(pae);
11982            receiver = pae.receiver;
11983        }
11984        if (receiver != null) {
11985            // Caller wants result sent back to them.
11986            try {
11987                pae.receiver.send(0, null);
11988            } catch (RemoteException e) {
11989            }
11990        }
11991    }
11992
11993    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11994        if (result != null) {
11995            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11996        }
11997        if (pae.hint != null) {
11998            pae.extras.putBoolean(pae.hint, true);
11999        }
12000    }
12001
12002    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12003            AssistContent content, Uri referrer) {
12004        PendingAssistExtras pae = (PendingAssistExtras)token;
12005        synchronized (pae) {
12006            pae.result = extras;
12007            pae.structure = structure;
12008            pae.content = content;
12009            if (referrer != null) {
12010                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12011            }
12012            pae.haveResult = true;
12013            pae.notifyAll();
12014            if (pae.intent == null && pae.receiver == null) {
12015                // Caller is just waiting for the result.
12016                return;
12017            }
12018        }
12019
12020        // We are now ready to launch the assist activity.
12021        IResultReceiver sendReceiver = null;
12022        Bundle sendBundle = null;
12023        synchronized (this) {
12024            buildAssistBundleLocked(pae, extras);
12025            boolean exists = mPendingAssistExtras.remove(pae);
12026            mUiHandler.removeCallbacks(pae);
12027            if (!exists) {
12028                // Timed out.
12029                return;
12030            }
12031            if ((sendReceiver=pae.receiver) != null) {
12032                // Caller wants result sent back to them.
12033                sendBundle = new Bundle();
12034                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12035                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12036                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12037                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12038                        pae.receiverExtras);
12039            }
12040        }
12041        if (sendReceiver != null) {
12042            try {
12043                sendReceiver.send(0, sendBundle);
12044            } catch (RemoteException e) {
12045            }
12046            return;
12047        }
12048
12049        long ident = Binder.clearCallingIdentity();
12050        try {
12051            pae.intent.replaceExtras(pae.extras);
12052            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12053                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12054                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12055            closeSystemDialogs("assist");
12056            try {
12057                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12058            } catch (ActivityNotFoundException e) {
12059                Slog.w(TAG, "No activity to handle assist action.", e);
12060            }
12061        } finally {
12062            Binder.restoreCallingIdentity(ident);
12063        }
12064    }
12065
12066    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12067            Bundle args) {
12068        return enqueueAssistContext(requestType, intent, hint, null, null, null, true,
12069                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12070    }
12071
12072    public void registerProcessObserver(IProcessObserver observer) {
12073        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12074                "registerProcessObserver()");
12075        synchronized (this) {
12076            mProcessObservers.register(observer);
12077        }
12078    }
12079
12080    @Override
12081    public void unregisterProcessObserver(IProcessObserver observer) {
12082        synchronized (this) {
12083            mProcessObservers.unregister(observer);
12084        }
12085    }
12086
12087    @Override
12088    public void registerUidObserver(IUidObserver observer, int which) {
12089        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12090                "registerUidObserver()");
12091        synchronized (this) {
12092            mUidObservers.register(observer, which);
12093        }
12094    }
12095
12096    @Override
12097    public void unregisterUidObserver(IUidObserver observer) {
12098        synchronized (this) {
12099            mUidObservers.unregister(observer);
12100        }
12101    }
12102
12103    @Override
12104    public boolean convertFromTranslucent(IBinder token) {
12105        final long origId = Binder.clearCallingIdentity();
12106        try {
12107            synchronized (this) {
12108                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12109                if (r == null) {
12110                    return false;
12111                }
12112                final boolean translucentChanged = r.changeWindowTranslucency(true);
12113                if (translucentChanged) {
12114                    r.task.stack.releaseBackgroundResources(r);
12115                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12116                }
12117                mWindowManager.setAppFullscreen(token, true);
12118                return translucentChanged;
12119            }
12120        } finally {
12121            Binder.restoreCallingIdentity(origId);
12122        }
12123    }
12124
12125    @Override
12126    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12127        final long origId = Binder.clearCallingIdentity();
12128        try {
12129            synchronized (this) {
12130                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12131                if (r == null) {
12132                    return false;
12133                }
12134                int index = r.task.mActivities.lastIndexOf(r);
12135                if (index > 0) {
12136                    ActivityRecord under = r.task.mActivities.get(index - 1);
12137                    under.returningOptions = options;
12138                }
12139                final boolean translucentChanged = r.changeWindowTranslucency(false);
12140                if (translucentChanged) {
12141                    r.task.stack.convertActivityToTranslucent(r);
12142                }
12143                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12144                mWindowManager.setAppFullscreen(token, false);
12145                return translucentChanged;
12146            }
12147        } finally {
12148            Binder.restoreCallingIdentity(origId);
12149        }
12150    }
12151
12152    @Override
12153    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12154        final long origId = Binder.clearCallingIdentity();
12155        try {
12156            synchronized (this) {
12157                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12158                if (r != null) {
12159                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12160                }
12161            }
12162            return false;
12163        } finally {
12164            Binder.restoreCallingIdentity(origId);
12165        }
12166    }
12167
12168    @Override
12169    public boolean isBackgroundVisibleBehind(IBinder token) {
12170        final long origId = Binder.clearCallingIdentity();
12171        try {
12172            synchronized (this) {
12173                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12174                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12175                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12176                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12177                return visible;
12178            }
12179        } finally {
12180            Binder.restoreCallingIdentity(origId);
12181        }
12182    }
12183
12184    @Override
12185    public ActivityOptions getActivityOptions(IBinder token) {
12186        final long origId = Binder.clearCallingIdentity();
12187        try {
12188            synchronized (this) {
12189                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12190                if (r != null) {
12191                    final ActivityOptions activityOptions = r.pendingOptions;
12192                    r.pendingOptions = null;
12193                    return activityOptions;
12194                }
12195                return null;
12196            }
12197        } finally {
12198            Binder.restoreCallingIdentity(origId);
12199        }
12200    }
12201
12202    @Override
12203    public void setImmersive(IBinder token, boolean immersive) {
12204        synchronized(this) {
12205            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12206            if (r == null) {
12207                throw new IllegalArgumentException();
12208            }
12209            r.immersive = immersive;
12210
12211            // update associated state if we're frontmost
12212            if (r == mFocusedActivity) {
12213                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12214                applyUpdateLockStateLocked(r);
12215            }
12216        }
12217    }
12218
12219    @Override
12220    public boolean isImmersive(IBinder token) {
12221        synchronized (this) {
12222            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12223            if (r == null) {
12224                throw new IllegalArgumentException();
12225            }
12226            return r.immersive;
12227        }
12228    }
12229
12230    @Override
12231    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12232        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12233            throw new UnsupportedOperationException("VR mode not supported on this device!");
12234        }
12235
12236        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12237
12238        ActivityRecord r;
12239        synchronized (this) {
12240            r = ActivityRecord.isInStackLocked(token);
12241        }
12242
12243        if (r == null) {
12244            throw new IllegalArgumentException();
12245        }
12246
12247        int err;
12248        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12249                VrManagerInternal.NO_ERROR) {
12250            return err;
12251        }
12252
12253        synchronized(this) {
12254            r.requestedVrComponent = (enabled) ? packageName : null;
12255
12256            // Update associated state if this activity is currently focused
12257            if (r == mFocusedActivity) {
12258                applyUpdateVrModeLocked(r);
12259            }
12260            return 0;
12261        }
12262    }
12263
12264    @Override
12265    public boolean isVrModePackageEnabled(ComponentName packageName) {
12266        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12267            throw new UnsupportedOperationException("VR mode not supported on this device!");
12268        }
12269
12270        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12271
12272        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12273                VrManagerInternal.NO_ERROR;
12274    }
12275
12276    public boolean isTopActivityImmersive() {
12277        enforceNotIsolatedCaller("startActivity");
12278        synchronized (this) {
12279            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12280            return (r != null) ? r.immersive : false;
12281        }
12282    }
12283
12284    @Override
12285    public boolean isTopOfTask(IBinder token) {
12286        synchronized (this) {
12287            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12288            if (r == null) {
12289                throw new IllegalArgumentException();
12290            }
12291            return r.task.getTopActivity() == r;
12292        }
12293    }
12294
12295    public final void enterSafeMode() {
12296        synchronized(this) {
12297            // It only makes sense to do this before the system is ready
12298            // and started launching other packages.
12299            if (!mSystemReady) {
12300                try {
12301                    AppGlobals.getPackageManager().enterSafeMode();
12302                } catch (RemoteException e) {
12303                }
12304            }
12305
12306            mSafeMode = true;
12307        }
12308    }
12309
12310    public final void showSafeModeOverlay() {
12311        View v = LayoutInflater.from(mContext).inflate(
12312                com.android.internal.R.layout.safe_mode, null);
12313        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12314        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12315        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12316        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12317        lp.gravity = Gravity.BOTTOM | Gravity.START;
12318        lp.format = v.getBackground().getOpacity();
12319        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12320                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12321        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12322        ((WindowManager)mContext.getSystemService(
12323                Context.WINDOW_SERVICE)).addView(v, lp);
12324    }
12325
12326    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12327        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12328            return;
12329        }
12330        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12331        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12332        synchronized (stats) {
12333            if (mBatteryStatsService.isOnBattery()) {
12334                mBatteryStatsService.enforceCallingPermission();
12335                int MY_UID = Binder.getCallingUid();
12336                final int uid;
12337                if (sender == null) {
12338                    uid = sourceUid;
12339                } else {
12340                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12341                }
12342                BatteryStatsImpl.Uid.Pkg pkg =
12343                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12344                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12345                pkg.noteWakeupAlarmLocked(tag);
12346            }
12347        }
12348    }
12349
12350    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12351        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12352            return;
12353        }
12354        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12355        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12356        synchronized (stats) {
12357            mBatteryStatsService.enforceCallingPermission();
12358            int MY_UID = Binder.getCallingUid();
12359            final int uid;
12360            if (sender == null) {
12361                uid = sourceUid;
12362            } else {
12363                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12364            }
12365            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12366        }
12367    }
12368
12369    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12370        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12371            return;
12372        }
12373        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12374        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12375        synchronized (stats) {
12376            mBatteryStatsService.enforceCallingPermission();
12377            int MY_UID = Binder.getCallingUid();
12378            final int uid;
12379            if (sender == null) {
12380                uid = sourceUid;
12381            } else {
12382                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12383            }
12384            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12385        }
12386    }
12387
12388    public boolean killPids(int[] pids, String pReason, boolean secure) {
12389        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12390            throw new SecurityException("killPids only available to the system");
12391        }
12392        String reason = (pReason == null) ? "Unknown" : pReason;
12393        // XXX Note: don't acquire main activity lock here, because the window
12394        // manager calls in with its locks held.
12395
12396        boolean killed = false;
12397        synchronized (mPidsSelfLocked) {
12398            int worstType = 0;
12399            for (int i=0; i<pids.length; i++) {
12400                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12401                if (proc != null) {
12402                    int type = proc.setAdj;
12403                    if (type > worstType) {
12404                        worstType = type;
12405                    }
12406                }
12407            }
12408
12409            // If the worst oom_adj is somewhere in the cached proc LRU range,
12410            // then constrain it so we will kill all cached procs.
12411            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12412                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12413                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12414            }
12415
12416            // If this is not a secure call, don't let it kill processes that
12417            // are important.
12418            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12419                worstType = ProcessList.SERVICE_ADJ;
12420            }
12421
12422            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12423            for (int i=0; i<pids.length; i++) {
12424                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12425                if (proc == null) {
12426                    continue;
12427                }
12428                int adj = proc.setAdj;
12429                if (adj >= worstType && !proc.killedByAm) {
12430                    proc.kill(reason, true);
12431                    killed = true;
12432                }
12433            }
12434        }
12435        return killed;
12436    }
12437
12438    @Override
12439    public void killUid(int appId, int userId, String reason) {
12440        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12441        synchronized (this) {
12442            final long identity = Binder.clearCallingIdentity();
12443            try {
12444                killPackageProcessesLocked(null, appId, userId,
12445                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12446                        reason != null ? reason : "kill uid");
12447            } finally {
12448                Binder.restoreCallingIdentity(identity);
12449            }
12450        }
12451    }
12452
12453    @Override
12454    public boolean killProcessesBelowForeground(String reason) {
12455        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12456            throw new SecurityException("killProcessesBelowForeground() only available to system");
12457        }
12458
12459        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12460    }
12461
12462    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12463        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12464            throw new SecurityException("killProcessesBelowAdj() only available to system");
12465        }
12466
12467        boolean killed = false;
12468        synchronized (mPidsSelfLocked) {
12469            final int size = mPidsSelfLocked.size();
12470            for (int i = 0; i < size; i++) {
12471                final int pid = mPidsSelfLocked.keyAt(i);
12472                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12473                if (proc == null) continue;
12474
12475                final int adj = proc.setAdj;
12476                if (adj > belowAdj && !proc.killedByAm) {
12477                    proc.kill(reason, true);
12478                    killed = true;
12479                }
12480            }
12481        }
12482        return killed;
12483    }
12484
12485    @Override
12486    public void hang(final IBinder who, boolean allowRestart) {
12487        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12488                != PackageManager.PERMISSION_GRANTED) {
12489            throw new SecurityException("Requires permission "
12490                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12491        }
12492
12493        final IBinder.DeathRecipient death = new DeathRecipient() {
12494            @Override
12495            public void binderDied() {
12496                synchronized (this) {
12497                    notifyAll();
12498                }
12499            }
12500        };
12501
12502        try {
12503            who.linkToDeath(death, 0);
12504        } catch (RemoteException e) {
12505            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12506            return;
12507        }
12508
12509        synchronized (this) {
12510            Watchdog.getInstance().setAllowRestart(allowRestart);
12511            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12512            synchronized (death) {
12513                while (who.isBinderAlive()) {
12514                    try {
12515                        death.wait();
12516                    } catch (InterruptedException e) {
12517                    }
12518                }
12519            }
12520            Watchdog.getInstance().setAllowRestart(true);
12521        }
12522    }
12523
12524    @Override
12525    public void restart() {
12526        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12527                != PackageManager.PERMISSION_GRANTED) {
12528            throw new SecurityException("Requires permission "
12529                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12530        }
12531
12532        Log.i(TAG, "Sending shutdown broadcast...");
12533
12534        BroadcastReceiver br = new BroadcastReceiver() {
12535            @Override public void onReceive(Context context, Intent intent) {
12536                // Now the broadcast is done, finish up the low-level shutdown.
12537                Log.i(TAG, "Shutting down activity manager...");
12538                shutdown(10000);
12539                Log.i(TAG, "Shutdown complete, restarting!");
12540                Process.killProcess(Process.myPid());
12541                System.exit(10);
12542            }
12543        };
12544
12545        // First send the high-level shut down broadcast.
12546        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12547        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12548        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12549        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12550        mContext.sendOrderedBroadcastAsUser(intent,
12551                UserHandle.ALL, null, br, mHandler, 0, null, null);
12552        */
12553        br.onReceive(mContext, intent);
12554    }
12555
12556    private long getLowRamTimeSinceIdle(long now) {
12557        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12558    }
12559
12560    @Override
12561    public void performIdleMaintenance() {
12562        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12563                != PackageManager.PERMISSION_GRANTED) {
12564            throw new SecurityException("Requires permission "
12565                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12566        }
12567
12568        synchronized (this) {
12569            final long now = SystemClock.uptimeMillis();
12570            final long timeSinceLastIdle = now - mLastIdleTime;
12571            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12572            mLastIdleTime = now;
12573            mLowRamTimeSinceLastIdle = 0;
12574            if (mLowRamStartTime != 0) {
12575                mLowRamStartTime = now;
12576            }
12577
12578            StringBuilder sb = new StringBuilder(128);
12579            sb.append("Idle maintenance over ");
12580            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12581            sb.append(" low RAM for ");
12582            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12583            Slog.i(TAG, sb.toString());
12584
12585            // If at least 1/3 of our time since the last idle period has been spent
12586            // with RAM low, then we want to kill processes.
12587            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12588
12589            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12590                ProcessRecord proc = mLruProcesses.get(i);
12591                if (proc.notCachedSinceIdle) {
12592                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12593                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12594                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12595                        if (doKilling && proc.initialIdlePss != 0
12596                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12597                            sb = new StringBuilder(128);
12598                            sb.append("Kill");
12599                            sb.append(proc.processName);
12600                            sb.append(" in idle maint: pss=");
12601                            sb.append(proc.lastPss);
12602                            sb.append(", swapPss=");
12603                            sb.append(proc.lastSwapPss);
12604                            sb.append(", initialPss=");
12605                            sb.append(proc.initialIdlePss);
12606                            sb.append(", period=");
12607                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12608                            sb.append(", lowRamPeriod=");
12609                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12610                            Slog.wtfQuiet(TAG, sb.toString());
12611                            proc.kill("idle maint (pss " + proc.lastPss
12612                                    + " from " + proc.initialIdlePss + ")", true);
12613                        }
12614                    }
12615                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12616                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12617                    proc.notCachedSinceIdle = true;
12618                    proc.initialIdlePss = 0;
12619                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12620                            mTestPssMode, isSleeping(), now);
12621                }
12622            }
12623
12624            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12625            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12626        }
12627    }
12628
12629    private void retrieveSettings() {
12630        final ContentResolver resolver = mContext.getContentResolver();
12631        final boolean freeformWindowManagement =
12632                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12633                        || Settings.Global.getInt(
12634                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12635        final boolean supportsPictureInPicture =
12636                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12637
12638        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12639        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12640        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12641        final boolean alwaysFinishActivities =
12642                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12643        final boolean lenientBackgroundCheck =
12644                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12645        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12646        final boolean forceResizable = Settings.Global.getInt(
12647                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12648        // Transfer any global setting for forcing RTL layout, into a System Property
12649        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12650
12651        final Configuration configuration = new Configuration();
12652        Settings.System.getConfiguration(resolver, configuration);
12653        if (forceRtl) {
12654            // This will take care of setting the correct layout direction flags
12655            configuration.setLayoutDirection(configuration.locale);
12656        }
12657
12658        synchronized (this) {
12659            mDebugApp = mOrigDebugApp = debugApp;
12660            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12661            mAlwaysFinishActivities = alwaysFinishActivities;
12662            mLenientBackgroundCheck = lenientBackgroundCheck;
12663            mForceResizableActivities = forceResizable;
12664            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12665            if (supportsMultiWindow || forceResizable) {
12666                mSupportsMultiWindow = true;
12667                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12668                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12669            } else {
12670                mSupportsMultiWindow = false;
12671                mSupportsFreeformWindowManagement = false;
12672                mSupportsPictureInPicture = false;
12673            }
12674            // This happens before any activities are started, so we can
12675            // change mConfiguration in-place.
12676            updateConfigurationLocked(configuration, null, true);
12677            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12678                    "Initial config: " + mConfiguration);
12679
12680            // Load resources only after the current configuration has been set.
12681            final Resources res = mContext.getResources();
12682            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12683            mThumbnailWidth = res.getDimensionPixelSize(
12684                    com.android.internal.R.dimen.thumbnail_width);
12685            mThumbnailHeight = res.getDimensionPixelSize(
12686                    com.android.internal.R.dimen.thumbnail_height);
12687            mFullscreenThumbnailScale = res.getFraction(
12688                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12689            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12690                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12691            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12692                    com.android.internal.R.string.config_appsNotReportingCrashes));
12693        }
12694    }
12695
12696    public boolean testIsSystemReady() {
12697        // no need to synchronize(this) just to read & return the value
12698        return mSystemReady;
12699    }
12700
12701    public void systemReady(final Runnable goingCallback) {
12702        synchronized(this) {
12703            if (mSystemReady) {
12704                // If we're done calling all the receivers, run the next "boot phase" passed in
12705                // by the SystemServer
12706                if (goingCallback != null) {
12707                    goingCallback.run();
12708                }
12709                return;
12710            }
12711
12712            mLocalDeviceIdleController
12713                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12714
12715            // Make sure we have the current profile info, since it is needed for security checks.
12716            mUserController.onSystemReady();
12717            mRecentTasks.onSystemReadyLocked();
12718            mAppOpsService.systemReady();
12719            mSystemReady = true;
12720        }
12721
12722        ArrayList<ProcessRecord> procsToKill = null;
12723        synchronized(mPidsSelfLocked) {
12724            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12725                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12726                if (!isAllowedWhileBooting(proc.info)){
12727                    if (procsToKill == null) {
12728                        procsToKill = new ArrayList<ProcessRecord>();
12729                    }
12730                    procsToKill.add(proc);
12731                }
12732            }
12733        }
12734
12735        synchronized(this) {
12736            if (procsToKill != null) {
12737                for (int i=procsToKill.size()-1; i>=0; i--) {
12738                    ProcessRecord proc = procsToKill.get(i);
12739                    Slog.i(TAG, "Removing system update proc: " + proc);
12740                    removeProcessLocked(proc, true, false, "system update done");
12741                }
12742            }
12743
12744            // Now that we have cleaned up any update processes, we
12745            // are ready to start launching real processes and know that
12746            // we won't trample on them any more.
12747            mProcessesReady = true;
12748        }
12749
12750        Slog.i(TAG, "System now ready");
12751        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12752            SystemClock.uptimeMillis());
12753
12754        synchronized(this) {
12755            // Make sure we have no pre-ready processes sitting around.
12756
12757            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12758                ResolveInfo ri = mContext.getPackageManager()
12759                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12760                                STOCK_PM_FLAGS);
12761                CharSequence errorMsg = null;
12762                if (ri != null) {
12763                    ActivityInfo ai = ri.activityInfo;
12764                    ApplicationInfo app = ai.applicationInfo;
12765                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12766                        mTopAction = Intent.ACTION_FACTORY_TEST;
12767                        mTopData = null;
12768                        mTopComponent = new ComponentName(app.packageName,
12769                                ai.name);
12770                    } else {
12771                        errorMsg = mContext.getResources().getText(
12772                                com.android.internal.R.string.factorytest_not_system);
12773                    }
12774                } else {
12775                    errorMsg = mContext.getResources().getText(
12776                            com.android.internal.R.string.factorytest_no_action);
12777                }
12778                if (errorMsg != null) {
12779                    mTopAction = null;
12780                    mTopData = null;
12781                    mTopComponent = null;
12782                    Message msg = Message.obtain();
12783                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12784                    msg.getData().putCharSequence("msg", errorMsg);
12785                    mUiHandler.sendMessage(msg);
12786                }
12787            }
12788        }
12789
12790        retrieveSettings();
12791        final int currentUserId;
12792        synchronized (this) {
12793            currentUserId = mUserController.getCurrentUserIdLocked();
12794            readGrantedUriPermissionsLocked();
12795        }
12796
12797        if (goingCallback != null) goingCallback.run();
12798
12799        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12800                Integer.toString(currentUserId), currentUserId);
12801        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12802                Integer.toString(currentUserId), currentUserId);
12803        mSystemServiceManager.startUser(currentUserId);
12804
12805        synchronized (this) {
12806            // Only start up encryption-aware persistent apps; once user is
12807            // unlocked we'll come back around and start unaware apps
12808            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12809
12810            // Start up initial activity.
12811            mBooting = true;
12812            // Enable home activity for system user, so that the system can always boot. We don't
12813            // do this when the system user is not setup since the setup wizard should be the one
12814            // to handle home activity in this case.
12815            if (UserManager.isSplitSystemUser() &&
12816                    Settings.Secure.getInt(mContext.getContentResolver(),
12817                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
12818                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12819                try {
12820                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12821                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12822                            UserHandle.USER_SYSTEM);
12823                } catch (RemoteException e) {
12824                    throw e.rethrowAsRuntimeException();
12825                }
12826            }
12827            startHomeActivityLocked(currentUserId, "systemReady");
12828
12829            try {
12830                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12831                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12832                            + " data partition or your device will be unstable.");
12833                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12834                }
12835            } catch (RemoteException e) {
12836            }
12837
12838            if (!Build.isBuildConsistent()) {
12839                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12840                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12841            }
12842
12843            long ident = Binder.clearCallingIdentity();
12844            try {
12845                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12846                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12847                        | Intent.FLAG_RECEIVER_FOREGROUND);
12848                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12849                broadcastIntentLocked(null, null, intent,
12850                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12851                        null, false, false, MY_PID, Process.SYSTEM_UID,
12852                        currentUserId);
12853                intent = new Intent(Intent.ACTION_USER_STARTING);
12854                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12855                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12856                broadcastIntentLocked(null, null, intent,
12857                        null, new IIntentReceiver.Stub() {
12858                            @Override
12859                            public void performReceive(Intent intent, int resultCode, String data,
12860                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12861                                    throws RemoteException {
12862                            }
12863                        }, 0, null, null,
12864                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12865                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12866            } catch (Throwable t) {
12867                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12868            } finally {
12869                Binder.restoreCallingIdentity(ident);
12870            }
12871            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12872            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12873        }
12874    }
12875
12876    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12877        synchronized (this) {
12878            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12879        }
12880    }
12881
12882    void skipCurrentReceiverLocked(ProcessRecord app) {
12883        for (BroadcastQueue queue : mBroadcastQueues) {
12884            queue.skipCurrentReceiverLocked(app);
12885        }
12886    }
12887
12888    /**
12889     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12890     * The application process will exit immediately after this call returns.
12891     * @param app object of the crashing app, null for the system server
12892     * @param crashInfo describing the exception
12893     */
12894    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12895        ProcessRecord r = findAppProcess(app, "Crash");
12896        final String processName = app == null ? "system_server"
12897                : (r == null ? "unknown" : r.processName);
12898
12899        handleApplicationCrashInner("crash", r, processName, crashInfo);
12900    }
12901
12902    /* Native crash reporting uses this inner version because it needs to be somewhat
12903     * decoupled from the AM-managed cleanup lifecycle
12904     */
12905    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12906            ApplicationErrorReport.CrashInfo crashInfo) {
12907        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12908                UserHandle.getUserId(Binder.getCallingUid()), processName,
12909                r == null ? -1 : r.info.flags,
12910                crashInfo.exceptionClassName,
12911                crashInfo.exceptionMessage,
12912                crashInfo.throwFileName,
12913                crashInfo.throwLineNumber);
12914
12915        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12916
12917        mAppErrors.crashApplication(r, crashInfo);
12918    }
12919
12920    public void handleApplicationStrictModeViolation(
12921            IBinder app,
12922            int violationMask,
12923            StrictMode.ViolationInfo info) {
12924        ProcessRecord r = findAppProcess(app, "StrictMode");
12925        if (r == null) {
12926            return;
12927        }
12928
12929        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12930            Integer stackFingerprint = info.hashCode();
12931            boolean logIt = true;
12932            synchronized (mAlreadyLoggedViolatedStacks) {
12933                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12934                    logIt = false;
12935                    // TODO: sub-sample into EventLog for these, with
12936                    // the info.durationMillis?  Then we'd get
12937                    // the relative pain numbers, without logging all
12938                    // the stack traces repeatedly.  We'd want to do
12939                    // likewise in the client code, which also does
12940                    // dup suppression, before the Binder call.
12941                } else {
12942                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12943                        mAlreadyLoggedViolatedStacks.clear();
12944                    }
12945                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12946                }
12947            }
12948            if (logIt) {
12949                logStrictModeViolationToDropBox(r, info);
12950            }
12951        }
12952
12953        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12954            AppErrorResult result = new AppErrorResult();
12955            synchronized (this) {
12956                final long origId = Binder.clearCallingIdentity();
12957
12958                Message msg = Message.obtain();
12959                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12960                HashMap<String, Object> data = new HashMap<String, Object>();
12961                data.put("result", result);
12962                data.put("app", r);
12963                data.put("violationMask", violationMask);
12964                data.put("info", info);
12965                msg.obj = data;
12966                mUiHandler.sendMessage(msg);
12967
12968                Binder.restoreCallingIdentity(origId);
12969            }
12970            int res = result.get();
12971            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12972        }
12973    }
12974
12975    // Depending on the policy in effect, there could be a bunch of
12976    // these in quick succession so we try to batch these together to
12977    // minimize disk writes, number of dropbox entries, and maximize
12978    // compression, by having more fewer, larger records.
12979    private void logStrictModeViolationToDropBox(
12980            ProcessRecord process,
12981            StrictMode.ViolationInfo info) {
12982        if (info == null) {
12983            return;
12984        }
12985        final boolean isSystemApp = process == null ||
12986                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12987                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12988        final String processName = process == null ? "unknown" : process.processName;
12989        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12990        final DropBoxManager dbox = (DropBoxManager)
12991                mContext.getSystemService(Context.DROPBOX_SERVICE);
12992
12993        // Exit early if the dropbox isn't configured to accept this report type.
12994        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12995
12996        boolean bufferWasEmpty;
12997        boolean needsFlush;
12998        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12999        synchronized (sb) {
13000            bufferWasEmpty = sb.length() == 0;
13001            appendDropBoxProcessHeaders(process, processName, sb);
13002            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13003            sb.append("System-App: ").append(isSystemApp).append("\n");
13004            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13005            if (info.violationNumThisLoop != 0) {
13006                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13007            }
13008            if (info.numAnimationsRunning != 0) {
13009                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13010            }
13011            if (info.broadcastIntentAction != null) {
13012                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13013            }
13014            if (info.durationMillis != -1) {
13015                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13016            }
13017            if (info.numInstances != -1) {
13018                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13019            }
13020            if (info.tags != null) {
13021                for (String tag : info.tags) {
13022                    sb.append("Span-Tag: ").append(tag).append("\n");
13023                }
13024            }
13025            sb.append("\n");
13026            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13027                sb.append(info.crashInfo.stackTrace);
13028                sb.append("\n");
13029            }
13030            if (info.message != null) {
13031                sb.append(info.message);
13032                sb.append("\n");
13033            }
13034
13035            // Only buffer up to ~64k.  Various logging bits truncate
13036            // things at 128k.
13037            needsFlush = (sb.length() > 64 * 1024);
13038        }
13039
13040        // Flush immediately if the buffer's grown too large, or this
13041        // is a non-system app.  Non-system apps are isolated with a
13042        // different tag & policy and not batched.
13043        //
13044        // Batching is useful during internal testing with
13045        // StrictMode settings turned up high.  Without batching,
13046        // thousands of separate files could be created on boot.
13047        if (!isSystemApp || needsFlush) {
13048            new Thread("Error dump: " + dropboxTag) {
13049                @Override
13050                public void run() {
13051                    String report;
13052                    synchronized (sb) {
13053                        report = sb.toString();
13054                        sb.delete(0, sb.length());
13055                        sb.trimToSize();
13056                    }
13057                    if (report.length() != 0) {
13058                        dbox.addText(dropboxTag, report);
13059                    }
13060                }
13061            }.start();
13062            return;
13063        }
13064
13065        // System app batching:
13066        if (!bufferWasEmpty) {
13067            // An existing dropbox-writing thread is outstanding, so
13068            // we don't need to start it up.  The existing thread will
13069            // catch the buffer appends we just did.
13070            return;
13071        }
13072
13073        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13074        // (After this point, we shouldn't access AMS internal data structures.)
13075        new Thread("Error dump: " + dropboxTag) {
13076            @Override
13077            public void run() {
13078                // 5 second sleep to let stacks arrive and be batched together
13079                try {
13080                    Thread.sleep(5000);  // 5 seconds
13081                } catch (InterruptedException e) {}
13082
13083                String errorReport;
13084                synchronized (mStrictModeBuffer) {
13085                    errorReport = mStrictModeBuffer.toString();
13086                    if (errorReport.length() == 0) {
13087                        return;
13088                    }
13089                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13090                    mStrictModeBuffer.trimToSize();
13091                }
13092                dbox.addText(dropboxTag, errorReport);
13093            }
13094        }.start();
13095    }
13096
13097    /**
13098     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13099     * @param app object of the crashing app, null for the system server
13100     * @param tag reported by the caller
13101     * @param system whether this wtf is coming from the system
13102     * @param crashInfo describing the context of the error
13103     * @return true if the process should exit immediately (WTF is fatal)
13104     */
13105    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13106            final ApplicationErrorReport.CrashInfo crashInfo) {
13107        final int callingUid = Binder.getCallingUid();
13108        final int callingPid = Binder.getCallingPid();
13109
13110        if (system) {
13111            // If this is coming from the system, we could very well have low-level
13112            // system locks held, so we want to do this all asynchronously.  And we
13113            // never want this to become fatal, so there is that too.
13114            mHandler.post(new Runnable() {
13115                @Override public void run() {
13116                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13117                }
13118            });
13119            return false;
13120        }
13121
13122        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13123                crashInfo);
13124
13125        if (r != null && r.pid != Process.myPid() &&
13126                Settings.Global.getInt(mContext.getContentResolver(),
13127                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13128            mAppErrors.crashApplication(r, crashInfo);
13129            return true;
13130        } else {
13131            return false;
13132        }
13133    }
13134
13135    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13136            final ApplicationErrorReport.CrashInfo crashInfo) {
13137        final ProcessRecord r = findAppProcess(app, "WTF");
13138        final String processName = app == null ? "system_server"
13139                : (r == null ? "unknown" : r.processName);
13140
13141        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13142                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13143
13144        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13145
13146        return r;
13147    }
13148
13149    /**
13150     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13151     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13152     */
13153    private ProcessRecord findAppProcess(IBinder app, String reason) {
13154        if (app == null) {
13155            return null;
13156        }
13157
13158        synchronized (this) {
13159            final int NP = mProcessNames.getMap().size();
13160            for (int ip=0; ip<NP; ip++) {
13161                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13162                final int NA = apps.size();
13163                for (int ia=0; ia<NA; ia++) {
13164                    ProcessRecord p = apps.valueAt(ia);
13165                    if (p.thread != null && p.thread.asBinder() == app) {
13166                        return p;
13167                    }
13168                }
13169            }
13170
13171            Slog.w(TAG, "Can't find mystery application for " + reason
13172                    + " from pid=" + Binder.getCallingPid()
13173                    + " uid=" + Binder.getCallingUid() + ": " + app);
13174            return null;
13175        }
13176    }
13177
13178    /**
13179     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13180     * to append various headers to the dropbox log text.
13181     */
13182    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13183            StringBuilder sb) {
13184        // Watchdog thread ends up invoking this function (with
13185        // a null ProcessRecord) to add the stack file to dropbox.
13186        // Do not acquire a lock on this (am) in such cases, as it
13187        // could cause a potential deadlock, if and when watchdog
13188        // is invoked due to unavailability of lock on am and it
13189        // would prevent watchdog from killing system_server.
13190        if (process == null) {
13191            sb.append("Process: ").append(processName).append("\n");
13192            return;
13193        }
13194        // Note: ProcessRecord 'process' is guarded by the service
13195        // instance.  (notably process.pkgList, which could otherwise change
13196        // concurrently during execution of this method)
13197        synchronized (this) {
13198            sb.append("Process: ").append(processName).append("\n");
13199            int flags = process.info.flags;
13200            IPackageManager pm = AppGlobals.getPackageManager();
13201            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13202            for (int ip=0; ip<process.pkgList.size(); ip++) {
13203                String pkg = process.pkgList.keyAt(ip);
13204                sb.append("Package: ").append(pkg);
13205                try {
13206                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13207                    if (pi != null) {
13208                        sb.append(" v").append(pi.versionCode);
13209                        if (pi.versionName != null) {
13210                            sb.append(" (").append(pi.versionName).append(")");
13211                        }
13212                    }
13213                } catch (RemoteException e) {
13214                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13215                }
13216                sb.append("\n");
13217            }
13218        }
13219    }
13220
13221    private static String processClass(ProcessRecord process) {
13222        if (process == null || process.pid == MY_PID) {
13223            return "system_server";
13224        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13225            return "system_app";
13226        } else {
13227            return "data_app";
13228        }
13229    }
13230
13231    private volatile long mWtfClusterStart;
13232    private volatile int mWtfClusterCount;
13233
13234    /**
13235     * Write a description of an error (crash, WTF, ANR) to the drop box.
13236     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13237     * @param process which caused the error, null means the system server
13238     * @param activity which triggered the error, null if unknown
13239     * @param parent activity related to the error, null if unknown
13240     * @param subject line related to the error, null if absent
13241     * @param report in long form describing the error, null if absent
13242     * @param logFile to include in the report, null if none
13243     * @param crashInfo giving an application stack trace, null if absent
13244     */
13245    public void addErrorToDropBox(String eventType,
13246            ProcessRecord process, String processName, ActivityRecord activity,
13247            ActivityRecord parent, String subject,
13248            final String report, final File logFile,
13249            final ApplicationErrorReport.CrashInfo crashInfo) {
13250        // NOTE -- this must never acquire the ActivityManagerService lock,
13251        // otherwise the watchdog may be prevented from resetting the system.
13252
13253        final String dropboxTag = processClass(process) + "_" + eventType;
13254        final DropBoxManager dbox = (DropBoxManager)
13255                mContext.getSystemService(Context.DROPBOX_SERVICE);
13256
13257        // Exit early if the dropbox isn't configured to accept this report type.
13258        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13259
13260        // Rate-limit how often we're willing to do the heavy lifting below to
13261        // collect and record logs; currently 5 logs per 10 second period.
13262        final long now = SystemClock.elapsedRealtime();
13263        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13264            mWtfClusterStart = now;
13265            mWtfClusterCount = 1;
13266        } else {
13267            if (mWtfClusterCount++ >= 5) return;
13268        }
13269
13270        final StringBuilder sb = new StringBuilder(1024);
13271        appendDropBoxProcessHeaders(process, processName, sb);
13272        if (process != null) {
13273            sb.append("Foreground: ")
13274                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13275                    .append("\n");
13276        }
13277        if (activity != null) {
13278            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13279        }
13280        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13281            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13282        }
13283        if (parent != null && parent != activity) {
13284            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13285        }
13286        if (subject != null) {
13287            sb.append("Subject: ").append(subject).append("\n");
13288        }
13289        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13290        if (Debug.isDebuggerConnected()) {
13291            sb.append("Debugger: Connected\n");
13292        }
13293        sb.append("\n");
13294
13295        // Do the rest in a worker thread to avoid blocking the caller on I/O
13296        // (After this point, we shouldn't access AMS internal data structures.)
13297        Thread worker = new Thread("Error dump: " + dropboxTag) {
13298            @Override
13299            public void run() {
13300                if (report != null) {
13301                    sb.append(report);
13302                }
13303                if (logFile != null) {
13304                    try {
13305                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13306                                    "\n\n[[TRUNCATED]]"));
13307                    } catch (IOException e) {
13308                        Slog.e(TAG, "Error reading " + logFile, e);
13309                    }
13310                }
13311                if (crashInfo != null && crashInfo.stackTrace != null) {
13312                    sb.append(crashInfo.stackTrace);
13313                }
13314
13315                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13316                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13317                if (lines > 0) {
13318                    sb.append("\n");
13319
13320                    // Merge several logcat streams, and take the last N lines
13321                    InputStreamReader input = null;
13322                    try {
13323                        java.lang.Process logcat = new ProcessBuilder(
13324                                "/system/bin/timeout", "-k", "15s", "10s",
13325                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13326                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13327                                        .redirectErrorStream(true).start();
13328
13329                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13330                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13331                        input = new InputStreamReader(logcat.getInputStream());
13332
13333                        int num;
13334                        char[] buf = new char[8192];
13335                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13336                    } catch (IOException e) {
13337                        Slog.e(TAG, "Error running logcat", e);
13338                    } finally {
13339                        if (input != null) try { input.close(); } catch (IOException e) {}
13340                    }
13341                }
13342
13343                dbox.addText(dropboxTag, sb.toString());
13344            }
13345        };
13346
13347        if (process == null) {
13348            // If process is null, we are being called from some internal code
13349            // and may be about to die -- run this synchronously.
13350            worker.run();
13351        } else {
13352            worker.start();
13353        }
13354    }
13355
13356    @Override
13357    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13358        enforceNotIsolatedCaller("getProcessesInErrorState");
13359        // assume our apps are happy - lazy create the list
13360        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13361
13362        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13363                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13364        int userId = UserHandle.getUserId(Binder.getCallingUid());
13365
13366        synchronized (this) {
13367
13368            // iterate across all processes
13369            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13370                ProcessRecord app = mLruProcesses.get(i);
13371                if (!allUsers && app.userId != userId) {
13372                    continue;
13373                }
13374                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13375                    // This one's in trouble, so we'll generate a report for it
13376                    // crashes are higher priority (in case there's a crash *and* an anr)
13377                    ActivityManager.ProcessErrorStateInfo report = null;
13378                    if (app.crashing) {
13379                        report = app.crashingReport;
13380                    } else if (app.notResponding) {
13381                        report = app.notRespondingReport;
13382                    }
13383
13384                    if (report != null) {
13385                        if (errList == null) {
13386                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13387                        }
13388                        errList.add(report);
13389                    } else {
13390                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13391                                " crashing = " + app.crashing +
13392                                " notResponding = " + app.notResponding);
13393                    }
13394                }
13395            }
13396        }
13397
13398        return errList;
13399    }
13400
13401    static int procStateToImportance(int procState, int memAdj,
13402            ActivityManager.RunningAppProcessInfo currApp) {
13403        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13404        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13405            currApp.lru = memAdj;
13406        } else {
13407            currApp.lru = 0;
13408        }
13409        return imp;
13410    }
13411
13412    private void fillInProcMemInfo(ProcessRecord app,
13413            ActivityManager.RunningAppProcessInfo outInfo) {
13414        outInfo.pid = app.pid;
13415        outInfo.uid = app.info.uid;
13416        if (mHeavyWeightProcess == app) {
13417            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13418        }
13419        if (app.persistent) {
13420            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13421        }
13422        if (app.activities.size() > 0) {
13423            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13424        }
13425        outInfo.lastTrimLevel = app.trimMemoryLevel;
13426        int adj = app.curAdj;
13427        int procState = app.curProcState;
13428        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13429        outInfo.importanceReasonCode = app.adjTypeCode;
13430        outInfo.processState = app.curProcState;
13431    }
13432
13433    @Override
13434    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13435        enforceNotIsolatedCaller("getRunningAppProcesses");
13436
13437        final int callingUid = Binder.getCallingUid();
13438
13439        // Lazy instantiation of list
13440        List<ActivityManager.RunningAppProcessInfo> runList = null;
13441        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13442                callingUid) == PackageManager.PERMISSION_GRANTED;
13443        final int userId = UserHandle.getUserId(callingUid);
13444        final boolean allUids = isGetTasksAllowed(
13445                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13446
13447        synchronized (this) {
13448            // Iterate across all processes
13449            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13450                ProcessRecord app = mLruProcesses.get(i);
13451                if ((!allUsers && app.userId != userId)
13452                        || (!allUids && app.uid != callingUid)) {
13453                    continue;
13454                }
13455                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13456                    // Generate process state info for running application
13457                    ActivityManager.RunningAppProcessInfo currApp =
13458                        new ActivityManager.RunningAppProcessInfo(app.processName,
13459                                app.pid, app.getPackageList());
13460                    fillInProcMemInfo(app, currApp);
13461                    if (app.adjSource instanceof ProcessRecord) {
13462                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13463                        currApp.importanceReasonImportance =
13464                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13465                                        app.adjSourceProcState);
13466                    } else if (app.adjSource instanceof ActivityRecord) {
13467                        ActivityRecord r = (ActivityRecord)app.adjSource;
13468                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13469                    }
13470                    if (app.adjTarget instanceof ComponentName) {
13471                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13472                    }
13473                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13474                    //        + " lru=" + currApp.lru);
13475                    if (runList == null) {
13476                        runList = new ArrayList<>();
13477                    }
13478                    runList.add(currApp);
13479                }
13480            }
13481        }
13482        return runList;
13483    }
13484
13485    @Override
13486    public List<ApplicationInfo> getRunningExternalApplications() {
13487        enforceNotIsolatedCaller("getRunningExternalApplications");
13488        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13489        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13490        if (runningApps != null && runningApps.size() > 0) {
13491            Set<String> extList = new HashSet<String>();
13492            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13493                if (app.pkgList != null) {
13494                    for (String pkg : app.pkgList) {
13495                        extList.add(pkg);
13496                    }
13497                }
13498            }
13499            IPackageManager pm = AppGlobals.getPackageManager();
13500            for (String pkg : extList) {
13501                try {
13502                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13503                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13504                        retList.add(info);
13505                    }
13506                } catch (RemoteException e) {
13507                }
13508            }
13509        }
13510        return retList;
13511    }
13512
13513    @Override
13514    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13515        enforceNotIsolatedCaller("getMyMemoryState");
13516        synchronized (this) {
13517            ProcessRecord proc;
13518            synchronized (mPidsSelfLocked) {
13519                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13520            }
13521            fillInProcMemInfo(proc, outInfo);
13522        }
13523    }
13524
13525    @Override
13526    public int getMemoryTrimLevel() {
13527        enforceNotIsolatedCaller("getMyMemoryState");
13528        synchronized (this) {
13529            return mLastMemoryLevel;
13530        }
13531    }
13532
13533    @Override
13534    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13535            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13536        (new ActivityManagerShellCommand(this, false)).exec(
13537                this, in, out, err, args, resultReceiver);
13538    }
13539
13540    @Override
13541    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13542        if (checkCallingPermission(android.Manifest.permission.DUMP)
13543                != PackageManager.PERMISSION_GRANTED) {
13544            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13545                    + Binder.getCallingPid()
13546                    + ", uid=" + Binder.getCallingUid()
13547                    + " without permission "
13548                    + android.Manifest.permission.DUMP);
13549            return;
13550        }
13551
13552        boolean dumpAll = false;
13553        boolean dumpClient = false;
13554        String dumpPackage = null;
13555
13556        int opti = 0;
13557        while (opti < args.length) {
13558            String opt = args[opti];
13559            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13560                break;
13561            }
13562            opti++;
13563            if ("-a".equals(opt)) {
13564                dumpAll = true;
13565            } else if ("-c".equals(opt)) {
13566                dumpClient = true;
13567            } else if ("-p".equals(opt)) {
13568                if (opti < args.length) {
13569                    dumpPackage = args[opti];
13570                    opti++;
13571                } else {
13572                    pw.println("Error: -p option requires package argument");
13573                    return;
13574                }
13575                dumpClient = true;
13576            } else if ("-h".equals(opt)) {
13577                ActivityManagerShellCommand.dumpHelp(pw, true);
13578                return;
13579            } else {
13580                pw.println("Unknown argument: " + opt + "; use -h for help");
13581            }
13582        }
13583
13584        long origId = Binder.clearCallingIdentity();
13585        boolean more = false;
13586        // Is the caller requesting to dump a particular piece of data?
13587        if (opti < args.length) {
13588            String cmd = args[opti];
13589            opti++;
13590            if ("activities".equals(cmd) || "a".equals(cmd)) {
13591                synchronized (this) {
13592                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13593                }
13594            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13595                synchronized (this) {
13596                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13597                }
13598            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13599                String[] newArgs;
13600                String name;
13601                if (opti >= args.length) {
13602                    name = null;
13603                    newArgs = EMPTY_STRING_ARRAY;
13604                } else {
13605                    dumpPackage = args[opti];
13606                    opti++;
13607                    newArgs = new String[args.length - opti];
13608                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13609                            args.length - opti);
13610                }
13611                synchronized (this) {
13612                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13613                }
13614            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13615                String[] newArgs;
13616                String name;
13617                if (opti >= args.length) {
13618                    name = null;
13619                    newArgs = EMPTY_STRING_ARRAY;
13620                } else {
13621                    dumpPackage = args[opti];
13622                    opti++;
13623                    newArgs = new String[args.length - opti];
13624                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13625                            args.length - opti);
13626                }
13627                synchronized (this) {
13628                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13629                }
13630            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13631                String[] newArgs;
13632                String name;
13633                if (opti >= args.length) {
13634                    name = null;
13635                    newArgs = EMPTY_STRING_ARRAY;
13636                } else {
13637                    dumpPackage = args[opti];
13638                    opti++;
13639                    newArgs = new String[args.length - opti];
13640                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13641                            args.length - opti);
13642                }
13643                synchronized (this) {
13644                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13645                }
13646            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13647                synchronized (this) {
13648                    dumpOomLocked(fd, pw, args, opti, true);
13649                }
13650            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13651                synchronized (this) {
13652                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13653                }
13654            } else if ("provider".equals(cmd)) {
13655                String[] newArgs;
13656                String name;
13657                if (opti >= args.length) {
13658                    name = null;
13659                    newArgs = EMPTY_STRING_ARRAY;
13660                } else {
13661                    name = args[opti];
13662                    opti++;
13663                    newArgs = new String[args.length - opti];
13664                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13665                }
13666                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13667                    pw.println("No providers match: " + name);
13668                    pw.println("Use -h for help.");
13669                }
13670            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13671                synchronized (this) {
13672                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13673                }
13674            } else if ("service".equals(cmd)) {
13675                String[] newArgs;
13676                String name;
13677                if (opti >= args.length) {
13678                    name = null;
13679                    newArgs = EMPTY_STRING_ARRAY;
13680                } else {
13681                    name = args[opti];
13682                    opti++;
13683                    newArgs = new String[args.length - opti];
13684                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13685                            args.length - opti);
13686                }
13687                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13688                    pw.println("No services match: " + name);
13689                    pw.println("Use -h for help.");
13690                }
13691            } else if ("package".equals(cmd)) {
13692                String[] newArgs;
13693                if (opti >= args.length) {
13694                    pw.println("package: no package name specified");
13695                    pw.println("Use -h for help.");
13696                } else {
13697                    dumpPackage = args[opti];
13698                    opti++;
13699                    newArgs = new String[args.length - opti];
13700                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13701                            args.length - opti);
13702                    args = newArgs;
13703                    opti = 0;
13704                    more = true;
13705                }
13706            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13707                synchronized (this) {
13708                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13709                }
13710            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13711                synchronized (this) {
13712                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13713                }
13714            } else if ("locks".equals(cmd)) {
13715                LockGuard.dump(fd, pw, args);
13716            } else {
13717                // Dumping a single activity?
13718                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13719                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13720                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13721                    if (res < 0) {
13722                        pw.println("Bad activity command, or no activities match: " + cmd);
13723                        pw.println("Use -h for help.");
13724                    }
13725                }
13726            }
13727            if (!more) {
13728                Binder.restoreCallingIdentity(origId);
13729                return;
13730            }
13731        }
13732
13733        // No piece of data specified, dump everything.
13734        synchronized (this) {
13735            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13736            pw.println();
13737            if (dumpAll) {
13738                pw.println("-------------------------------------------------------------------------------");
13739            }
13740            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13741            pw.println();
13742            if (dumpAll) {
13743                pw.println("-------------------------------------------------------------------------------");
13744            }
13745            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13746            pw.println();
13747            if (dumpAll) {
13748                pw.println("-------------------------------------------------------------------------------");
13749            }
13750            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13751            pw.println();
13752            if (dumpAll) {
13753                pw.println("-------------------------------------------------------------------------------");
13754            }
13755            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13756            pw.println();
13757            if (dumpAll) {
13758                pw.println("-------------------------------------------------------------------------------");
13759            }
13760            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13761            pw.println();
13762            if (dumpAll) {
13763                pw.println("-------------------------------------------------------------------------------");
13764            }
13765            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13766            if (mAssociations.size() > 0) {
13767                pw.println();
13768                if (dumpAll) {
13769                    pw.println("-------------------------------------------------------------------------------");
13770                }
13771                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13772            }
13773            pw.println();
13774            if (dumpAll) {
13775                pw.println("-------------------------------------------------------------------------------");
13776            }
13777            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13778        }
13779        Binder.restoreCallingIdentity(origId);
13780    }
13781
13782    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13783            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13784        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13785
13786        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13787                dumpPackage);
13788        boolean needSep = printedAnything;
13789
13790        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13791                dumpPackage, needSep, "  mFocusedActivity: ");
13792        if (printed) {
13793            printedAnything = true;
13794            needSep = false;
13795        }
13796
13797        if (dumpPackage == null) {
13798            if (needSep) {
13799                pw.println();
13800            }
13801            needSep = true;
13802            printedAnything = true;
13803            mStackSupervisor.dump(pw, "  ");
13804        }
13805
13806        if (!printedAnything) {
13807            pw.println("  (nothing)");
13808        }
13809    }
13810
13811    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13812            int opti, boolean dumpAll, String dumpPackage) {
13813        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13814
13815        boolean printedAnything = false;
13816
13817        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13818            boolean printedHeader = false;
13819
13820            final int N = mRecentTasks.size();
13821            for (int i=0; i<N; i++) {
13822                TaskRecord tr = mRecentTasks.get(i);
13823                if (dumpPackage != null) {
13824                    if (tr.realActivity == null ||
13825                            !dumpPackage.equals(tr.realActivity)) {
13826                        continue;
13827                    }
13828                }
13829                if (!printedHeader) {
13830                    pw.println("  Recent tasks:");
13831                    printedHeader = true;
13832                    printedAnything = true;
13833                }
13834                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13835                        pw.println(tr);
13836                if (dumpAll) {
13837                    mRecentTasks.get(i).dump(pw, "    ");
13838                }
13839            }
13840        }
13841
13842        if (!printedAnything) {
13843            pw.println("  (nothing)");
13844        }
13845    }
13846
13847    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13848            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13849        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13850
13851        int dumpUid = 0;
13852        if (dumpPackage != null) {
13853            IPackageManager pm = AppGlobals.getPackageManager();
13854            try {
13855                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13856            } catch (RemoteException e) {
13857            }
13858        }
13859
13860        boolean printedAnything = false;
13861
13862        final long now = SystemClock.uptimeMillis();
13863
13864        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13865            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13866                    = mAssociations.valueAt(i1);
13867            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13868                SparseArray<ArrayMap<String, Association>> sourceUids
13869                        = targetComponents.valueAt(i2);
13870                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13871                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13872                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13873                        Association ass = sourceProcesses.valueAt(i4);
13874                        if (dumpPackage != null) {
13875                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13876                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13877                                continue;
13878                            }
13879                        }
13880                        printedAnything = true;
13881                        pw.print("  ");
13882                        pw.print(ass.mTargetProcess);
13883                        pw.print("/");
13884                        UserHandle.formatUid(pw, ass.mTargetUid);
13885                        pw.print(" <- ");
13886                        pw.print(ass.mSourceProcess);
13887                        pw.print("/");
13888                        UserHandle.formatUid(pw, ass.mSourceUid);
13889                        pw.println();
13890                        pw.print("    via ");
13891                        pw.print(ass.mTargetComponent.flattenToShortString());
13892                        pw.println();
13893                        pw.print("    ");
13894                        long dur = ass.mTime;
13895                        if (ass.mNesting > 0) {
13896                            dur += now - ass.mStartTime;
13897                        }
13898                        TimeUtils.formatDuration(dur, pw);
13899                        pw.print(" (");
13900                        pw.print(ass.mCount);
13901                        pw.print(" times)");
13902                        pw.print("  ");
13903                        for (int i=0; i<ass.mStateTimes.length; i++) {
13904                            long amt = ass.mStateTimes[i];
13905                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13906                                amt += now - ass.mLastStateUptime;
13907                            }
13908                            if (amt != 0) {
13909                                pw.print(" ");
13910                                pw.print(ProcessList.makeProcStateString(
13911                                            i + ActivityManager.MIN_PROCESS_STATE));
13912                                pw.print("=");
13913                                TimeUtils.formatDuration(amt, pw);
13914                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13915                                    pw.print("*");
13916                                }
13917                            }
13918                        }
13919                        pw.println();
13920                        if (ass.mNesting > 0) {
13921                            pw.print("    Currently active: ");
13922                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13923                            pw.println();
13924                        }
13925                    }
13926                }
13927            }
13928
13929        }
13930
13931        if (!printedAnything) {
13932            pw.println("  (nothing)");
13933        }
13934    }
13935
13936    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13937            String header, boolean needSep) {
13938        boolean printed = false;
13939        int whichAppId = -1;
13940        if (dumpPackage != null) {
13941            try {
13942                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13943                        dumpPackage, 0);
13944                whichAppId = UserHandle.getAppId(info.uid);
13945            } catch (NameNotFoundException e) {
13946                e.printStackTrace();
13947            }
13948        }
13949        for (int i=0; i<uids.size(); i++) {
13950            UidRecord uidRec = uids.valueAt(i);
13951            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13952                continue;
13953            }
13954            if (!printed) {
13955                printed = true;
13956                if (needSep) {
13957                    pw.println();
13958                }
13959                pw.print("  ");
13960                pw.println(header);
13961                needSep = true;
13962            }
13963            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13964            pw.print(": "); pw.println(uidRec);
13965        }
13966        return printed;
13967    }
13968
13969    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13970            int opti, boolean dumpAll, String dumpPackage) {
13971        boolean needSep = false;
13972        boolean printedAnything = false;
13973        int numPers = 0;
13974
13975        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13976
13977        if (dumpAll) {
13978            final int NP = mProcessNames.getMap().size();
13979            for (int ip=0; ip<NP; ip++) {
13980                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13981                final int NA = procs.size();
13982                for (int ia=0; ia<NA; ia++) {
13983                    ProcessRecord r = procs.valueAt(ia);
13984                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13985                        continue;
13986                    }
13987                    if (!needSep) {
13988                        pw.println("  All known processes:");
13989                        needSep = true;
13990                        printedAnything = true;
13991                    }
13992                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13993                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13994                        pw.print(" "); pw.println(r);
13995                    r.dump(pw, "    ");
13996                    if (r.persistent) {
13997                        numPers++;
13998                    }
13999                }
14000            }
14001        }
14002
14003        if (mIsolatedProcesses.size() > 0) {
14004            boolean printed = false;
14005            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14006                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14007                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14008                    continue;
14009                }
14010                if (!printed) {
14011                    if (needSep) {
14012                        pw.println();
14013                    }
14014                    pw.println("  Isolated process list (sorted by uid):");
14015                    printedAnything = true;
14016                    printed = true;
14017                    needSep = true;
14018                }
14019                pw.println(String.format("%sIsolated #%2d: %s",
14020                        "    ", i, r.toString()));
14021            }
14022        }
14023
14024        if (mActiveUids.size() > 0) {
14025            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14026                printedAnything = needSep = true;
14027            }
14028        }
14029        if (mValidateUids.size() > 0) {
14030            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14031                printedAnything = needSep = true;
14032            }
14033        }
14034
14035        if (mLruProcesses.size() > 0) {
14036            if (needSep) {
14037                pw.println();
14038            }
14039            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14040                    pw.print(" total, non-act at ");
14041                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14042                    pw.print(", non-svc at ");
14043                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14044                    pw.println("):");
14045            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14046            needSep = true;
14047            printedAnything = true;
14048        }
14049
14050        if (dumpAll || dumpPackage != null) {
14051            synchronized (mPidsSelfLocked) {
14052                boolean printed = false;
14053                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14054                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14055                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14056                        continue;
14057                    }
14058                    if (!printed) {
14059                        if (needSep) pw.println();
14060                        needSep = true;
14061                        pw.println("  PID mappings:");
14062                        printed = true;
14063                        printedAnything = true;
14064                    }
14065                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14066                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14067                }
14068            }
14069        }
14070
14071        if (mForegroundProcesses.size() > 0) {
14072            synchronized (mPidsSelfLocked) {
14073                boolean printed = false;
14074                for (int i=0; i<mForegroundProcesses.size(); i++) {
14075                    ProcessRecord r = mPidsSelfLocked.get(
14076                            mForegroundProcesses.valueAt(i).pid);
14077                    if (dumpPackage != null && (r == null
14078                            || !r.pkgList.containsKey(dumpPackage))) {
14079                        continue;
14080                    }
14081                    if (!printed) {
14082                        if (needSep) pw.println();
14083                        needSep = true;
14084                        pw.println("  Foreground Processes:");
14085                        printed = true;
14086                        printedAnything = true;
14087                    }
14088                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14089                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14090                }
14091            }
14092        }
14093
14094        if (mPersistentStartingProcesses.size() > 0) {
14095            if (needSep) pw.println();
14096            needSep = true;
14097            printedAnything = true;
14098            pw.println("  Persisent processes that are starting:");
14099            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14100                    "Starting Norm", "Restarting PERS", dumpPackage);
14101        }
14102
14103        if (mRemovedProcesses.size() > 0) {
14104            if (needSep) pw.println();
14105            needSep = true;
14106            printedAnything = true;
14107            pw.println("  Processes that are being removed:");
14108            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14109                    "Removed Norm", "Removed PERS", dumpPackage);
14110        }
14111
14112        if (mProcessesOnHold.size() > 0) {
14113            if (needSep) pw.println();
14114            needSep = true;
14115            printedAnything = true;
14116            pw.println("  Processes that are on old until the system is ready:");
14117            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14118                    "OnHold Norm", "OnHold PERS", dumpPackage);
14119        }
14120
14121        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14122
14123        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14124        if (needSep) {
14125            printedAnything = true;
14126        }
14127
14128        if (dumpPackage == null) {
14129            pw.println();
14130            needSep = false;
14131            mUserController.dump(pw, dumpAll);
14132        }
14133        if (mHomeProcess != null && (dumpPackage == null
14134                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14135            if (needSep) {
14136                pw.println();
14137                needSep = false;
14138            }
14139            pw.println("  mHomeProcess: " + mHomeProcess);
14140        }
14141        if (mPreviousProcess != null && (dumpPackage == null
14142                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14143            if (needSep) {
14144                pw.println();
14145                needSep = false;
14146            }
14147            pw.println("  mPreviousProcess: " + mPreviousProcess);
14148        }
14149        if (dumpAll) {
14150            StringBuilder sb = new StringBuilder(128);
14151            sb.append("  mPreviousProcessVisibleTime: ");
14152            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14153            pw.println(sb);
14154        }
14155        if (mHeavyWeightProcess != null && (dumpPackage == null
14156                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14157            if (needSep) {
14158                pw.println();
14159                needSep = false;
14160            }
14161            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14162        }
14163        if (dumpPackage == null) {
14164            pw.println("  mConfiguration: " + mConfiguration);
14165        }
14166        if (dumpAll) {
14167            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14168            if (mCompatModePackages.getPackages().size() > 0) {
14169                boolean printed = false;
14170                for (Map.Entry<String, Integer> entry
14171                        : mCompatModePackages.getPackages().entrySet()) {
14172                    String pkg = entry.getKey();
14173                    int mode = entry.getValue();
14174                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14175                        continue;
14176                    }
14177                    if (!printed) {
14178                        pw.println("  mScreenCompatPackages:");
14179                        printed = true;
14180                    }
14181                    pw.print("    "); pw.print(pkg); pw.print(": ");
14182                            pw.print(mode); pw.println();
14183                }
14184            }
14185        }
14186        if (dumpPackage == null) {
14187            pw.println("  mWakefulness="
14188                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14189            pw.println("  mSleepTokens=" + mSleepTokens);
14190            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14191                    + lockScreenShownToString());
14192            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14193            if (mRunningVoice != null) {
14194                pw.println("  mRunningVoice=" + mRunningVoice);
14195                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14196            }
14197        }
14198        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14199                || mOrigWaitForDebugger) {
14200            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14201                    || dumpPackage.equals(mOrigDebugApp)) {
14202                if (needSep) {
14203                    pw.println();
14204                    needSep = false;
14205                }
14206                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14207                        + " mDebugTransient=" + mDebugTransient
14208                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14209            }
14210        }
14211        if (mCurAppTimeTracker != null) {
14212            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14213        }
14214        if (mMemWatchProcesses.getMap().size() > 0) {
14215            pw.println("  Mem watch processes:");
14216            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14217                    = mMemWatchProcesses.getMap();
14218            for (int i=0; i<procs.size(); i++) {
14219                final String proc = procs.keyAt(i);
14220                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14221                for (int j=0; j<uids.size(); j++) {
14222                    if (needSep) {
14223                        pw.println();
14224                        needSep = false;
14225                    }
14226                    StringBuilder sb = new StringBuilder();
14227                    sb.append("    ").append(proc).append('/');
14228                    UserHandle.formatUid(sb, uids.keyAt(j));
14229                    Pair<Long, String> val = uids.valueAt(j);
14230                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14231                    if (val.second != null) {
14232                        sb.append(", report to ").append(val.second);
14233                    }
14234                    pw.println(sb.toString());
14235                }
14236            }
14237            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14238            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14239            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14240                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14241        }
14242        if (mTrackAllocationApp != null) {
14243            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14244                if (needSep) {
14245                    pw.println();
14246                    needSep = false;
14247                }
14248                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14249            }
14250        }
14251        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14252                || mProfileFd != null) {
14253            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14254                if (needSep) {
14255                    pw.println();
14256                    needSep = false;
14257                }
14258                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14259                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14260                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14261                        + mAutoStopProfiler);
14262                pw.println("  mProfileType=" + mProfileType);
14263            }
14264        }
14265        if (mNativeDebuggingApp != null) {
14266            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14267                if (needSep) {
14268                    pw.println();
14269                    needSep = false;
14270                }
14271                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14272            }
14273        }
14274        if (dumpPackage == null) {
14275            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14276                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14277                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14278            }
14279            if (mController != null) {
14280                pw.println("  mController=" + mController
14281                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14282            }
14283            if (dumpAll) {
14284                pw.println("  Total persistent processes: " + numPers);
14285                pw.println("  mProcessesReady=" + mProcessesReady
14286                        + " mSystemReady=" + mSystemReady
14287                        + " mBooted=" + mBooted
14288                        + " mFactoryTest=" + mFactoryTest);
14289                pw.println("  mBooting=" + mBooting
14290                        + " mCallFinishBooting=" + mCallFinishBooting
14291                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14292                pw.print("  mLastPowerCheckRealtime=");
14293                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14294                        pw.println("");
14295                pw.print("  mLastPowerCheckUptime=");
14296                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14297                        pw.println("");
14298                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14299                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14300                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14301                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14302                        + " (" + mLruProcesses.size() + " total)"
14303                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14304                        + " mNumServiceProcs=" + mNumServiceProcs
14305                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14306                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14307                        + " mLastMemoryLevel=" + mLastMemoryLevel
14308                        + " mLastNumProcesses=" + mLastNumProcesses);
14309                long now = SystemClock.uptimeMillis();
14310                pw.print("  mLastIdleTime=");
14311                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14312                        pw.print(" mLowRamSinceLastIdle=");
14313                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14314                        pw.println();
14315            }
14316        }
14317
14318        if (!printedAnything) {
14319            pw.println("  (nothing)");
14320        }
14321    }
14322
14323    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14324            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14325        if (mProcessesToGc.size() > 0) {
14326            boolean printed = false;
14327            long now = SystemClock.uptimeMillis();
14328            for (int i=0; i<mProcessesToGc.size(); i++) {
14329                ProcessRecord proc = mProcessesToGc.get(i);
14330                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14331                    continue;
14332                }
14333                if (!printed) {
14334                    if (needSep) pw.println();
14335                    needSep = true;
14336                    pw.println("  Processes that are waiting to GC:");
14337                    printed = true;
14338                }
14339                pw.print("    Process "); pw.println(proc);
14340                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14341                        pw.print(", last gced=");
14342                        pw.print(now-proc.lastRequestedGc);
14343                        pw.print(" ms ago, last lowMem=");
14344                        pw.print(now-proc.lastLowMemory);
14345                        pw.println(" ms ago");
14346
14347            }
14348        }
14349        return needSep;
14350    }
14351
14352    void printOomLevel(PrintWriter pw, String name, int adj) {
14353        pw.print("    ");
14354        if (adj >= 0) {
14355            pw.print(' ');
14356            if (adj < 10) pw.print(' ');
14357        } else {
14358            if (adj > -10) pw.print(' ');
14359        }
14360        pw.print(adj);
14361        pw.print(": ");
14362        pw.print(name);
14363        pw.print(" (");
14364        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14365        pw.println(")");
14366    }
14367
14368    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14369            int opti, boolean dumpAll) {
14370        boolean needSep = false;
14371
14372        if (mLruProcesses.size() > 0) {
14373            if (needSep) pw.println();
14374            needSep = true;
14375            pw.println("  OOM levels:");
14376            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14377            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14378            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14379            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14380            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14381            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14382            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14383            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14384            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14385            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14386            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14387            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14388            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14389            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14390
14391            if (needSep) pw.println();
14392            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14393                    pw.print(" total, non-act at ");
14394                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14395                    pw.print(", non-svc at ");
14396                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14397                    pw.println("):");
14398            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14399            needSep = true;
14400        }
14401
14402        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14403
14404        pw.println();
14405        pw.println("  mHomeProcess: " + mHomeProcess);
14406        pw.println("  mPreviousProcess: " + mPreviousProcess);
14407        if (mHeavyWeightProcess != null) {
14408            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14409        }
14410
14411        return true;
14412    }
14413
14414    /**
14415     * There are three ways to call this:
14416     *  - no provider specified: dump all the providers
14417     *  - a flattened component name that matched an existing provider was specified as the
14418     *    first arg: dump that one provider
14419     *  - the first arg isn't the flattened component name of an existing provider:
14420     *    dump all providers whose component contains the first arg as a substring
14421     */
14422    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14423            int opti, boolean dumpAll) {
14424        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14425    }
14426
14427    static class ItemMatcher {
14428        ArrayList<ComponentName> components;
14429        ArrayList<String> strings;
14430        ArrayList<Integer> objects;
14431        boolean all;
14432
14433        ItemMatcher() {
14434            all = true;
14435        }
14436
14437        void build(String name) {
14438            ComponentName componentName = ComponentName.unflattenFromString(name);
14439            if (componentName != null) {
14440                if (components == null) {
14441                    components = new ArrayList<ComponentName>();
14442                }
14443                components.add(componentName);
14444                all = false;
14445            } else {
14446                int objectId = 0;
14447                // Not a '/' separated full component name; maybe an object ID?
14448                try {
14449                    objectId = Integer.parseInt(name, 16);
14450                    if (objects == null) {
14451                        objects = new ArrayList<Integer>();
14452                    }
14453                    objects.add(objectId);
14454                    all = false;
14455                } catch (RuntimeException e) {
14456                    // Not an integer; just do string match.
14457                    if (strings == null) {
14458                        strings = new ArrayList<String>();
14459                    }
14460                    strings.add(name);
14461                    all = false;
14462                }
14463            }
14464        }
14465
14466        int build(String[] args, int opti) {
14467            for (; opti<args.length; opti++) {
14468                String name = args[opti];
14469                if ("--".equals(name)) {
14470                    return opti+1;
14471                }
14472                build(name);
14473            }
14474            return opti;
14475        }
14476
14477        boolean match(Object object, ComponentName comp) {
14478            if (all) {
14479                return true;
14480            }
14481            if (components != null) {
14482                for (int i=0; i<components.size(); i++) {
14483                    if (components.get(i).equals(comp)) {
14484                        return true;
14485                    }
14486                }
14487            }
14488            if (objects != null) {
14489                for (int i=0; i<objects.size(); i++) {
14490                    if (System.identityHashCode(object) == objects.get(i)) {
14491                        return true;
14492                    }
14493                }
14494            }
14495            if (strings != null) {
14496                String flat = comp.flattenToString();
14497                for (int i=0; i<strings.size(); i++) {
14498                    if (flat.contains(strings.get(i))) {
14499                        return true;
14500                    }
14501                }
14502            }
14503            return false;
14504        }
14505    }
14506
14507    /**
14508     * There are three things that cmd can be:
14509     *  - a flattened component name that matches an existing activity
14510     *  - the cmd arg isn't the flattened component name of an existing activity:
14511     *    dump all activity whose component contains the cmd as a substring
14512     *  - A hex number of the ActivityRecord object instance.
14513     */
14514    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14515            int opti, boolean dumpAll) {
14516        ArrayList<ActivityRecord> activities;
14517
14518        synchronized (this) {
14519            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14520        }
14521
14522        if (activities.size() <= 0) {
14523            return false;
14524        }
14525
14526        String[] newArgs = new String[args.length - opti];
14527        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14528
14529        TaskRecord lastTask = null;
14530        boolean needSep = false;
14531        for (int i=activities.size()-1; i>=0; i--) {
14532            ActivityRecord r = activities.get(i);
14533            if (needSep) {
14534                pw.println();
14535            }
14536            needSep = true;
14537            synchronized (this) {
14538                if (lastTask != r.task) {
14539                    lastTask = r.task;
14540                    pw.print("TASK "); pw.print(lastTask.affinity);
14541                            pw.print(" id="); pw.println(lastTask.taskId);
14542                    if (dumpAll) {
14543                        lastTask.dump(pw, "  ");
14544                    }
14545                }
14546            }
14547            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14548        }
14549        return true;
14550    }
14551
14552    /**
14553     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14554     * there is a thread associated with the activity.
14555     */
14556    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14557            final ActivityRecord r, String[] args, boolean dumpAll) {
14558        String innerPrefix = prefix + "  ";
14559        synchronized (this) {
14560            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14561                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14562                    pw.print(" pid=");
14563                    if (r.app != null) pw.println(r.app.pid);
14564                    else pw.println("(not running)");
14565            if (dumpAll) {
14566                r.dump(pw, innerPrefix);
14567            }
14568        }
14569        if (r.app != null && r.app.thread != null) {
14570            // flush anything that is already in the PrintWriter since the thread is going
14571            // to write to the file descriptor directly
14572            pw.flush();
14573            try {
14574                TransferPipe tp = new TransferPipe();
14575                try {
14576                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14577                            r.appToken, innerPrefix, args);
14578                    tp.go(fd);
14579                } finally {
14580                    tp.kill();
14581                }
14582            } catch (IOException e) {
14583                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14584            } catch (RemoteException e) {
14585                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14586            }
14587        }
14588    }
14589
14590    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14591            int opti, boolean dumpAll, String dumpPackage) {
14592        boolean needSep = false;
14593        boolean onlyHistory = false;
14594        boolean printedAnything = false;
14595
14596        if ("history".equals(dumpPackage)) {
14597            if (opti < args.length && "-s".equals(args[opti])) {
14598                dumpAll = false;
14599            }
14600            onlyHistory = true;
14601            dumpPackage = null;
14602        }
14603
14604        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14605        if (!onlyHistory && dumpAll) {
14606            if (mRegisteredReceivers.size() > 0) {
14607                boolean printed = false;
14608                Iterator it = mRegisteredReceivers.values().iterator();
14609                while (it.hasNext()) {
14610                    ReceiverList r = (ReceiverList)it.next();
14611                    if (dumpPackage != null && (r.app == null ||
14612                            !dumpPackage.equals(r.app.info.packageName))) {
14613                        continue;
14614                    }
14615                    if (!printed) {
14616                        pw.println("  Registered Receivers:");
14617                        needSep = true;
14618                        printed = true;
14619                        printedAnything = true;
14620                    }
14621                    pw.print("  * "); pw.println(r);
14622                    r.dump(pw, "    ");
14623                }
14624            }
14625
14626            if (mReceiverResolver.dump(pw, needSep ?
14627                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14628                    "    ", dumpPackage, false, false)) {
14629                needSep = true;
14630                printedAnything = true;
14631            }
14632        }
14633
14634        for (BroadcastQueue q : mBroadcastQueues) {
14635            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14636            printedAnything |= needSep;
14637        }
14638
14639        needSep = true;
14640
14641        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14642            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14643                if (needSep) {
14644                    pw.println();
14645                }
14646                needSep = true;
14647                printedAnything = true;
14648                pw.print("  Sticky broadcasts for user ");
14649                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14650                StringBuilder sb = new StringBuilder(128);
14651                for (Map.Entry<String, ArrayList<Intent>> ent
14652                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14653                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14654                    if (dumpAll) {
14655                        pw.println(":");
14656                        ArrayList<Intent> intents = ent.getValue();
14657                        final int N = intents.size();
14658                        for (int i=0; i<N; i++) {
14659                            sb.setLength(0);
14660                            sb.append("    Intent: ");
14661                            intents.get(i).toShortString(sb, false, true, false, false);
14662                            pw.println(sb.toString());
14663                            Bundle bundle = intents.get(i).getExtras();
14664                            if (bundle != null) {
14665                                pw.print("      ");
14666                                pw.println(bundle.toString());
14667                            }
14668                        }
14669                    } else {
14670                        pw.println("");
14671                    }
14672                }
14673            }
14674        }
14675
14676        if (!onlyHistory && dumpAll) {
14677            pw.println();
14678            for (BroadcastQueue queue : mBroadcastQueues) {
14679                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14680                        + queue.mBroadcastsScheduled);
14681            }
14682            pw.println("  mHandler:");
14683            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14684            needSep = true;
14685            printedAnything = true;
14686        }
14687
14688        if (!printedAnything) {
14689            pw.println("  (nothing)");
14690        }
14691    }
14692
14693    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14694            int opti, boolean dumpAll, String dumpPackage) {
14695        boolean needSep;
14696        boolean printedAnything = false;
14697
14698        ItemMatcher matcher = new ItemMatcher();
14699        matcher.build(args, opti);
14700
14701        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14702
14703        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14704        printedAnything |= needSep;
14705
14706        if (mLaunchingProviders.size() > 0) {
14707            boolean printed = false;
14708            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14709                ContentProviderRecord r = mLaunchingProviders.get(i);
14710                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14711                    continue;
14712                }
14713                if (!printed) {
14714                    if (needSep) pw.println();
14715                    needSep = true;
14716                    pw.println("  Launching content providers:");
14717                    printed = true;
14718                    printedAnything = true;
14719                }
14720                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14721                        pw.println(r);
14722            }
14723        }
14724
14725        if (!printedAnything) {
14726            pw.println("  (nothing)");
14727        }
14728    }
14729
14730    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14731            int opti, boolean dumpAll, String dumpPackage) {
14732        boolean needSep = false;
14733        boolean printedAnything = false;
14734
14735        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14736
14737        if (mGrantedUriPermissions.size() > 0) {
14738            boolean printed = false;
14739            int dumpUid = -2;
14740            if (dumpPackage != null) {
14741                try {
14742                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14743                            MATCH_UNINSTALLED_PACKAGES, 0);
14744                } catch (NameNotFoundException e) {
14745                    dumpUid = -1;
14746                }
14747            }
14748            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14749                int uid = mGrantedUriPermissions.keyAt(i);
14750                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14751                    continue;
14752                }
14753                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14754                if (!printed) {
14755                    if (needSep) pw.println();
14756                    needSep = true;
14757                    pw.println("  Granted Uri Permissions:");
14758                    printed = true;
14759                    printedAnything = true;
14760                }
14761                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14762                for (UriPermission perm : perms.values()) {
14763                    pw.print("    "); pw.println(perm);
14764                    if (dumpAll) {
14765                        perm.dump(pw, "      ");
14766                    }
14767                }
14768            }
14769        }
14770
14771        if (!printedAnything) {
14772            pw.println("  (nothing)");
14773        }
14774    }
14775
14776    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14777            int opti, boolean dumpAll, String dumpPackage) {
14778        boolean printed = false;
14779
14780        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14781
14782        if (mIntentSenderRecords.size() > 0) {
14783            Iterator<WeakReference<PendingIntentRecord>> it
14784                    = mIntentSenderRecords.values().iterator();
14785            while (it.hasNext()) {
14786                WeakReference<PendingIntentRecord> ref = it.next();
14787                PendingIntentRecord rec = ref != null ? ref.get(): null;
14788                if (dumpPackage != null && (rec == null
14789                        || !dumpPackage.equals(rec.key.packageName))) {
14790                    continue;
14791                }
14792                printed = true;
14793                if (rec != null) {
14794                    pw.print("  * "); pw.println(rec);
14795                    if (dumpAll) {
14796                        rec.dump(pw, "    ");
14797                    }
14798                } else {
14799                    pw.print("  * "); pw.println(ref);
14800                }
14801            }
14802        }
14803
14804        if (!printed) {
14805            pw.println("  (nothing)");
14806        }
14807    }
14808
14809    private static final int dumpProcessList(PrintWriter pw,
14810            ActivityManagerService service, List list,
14811            String prefix, String normalLabel, String persistentLabel,
14812            String dumpPackage) {
14813        int numPers = 0;
14814        final int N = list.size()-1;
14815        for (int i=N; i>=0; i--) {
14816            ProcessRecord r = (ProcessRecord)list.get(i);
14817            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14818                continue;
14819            }
14820            pw.println(String.format("%s%s #%2d: %s",
14821                    prefix, (r.persistent ? persistentLabel : normalLabel),
14822                    i, r.toString()));
14823            if (r.persistent) {
14824                numPers++;
14825            }
14826        }
14827        return numPers;
14828    }
14829
14830    private static final boolean dumpProcessOomList(PrintWriter pw,
14831            ActivityManagerService service, List<ProcessRecord> origList,
14832            String prefix, String normalLabel, String persistentLabel,
14833            boolean inclDetails, String dumpPackage) {
14834
14835        ArrayList<Pair<ProcessRecord, Integer>> list
14836                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14837        for (int i=0; i<origList.size(); i++) {
14838            ProcessRecord r = origList.get(i);
14839            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14840                continue;
14841            }
14842            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14843        }
14844
14845        if (list.size() <= 0) {
14846            return false;
14847        }
14848
14849        Comparator<Pair<ProcessRecord, Integer>> comparator
14850                = new Comparator<Pair<ProcessRecord, Integer>>() {
14851            @Override
14852            public int compare(Pair<ProcessRecord, Integer> object1,
14853                    Pair<ProcessRecord, Integer> object2) {
14854                if (object1.first.setAdj != object2.first.setAdj) {
14855                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14856                }
14857                if (object1.first.setProcState != object2.first.setProcState) {
14858                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14859                }
14860                if (object1.second.intValue() != object2.second.intValue()) {
14861                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14862                }
14863                return 0;
14864            }
14865        };
14866
14867        Collections.sort(list, comparator);
14868
14869        final long curRealtime = SystemClock.elapsedRealtime();
14870        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14871        final long curUptime = SystemClock.uptimeMillis();
14872        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14873
14874        for (int i=list.size()-1; i>=0; i--) {
14875            ProcessRecord r = list.get(i).first;
14876            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14877            char schedGroup;
14878            switch (r.setSchedGroup) {
14879                case ProcessList.SCHED_GROUP_BACKGROUND:
14880                    schedGroup = 'B';
14881                    break;
14882                case ProcessList.SCHED_GROUP_DEFAULT:
14883                    schedGroup = 'F';
14884                    break;
14885                case ProcessList.SCHED_GROUP_TOP_APP:
14886                    schedGroup = 'T';
14887                    break;
14888                default:
14889                    schedGroup = '?';
14890                    break;
14891            }
14892            char foreground;
14893            if (r.foregroundActivities) {
14894                foreground = 'A';
14895            } else if (r.foregroundServices) {
14896                foreground = 'S';
14897            } else {
14898                foreground = ' ';
14899            }
14900            String procState = ProcessList.makeProcStateString(r.curProcState);
14901            pw.print(prefix);
14902            pw.print(r.persistent ? persistentLabel : normalLabel);
14903            pw.print(" #");
14904            int num = (origList.size()-1)-list.get(i).second;
14905            if (num < 10) pw.print(' ');
14906            pw.print(num);
14907            pw.print(": ");
14908            pw.print(oomAdj);
14909            pw.print(' ');
14910            pw.print(schedGroup);
14911            pw.print('/');
14912            pw.print(foreground);
14913            pw.print('/');
14914            pw.print(procState);
14915            pw.print(" trm:");
14916            if (r.trimMemoryLevel < 10) pw.print(' ');
14917            pw.print(r.trimMemoryLevel);
14918            pw.print(' ');
14919            pw.print(r.toShortString());
14920            pw.print(" (");
14921            pw.print(r.adjType);
14922            pw.println(')');
14923            if (r.adjSource != null || r.adjTarget != null) {
14924                pw.print(prefix);
14925                pw.print("    ");
14926                if (r.adjTarget instanceof ComponentName) {
14927                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14928                } else if (r.adjTarget != null) {
14929                    pw.print(r.adjTarget.toString());
14930                } else {
14931                    pw.print("{null}");
14932                }
14933                pw.print("<=");
14934                if (r.adjSource instanceof ProcessRecord) {
14935                    pw.print("Proc{");
14936                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14937                    pw.println("}");
14938                } else if (r.adjSource != null) {
14939                    pw.println(r.adjSource.toString());
14940                } else {
14941                    pw.println("{null}");
14942                }
14943            }
14944            if (inclDetails) {
14945                pw.print(prefix);
14946                pw.print("    ");
14947                pw.print("oom: max="); pw.print(r.maxAdj);
14948                pw.print(" curRaw="); pw.print(r.curRawAdj);
14949                pw.print(" setRaw="); pw.print(r.setRawAdj);
14950                pw.print(" cur="); pw.print(r.curAdj);
14951                pw.print(" set="); pw.println(r.setAdj);
14952                pw.print(prefix);
14953                pw.print("    ");
14954                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14955                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14956                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14957                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14958                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14959                pw.println();
14960                pw.print(prefix);
14961                pw.print("    ");
14962                pw.print("cached="); pw.print(r.cached);
14963                pw.print(" empty="); pw.print(r.empty);
14964                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14965
14966                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14967                    if (r.lastWakeTime != 0) {
14968                        long wtime;
14969                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14970                        synchronized (stats) {
14971                            wtime = stats.getProcessWakeTime(r.info.uid,
14972                                    r.pid, curRealtime);
14973                        }
14974                        long timeUsed = wtime - r.lastWakeTime;
14975                        pw.print(prefix);
14976                        pw.print("    ");
14977                        pw.print("keep awake over ");
14978                        TimeUtils.formatDuration(realtimeSince, pw);
14979                        pw.print(" used ");
14980                        TimeUtils.formatDuration(timeUsed, pw);
14981                        pw.print(" (");
14982                        pw.print((timeUsed*100)/realtimeSince);
14983                        pw.println("%)");
14984                    }
14985                    if (r.lastCpuTime != 0) {
14986                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14987                        pw.print(prefix);
14988                        pw.print("    ");
14989                        pw.print("run cpu over ");
14990                        TimeUtils.formatDuration(uptimeSince, pw);
14991                        pw.print(" used ");
14992                        TimeUtils.formatDuration(timeUsed, pw);
14993                        pw.print(" (");
14994                        pw.print((timeUsed*100)/uptimeSince);
14995                        pw.println("%)");
14996                    }
14997                }
14998            }
14999        }
15000        return true;
15001    }
15002
15003    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15004            String[] args) {
15005        ArrayList<ProcessRecord> procs;
15006        synchronized (this) {
15007            if (args != null && args.length > start
15008                    && args[start].charAt(0) != '-') {
15009                procs = new ArrayList<ProcessRecord>();
15010                int pid = -1;
15011                try {
15012                    pid = Integer.parseInt(args[start]);
15013                } catch (NumberFormatException e) {
15014                }
15015                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15016                    ProcessRecord proc = mLruProcesses.get(i);
15017                    if (proc.pid == pid) {
15018                        procs.add(proc);
15019                    } else if (allPkgs && proc.pkgList != null
15020                            && proc.pkgList.containsKey(args[start])) {
15021                        procs.add(proc);
15022                    } else if (proc.processName.equals(args[start])) {
15023                        procs.add(proc);
15024                    }
15025                }
15026                if (procs.size() <= 0) {
15027                    return null;
15028                }
15029            } else {
15030                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15031            }
15032        }
15033        return procs;
15034    }
15035
15036    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15037            PrintWriter pw, String[] args) {
15038        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15039        if (procs == null) {
15040            pw.println("No process found for: " + args[0]);
15041            return;
15042        }
15043
15044        long uptime = SystemClock.uptimeMillis();
15045        long realtime = SystemClock.elapsedRealtime();
15046        pw.println("Applications Graphics Acceleration Info:");
15047        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15048
15049        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15050            ProcessRecord r = procs.get(i);
15051            if (r.thread != null) {
15052                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15053                pw.flush();
15054                try {
15055                    TransferPipe tp = new TransferPipe();
15056                    try {
15057                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15058                        tp.go(fd);
15059                    } finally {
15060                        tp.kill();
15061                    }
15062                } catch (IOException e) {
15063                    pw.println("Failure while dumping the app: " + r);
15064                    pw.flush();
15065                } catch (RemoteException e) {
15066                    pw.println("Got a RemoteException while dumping the app " + r);
15067                    pw.flush();
15068                }
15069            }
15070        }
15071    }
15072
15073    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15074        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15075        if (procs == null) {
15076            pw.println("No process found for: " + args[0]);
15077            return;
15078        }
15079
15080        pw.println("Applications Database Info:");
15081
15082        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15083            ProcessRecord r = procs.get(i);
15084            if (r.thread != null) {
15085                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15086                pw.flush();
15087                try {
15088                    TransferPipe tp = new TransferPipe();
15089                    try {
15090                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15091                        tp.go(fd);
15092                    } finally {
15093                        tp.kill();
15094                    }
15095                } catch (IOException e) {
15096                    pw.println("Failure while dumping the app: " + r);
15097                    pw.flush();
15098                } catch (RemoteException e) {
15099                    pw.println("Got a RemoteException while dumping the app " + r);
15100                    pw.flush();
15101                }
15102            }
15103        }
15104    }
15105
15106    final static class MemItem {
15107        final boolean isProc;
15108        final String label;
15109        final String shortLabel;
15110        final long pss;
15111        final long swapPss;
15112        final int id;
15113        final boolean hasActivities;
15114        ArrayList<MemItem> subitems;
15115
15116        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15117                boolean _hasActivities) {
15118            isProc = true;
15119            label = _label;
15120            shortLabel = _shortLabel;
15121            pss = _pss;
15122            swapPss = _swapPss;
15123            id = _id;
15124            hasActivities = _hasActivities;
15125        }
15126
15127        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15128            isProc = false;
15129            label = _label;
15130            shortLabel = _shortLabel;
15131            pss = _pss;
15132            swapPss = _swapPss;
15133            id = _id;
15134            hasActivities = false;
15135        }
15136    }
15137
15138    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15139            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15140        if (sort && !isCompact) {
15141            Collections.sort(items, new Comparator<MemItem>() {
15142                @Override
15143                public int compare(MemItem lhs, MemItem rhs) {
15144                    if (lhs.pss < rhs.pss) {
15145                        return 1;
15146                    } else if (lhs.pss > rhs.pss) {
15147                        return -1;
15148                    }
15149                    return 0;
15150                }
15151            });
15152        }
15153
15154        for (int i=0; i<items.size(); i++) {
15155            MemItem mi = items.get(i);
15156            if (!isCompact) {
15157                if (dumpSwapPss) {
15158                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15159                            mi.label, stringifyKBSize(mi.swapPss));
15160                } else {
15161                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15162                }
15163            } else if (mi.isProc) {
15164                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15165                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15166                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15167                pw.println(mi.hasActivities ? ",a" : ",e");
15168            } else {
15169                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15170                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15171            }
15172            if (mi.subitems != null) {
15173                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15174                        true, isCompact, dumpSwapPss);
15175            }
15176        }
15177    }
15178
15179    // These are in KB.
15180    static final long[] DUMP_MEM_BUCKETS = new long[] {
15181        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15182        120*1024, 160*1024, 200*1024,
15183        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15184        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15185    };
15186
15187    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15188            boolean stackLike) {
15189        int start = label.lastIndexOf('.');
15190        if (start >= 0) start++;
15191        else start = 0;
15192        int end = label.length();
15193        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15194            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15195                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15196                out.append(bucket);
15197                out.append(stackLike ? "MB." : "MB ");
15198                out.append(label, start, end);
15199                return;
15200            }
15201        }
15202        out.append(memKB/1024);
15203        out.append(stackLike ? "MB." : "MB ");
15204        out.append(label, start, end);
15205    }
15206
15207    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15208            ProcessList.NATIVE_ADJ,
15209            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15210            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15211            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15212            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15213            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15214            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15215    };
15216    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15217            "Native",
15218            "System", "Persistent", "Persistent Service", "Foreground",
15219            "Visible", "Perceptible",
15220            "Heavy Weight", "Backup",
15221            "A Services", "Home",
15222            "Previous", "B Services", "Cached"
15223    };
15224    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15225            "native",
15226            "sys", "pers", "persvc", "fore",
15227            "vis", "percept",
15228            "heavy", "backup",
15229            "servicea", "home",
15230            "prev", "serviceb", "cached"
15231    };
15232
15233    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15234            long realtime, boolean isCheckinRequest, boolean isCompact) {
15235        if (isCompact) {
15236            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15237        }
15238        if (isCheckinRequest || isCompact) {
15239            // short checkin version
15240            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15241        } else {
15242            pw.println("Applications Memory Usage (in Kilobytes):");
15243            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15244        }
15245    }
15246
15247    private static final int KSM_SHARED = 0;
15248    private static final int KSM_SHARING = 1;
15249    private static final int KSM_UNSHARED = 2;
15250    private static final int KSM_VOLATILE = 3;
15251
15252    private final long[] getKsmInfo() {
15253        long[] longOut = new long[4];
15254        final int[] SINGLE_LONG_FORMAT = new int[] {
15255            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15256        };
15257        long[] longTmp = new long[1];
15258        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15259                SINGLE_LONG_FORMAT, null, longTmp, null);
15260        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15261        longTmp[0] = 0;
15262        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15263                SINGLE_LONG_FORMAT, null, longTmp, null);
15264        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15265        longTmp[0] = 0;
15266        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15267                SINGLE_LONG_FORMAT, null, longTmp, null);
15268        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15269        longTmp[0] = 0;
15270        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15271                SINGLE_LONG_FORMAT, null, longTmp, null);
15272        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15273        return longOut;
15274    }
15275
15276    private static String stringifySize(long size, int order) {
15277        Locale locale = Locale.US;
15278        switch (order) {
15279            case 1:
15280                return String.format(locale, "%,13d", size);
15281            case 1024:
15282                return String.format(locale, "%,9dK", size / 1024);
15283            case 1024 * 1024:
15284                return String.format(locale, "%,5dM", size / 1024 / 1024);
15285            case 1024 * 1024 * 1024:
15286                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15287            default:
15288                throw new IllegalArgumentException("Invalid size order");
15289        }
15290    }
15291
15292    private static String stringifyKBSize(long size) {
15293        return stringifySize(size * 1024, 1024);
15294    }
15295
15296    // Update this version number in case you change the 'compact' format
15297    private static final int MEMINFO_COMPACT_VERSION = 1;
15298
15299    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15300            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15301        boolean dumpDetails = false;
15302        boolean dumpFullDetails = false;
15303        boolean dumpDalvik = false;
15304        boolean dumpSummaryOnly = false;
15305        boolean dumpUnreachable = false;
15306        boolean oomOnly = false;
15307        boolean isCompact = false;
15308        boolean localOnly = false;
15309        boolean packages = false;
15310        boolean isCheckinRequest = false;
15311        boolean dumpSwapPss = false;
15312
15313        int opti = 0;
15314        while (opti < args.length) {
15315            String opt = args[opti];
15316            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15317                break;
15318            }
15319            opti++;
15320            if ("-a".equals(opt)) {
15321                dumpDetails = true;
15322                dumpFullDetails = true;
15323                dumpDalvik = true;
15324                dumpSwapPss = true;
15325            } else if ("-d".equals(opt)) {
15326                dumpDalvik = true;
15327            } else if ("-c".equals(opt)) {
15328                isCompact = true;
15329            } else if ("-s".equals(opt)) {
15330                dumpDetails = true;
15331                dumpSummaryOnly = true;
15332            } else if ("-S".equals(opt)) {
15333                dumpSwapPss = true;
15334            } else if ("--unreachable".equals(opt)) {
15335                dumpUnreachable = true;
15336            } else if ("--oom".equals(opt)) {
15337                oomOnly = true;
15338            } else if ("--local".equals(opt)) {
15339                localOnly = true;
15340            } else if ("--package".equals(opt)) {
15341                packages = true;
15342            } else if ("--checkin".equals(opt)) {
15343                isCheckinRequest = true;
15344
15345            } else if ("-h".equals(opt)) {
15346                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15347                pw.println("  -a: include all available information for each process.");
15348                pw.println("  -d: include dalvik details.");
15349                pw.println("  -c: dump in a compact machine-parseable representation.");
15350                pw.println("  -s: dump only summary of application memory usage.");
15351                pw.println("  -S: dump also SwapPss.");
15352                pw.println("  --oom: only show processes organized by oom adj.");
15353                pw.println("  --local: only collect details locally, don't call process.");
15354                pw.println("  --package: interpret process arg as package, dumping all");
15355                pw.println("             processes that have loaded that package.");
15356                pw.println("  --checkin: dump data for a checkin");
15357                pw.println("If [process] is specified it can be the name or ");
15358                pw.println("pid of a specific process to dump.");
15359                return;
15360            } else {
15361                pw.println("Unknown argument: " + opt + "; use -h for help");
15362            }
15363        }
15364
15365        long uptime = SystemClock.uptimeMillis();
15366        long realtime = SystemClock.elapsedRealtime();
15367        final long[] tmpLong = new long[1];
15368
15369        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15370        if (procs == null) {
15371            // No Java processes.  Maybe they want to print a native process.
15372            if (args != null && args.length > opti
15373                    && args[opti].charAt(0) != '-') {
15374                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15375                        = new ArrayList<ProcessCpuTracker.Stats>();
15376                updateCpuStatsNow();
15377                int findPid = -1;
15378                try {
15379                    findPid = Integer.parseInt(args[opti]);
15380                } catch (NumberFormatException e) {
15381                }
15382                synchronized (mProcessCpuTracker) {
15383                    final int N = mProcessCpuTracker.countStats();
15384                    for (int i=0; i<N; i++) {
15385                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15386                        if (st.pid == findPid || (st.baseName != null
15387                                && st.baseName.equals(args[opti]))) {
15388                            nativeProcs.add(st);
15389                        }
15390                    }
15391                }
15392                if (nativeProcs.size() > 0) {
15393                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15394                            isCompact);
15395                    Debug.MemoryInfo mi = null;
15396                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15397                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15398                        final int pid = r.pid;
15399                        if (!isCheckinRequest && dumpDetails) {
15400                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15401                        }
15402                        if (mi == null) {
15403                            mi = new Debug.MemoryInfo();
15404                        }
15405                        if (dumpDetails || (!brief && !oomOnly)) {
15406                            Debug.getMemoryInfo(pid, mi);
15407                        } else {
15408                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15409                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15410                        }
15411                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15412                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15413                        if (isCheckinRequest) {
15414                            pw.println();
15415                        }
15416                    }
15417                    return;
15418                }
15419            }
15420            pw.println("No process found for: " + args[opti]);
15421            return;
15422        }
15423
15424        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15425            dumpDetails = true;
15426        }
15427
15428        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15429
15430        String[] innerArgs = new String[args.length-opti];
15431        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15432
15433        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15434        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15435        long nativePss = 0;
15436        long nativeSwapPss = 0;
15437        long dalvikPss = 0;
15438        long dalvikSwapPss = 0;
15439        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15440                EmptyArray.LONG;
15441        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15442                EmptyArray.LONG;
15443        long otherPss = 0;
15444        long otherSwapPss = 0;
15445        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15446        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15447
15448        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15449        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15450        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15451                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15452
15453        long totalPss = 0;
15454        long totalSwapPss = 0;
15455        long cachedPss = 0;
15456        long cachedSwapPss = 0;
15457        boolean hasSwapPss = false;
15458
15459        Debug.MemoryInfo mi = null;
15460        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15461            final ProcessRecord r = procs.get(i);
15462            final IApplicationThread thread;
15463            final int pid;
15464            final int oomAdj;
15465            final boolean hasActivities;
15466            synchronized (this) {
15467                thread = r.thread;
15468                pid = r.pid;
15469                oomAdj = r.getSetAdjWithServices();
15470                hasActivities = r.activities.size() > 0;
15471            }
15472            if (thread != null) {
15473                if (!isCheckinRequest && dumpDetails) {
15474                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15475                }
15476                if (mi == null) {
15477                    mi = new Debug.MemoryInfo();
15478                }
15479                if (dumpDetails || (!brief && !oomOnly)) {
15480                    Debug.getMemoryInfo(pid, mi);
15481                    hasSwapPss = mi.hasSwappedOutPss;
15482                } else {
15483                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15484                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15485                }
15486                if (dumpDetails) {
15487                    if (localOnly) {
15488                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15489                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15490                        if (isCheckinRequest) {
15491                            pw.println();
15492                        }
15493                    } else {
15494                        try {
15495                            pw.flush();
15496                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15497                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15498                        } catch (RemoteException e) {
15499                            if (!isCheckinRequest) {
15500                                pw.println("Got RemoteException!");
15501                                pw.flush();
15502                            }
15503                        }
15504                    }
15505                }
15506
15507                final long myTotalPss = mi.getTotalPss();
15508                final long myTotalUss = mi.getTotalUss();
15509                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15510
15511                synchronized (this) {
15512                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15513                        // Record this for posterity if the process has been stable.
15514                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15515                    }
15516                }
15517
15518                if (!isCheckinRequest && mi != null) {
15519                    totalPss += myTotalPss;
15520                    totalSwapPss += myTotalSwapPss;
15521                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15522                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15523                            myTotalSwapPss, pid, hasActivities);
15524                    procMems.add(pssItem);
15525                    procMemsMap.put(pid, pssItem);
15526
15527                    nativePss += mi.nativePss;
15528                    nativeSwapPss += mi.nativeSwappedOutPss;
15529                    dalvikPss += mi.dalvikPss;
15530                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15531                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15532                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15533                        dalvikSubitemSwapPss[j] +=
15534                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15535                    }
15536                    otherPss += mi.otherPss;
15537                    otherSwapPss += mi.otherSwappedOutPss;
15538                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15539                        long mem = mi.getOtherPss(j);
15540                        miscPss[j] += mem;
15541                        otherPss -= mem;
15542                        mem = mi.getOtherSwappedOutPss(j);
15543                        miscSwapPss[j] += mem;
15544                        otherSwapPss -= mem;
15545                    }
15546
15547                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15548                        cachedPss += myTotalPss;
15549                        cachedSwapPss += myTotalSwapPss;
15550                    }
15551
15552                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15553                        if (oomIndex == (oomPss.length - 1)
15554                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15555                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15556                            oomPss[oomIndex] += myTotalPss;
15557                            oomSwapPss[oomIndex] += myTotalSwapPss;
15558                            if (oomProcs[oomIndex] == null) {
15559                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15560                            }
15561                            oomProcs[oomIndex].add(pssItem);
15562                            break;
15563                        }
15564                    }
15565                }
15566            }
15567        }
15568
15569        long nativeProcTotalPss = 0;
15570
15571        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15572            // If we are showing aggregations, also look for native processes to
15573            // include so that our aggregations are more accurate.
15574            updateCpuStatsNow();
15575            mi = null;
15576            synchronized (mProcessCpuTracker) {
15577                final int N = mProcessCpuTracker.countStats();
15578                for (int i=0; i<N; i++) {
15579                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15580                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15581                        if (mi == null) {
15582                            mi = new Debug.MemoryInfo();
15583                        }
15584                        if (!brief && !oomOnly) {
15585                            Debug.getMemoryInfo(st.pid, mi);
15586                        } else {
15587                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15588                            mi.nativePrivateDirty = (int)tmpLong[0];
15589                        }
15590
15591                        final long myTotalPss = mi.getTotalPss();
15592                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15593                        totalPss += myTotalPss;
15594                        nativeProcTotalPss += myTotalPss;
15595
15596                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15597                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15598                        procMems.add(pssItem);
15599
15600                        nativePss += mi.nativePss;
15601                        nativeSwapPss += mi.nativeSwappedOutPss;
15602                        dalvikPss += mi.dalvikPss;
15603                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15604                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15605                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15606                            dalvikSubitemSwapPss[j] +=
15607                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15608                        }
15609                        otherPss += mi.otherPss;
15610                        otherSwapPss += mi.otherSwappedOutPss;
15611                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15612                            long mem = mi.getOtherPss(j);
15613                            miscPss[j] += mem;
15614                            otherPss -= mem;
15615                            mem = mi.getOtherSwappedOutPss(j);
15616                            miscSwapPss[j] += mem;
15617                            otherSwapPss -= mem;
15618                        }
15619                        oomPss[0] += myTotalPss;
15620                        oomSwapPss[0] += myTotalSwapPss;
15621                        if (oomProcs[0] == null) {
15622                            oomProcs[0] = new ArrayList<MemItem>();
15623                        }
15624                        oomProcs[0].add(pssItem);
15625                    }
15626                }
15627            }
15628
15629            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15630
15631            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15632            final MemItem dalvikItem =
15633                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15634            if (dalvikSubitemPss.length > 0) {
15635                dalvikItem.subitems = new ArrayList<MemItem>();
15636                for (int j=0; j<dalvikSubitemPss.length; j++) {
15637                    final String name = Debug.MemoryInfo.getOtherLabel(
15638                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15639                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15640                                    dalvikSubitemSwapPss[j], j));
15641                }
15642            }
15643            catMems.add(dalvikItem);
15644            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15645            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15646                String label = Debug.MemoryInfo.getOtherLabel(j);
15647                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15648            }
15649
15650            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15651            for (int j=0; j<oomPss.length; j++) {
15652                if (oomPss[j] != 0) {
15653                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15654                            : DUMP_MEM_OOM_LABEL[j];
15655                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15656                            DUMP_MEM_OOM_ADJ[j]);
15657                    item.subitems = oomProcs[j];
15658                    oomMems.add(item);
15659                }
15660            }
15661
15662            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15663            if (!brief && !oomOnly && !isCompact) {
15664                pw.println();
15665                pw.println("Total PSS by process:");
15666                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15667                pw.println();
15668            }
15669            if (!isCompact) {
15670                pw.println("Total PSS by OOM adjustment:");
15671            }
15672            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15673            if (!brief && !oomOnly) {
15674                PrintWriter out = categoryPw != null ? categoryPw : pw;
15675                if (!isCompact) {
15676                    out.println();
15677                    out.println("Total PSS by category:");
15678                }
15679                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15680            }
15681            if (!isCompact) {
15682                pw.println();
15683            }
15684            MemInfoReader memInfo = new MemInfoReader();
15685            memInfo.readMemInfo();
15686            if (nativeProcTotalPss > 0) {
15687                synchronized (this) {
15688                    final long cachedKb = memInfo.getCachedSizeKb();
15689                    final long freeKb = memInfo.getFreeSizeKb();
15690                    final long zramKb = memInfo.getZramTotalSizeKb();
15691                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15692                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15693                            kernelKb*1024, nativeProcTotalPss*1024);
15694                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15695                            nativeProcTotalPss);
15696                }
15697            }
15698            if (!brief) {
15699                if (!isCompact) {
15700                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15701                    pw.print(" (status ");
15702                    switch (mLastMemoryLevel) {
15703                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15704                            pw.println("normal)");
15705                            break;
15706                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15707                            pw.println("moderate)");
15708                            break;
15709                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15710                            pw.println("low)");
15711                            break;
15712                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15713                            pw.println("critical)");
15714                            break;
15715                        default:
15716                            pw.print(mLastMemoryLevel);
15717                            pw.println(")");
15718                            break;
15719                    }
15720                    pw.print(" Free RAM: ");
15721                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15722                            + memInfo.getFreeSizeKb()));
15723                    pw.print(" (");
15724                    pw.print(stringifyKBSize(cachedPss));
15725                    pw.print(" cached pss + ");
15726                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15727                    pw.print(" cached kernel + ");
15728                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15729                    pw.println(" free)");
15730                } else {
15731                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15732                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15733                            + memInfo.getFreeSizeKb()); pw.print(",");
15734                    pw.println(totalPss - cachedPss);
15735                }
15736            }
15737            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15738                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15739                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15740            if (!isCompact) {
15741                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15742                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15743                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15744                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15745                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15746            } else {
15747                pw.print("lostram,"); pw.println(lostRAM);
15748            }
15749            if (!brief) {
15750                if (memInfo.getZramTotalSizeKb() != 0) {
15751                    if (!isCompact) {
15752                        pw.print("     ZRAM: ");
15753                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15754                                pw.print(" physical used for ");
15755                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15756                                        - memInfo.getSwapFreeSizeKb()));
15757                                pw.print(" in swap (");
15758                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15759                                pw.println(" total swap)");
15760                    } else {
15761                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15762                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15763                                pw.println(memInfo.getSwapFreeSizeKb());
15764                    }
15765                }
15766                final long[] ksm = getKsmInfo();
15767                if (!isCompact) {
15768                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15769                            || ksm[KSM_VOLATILE] != 0) {
15770                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15771                                pw.print(" saved from shared ");
15772                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15773                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15774                                pw.print(" unshared; ");
15775                                pw.print(stringifyKBSize(
15776                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15777                    }
15778                    pw.print("   Tuning: ");
15779                    pw.print(ActivityManager.staticGetMemoryClass());
15780                    pw.print(" (large ");
15781                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15782                    pw.print("), oom ");
15783                    pw.print(stringifySize(
15784                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15785                    pw.print(", restore limit ");
15786                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15787                    if (ActivityManager.isLowRamDeviceStatic()) {
15788                        pw.print(" (low-ram)");
15789                    }
15790                    if (ActivityManager.isHighEndGfx()) {
15791                        pw.print(" (high-end-gfx)");
15792                    }
15793                    pw.println();
15794                } else {
15795                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15796                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15797                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15798                    pw.print("tuning,");
15799                    pw.print(ActivityManager.staticGetMemoryClass());
15800                    pw.print(',');
15801                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15802                    pw.print(',');
15803                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15804                    if (ActivityManager.isLowRamDeviceStatic()) {
15805                        pw.print(",low-ram");
15806                    }
15807                    if (ActivityManager.isHighEndGfx()) {
15808                        pw.print(",high-end-gfx");
15809                    }
15810                    pw.println();
15811                }
15812            }
15813        }
15814    }
15815
15816    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15817            long memtrack, String name) {
15818        sb.append("  ");
15819        sb.append(ProcessList.makeOomAdjString(oomAdj));
15820        sb.append(' ');
15821        sb.append(ProcessList.makeProcStateString(procState));
15822        sb.append(' ');
15823        ProcessList.appendRamKb(sb, pss);
15824        sb.append(": ");
15825        sb.append(name);
15826        if (memtrack > 0) {
15827            sb.append(" (");
15828            sb.append(stringifyKBSize(memtrack));
15829            sb.append(" memtrack)");
15830        }
15831    }
15832
15833    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15834        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15835        sb.append(" (pid ");
15836        sb.append(mi.pid);
15837        sb.append(") ");
15838        sb.append(mi.adjType);
15839        sb.append('\n');
15840        if (mi.adjReason != null) {
15841            sb.append("                      ");
15842            sb.append(mi.adjReason);
15843            sb.append('\n');
15844        }
15845    }
15846
15847    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15848        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15849        for (int i=0, N=memInfos.size(); i<N; i++) {
15850            ProcessMemInfo mi = memInfos.get(i);
15851            infoMap.put(mi.pid, mi);
15852        }
15853        updateCpuStatsNow();
15854        long[] memtrackTmp = new long[1];
15855        synchronized (mProcessCpuTracker) {
15856            final int N = mProcessCpuTracker.countStats();
15857            for (int i=0; i<N; i++) {
15858                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15859                if (st.vsize > 0) {
15860                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15861                    if (pss > 0) {
15862                        if (infoMap.indexOfKey(st.pid) < 0) {
15863                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15864                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15865                            mi.pss = pss;
15866                            mi.memtrack = memtrackTmp[0];
15867                            memInfos.add(mi);
15868                        }
15869                    }
15870                }
15871            }
15872        }
15873
15874        long totalPss = 0;
15875        long totalMemtrack = 0;
15876        for (int i=0, N=memInfos.size(); i<N; i++) {
15877            ProcessMemInfo mi = memInfos.get(i);
15878            if (mi.pss == 0) {
15879                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15880                mi.memtrack = memtrackTmp[0];
15881            }
15882            totalPss += mi.pss;
15883            totalMemtrack += mi.memtrack;
15884        }
15885        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15886            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15887                if (lhs.oomAdj != rhs.oomAdj) {
15888                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15889                }
15890                if (lhs.pss != rhs.pss) {
15891                    return lhs.pss < rhs.pss ? 1 : -1;
15892                }
15893                return 0;
15894            }
15895        });
15896
15897        StringBuilder tag = new StringBuilder(128);
15898        StringBuilder stack = new StringBuilder(128);
15899        tag.append("Low on memory -- ");
15900        appendMemBucket(tag, totalPss, "total", false);
15901        appendMemBucket(stack, totalPss, "total", true);
15902
15903        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15904        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15905        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15906
15907        boolean firstLine = true;
15908        int lastOomAdj = Integer.MIN_VALUE;
15909        long extraNativeRam = 0;
15910        long extraNativeMemtrack = 0;
15911        long cachedPss = 0;
15912        for (int i=0, N=memInfos.size(); i<N; i++) {
15913            ProcessMemInfo mi = memInfos.get(i);
15914
15915            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15916                cachedPss += mi.pss;
15917            }
15918
15919            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15920                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15921                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15922                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15923                if (lastOomAdj != mi.oomAdj) {
15924                    lastOomAdj = mi.oomAdj;
15925                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15926                        tag.append(" / ");
15927                    }
15928                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15929                        if (firstLine) {
15930                            stack.append(":");
15931                            firstLine = false;
15932                        }
15933                        stack.append("\n\t at ");
15934                    } else {
15935                        stack.append("$");
15936                    }
15937                } else {
15938                    tag.append(" ");
15939                    stack.append("$");
15940                }
15941                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15942                    appendMemBucket(tag, mi.pss, mi.name, false);
15943                }
15944                appendMemBucket(stack, mi.pss, mi.name, true);
15945                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15946                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15947                    stack.append("(");
15948                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15949                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15950                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15951                            stack.append(":");
15952                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15953                        }
15954                    }
15955                    stack.append(")");
15956                }
15957            }
15958
15959            appendMemInfo(fullNativeBuilder, mi);
15960            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15961                // The short form only has native processes that are >= 512K.
15962                if (mi.pss >= 512) {
15963                    appendMemInfo(shortNativeBuilder, mi);
15964                } else {
15965                    extraNativeRam += mi.pss;
15966                    extraNativeMemtrack += mi.memtrack;
15967                }
15968            } else {
15969                // Short form has all other details, but if we have collected RAM
15970                // from smaller native processes let's dump a summary of that.
15971                if (extraNativeRam > 0) {
15972                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15973                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15974                    shortNativeBuilder.append('\n');
15975                    extraNativeRam = 0;
15976                }
15977                appendMemInfo(fullJavaBuilder, mi);
15978            }
15979        }
15980
15981        fullJavaBuilder.append("           ");
15982        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15983        fullJavaBuilder.append(": TOTAL");
15984        if (totalMemtrack > 0) {
15985            fullJavaBuilder.append(" (");
15986            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15987            fullJavaBuilder.append(" memtrack)");
15988        } else {
15989        }
15990        fullJavaBuilder.append("\n");
15991
15992        MemInfoReader memInfo = new MemInfoReader();
15993        memInfo.readMemInfo();
15994        final long[] infos = memInfo.getRawInfo();
15995
15996        StringBuilder memInfoBuilder = new StringBuilder(1024);
15997        Debug.getMemInfo(infos);
15998        memInfoBuilder.append("  MemInfo: ");
15999        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16000        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16001        memInfoBuilder.append(stringifyKBSize(
16002                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16003        memInfoBuilder.append(stringifyKBSize(
16004                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16005        memInfoBuilder.append(stringifyKBSize(
16006                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16007        memInfoBuilder.append("           ");
16008        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16009        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16010        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16011        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16012        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16013            memInfoBuilder.append("  ZRAM: ");
16014            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16015            memInfoBuilder.append(" RAM, ");
16016            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16017            memInfoBuilder.append(" swap total, ");
16018            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16019            memInfoBuilder.append(" swap free\n");
16020        }
16021        final long[] ksm = getKsmInfo();
16022        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16023                || ksm[KSM_VOLATILE] != 0) {
16024            memInfoBuilder.append("  KSM: ");
16025            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16026            memInfoBuilder.append(" saved from shared ");
16027            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16028            memInfoBuilder.append("\n       ");
16029            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16030            memInfoBuilder.append(" unshared; ");
16031            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16032            memInfoBuilder.append(" volatile\n");
16033        }
16034        memInfoBuilder.append("  Free RAM: ");
16035        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16036                + memInfo.getFreeSizeKb()));
16037        memInfoBuilder.append("\n");
16038        memInfoBuilder.append("  Used RAM: ");
16039        memInfoBuilder.append(stringifyKBSize(
16040                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16041        memInfoBuilder.append("\n");
16042        memInfoBuilder.append("  Lost RAM: ");
16043        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16044                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16045                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16046        memInfoBuilder.append("\n");
16047        Slog.i(TAG, "Low on memory:");
16048        Slog.i(TAG, shortNativeBuilder.toString());
16049        Slog.i(TAG, fullJavaBuilder.toString());
16050        Slog.i(TAG, memInfoBuilder.toString());
16051
16052        StringBuilder dropBuilder = new StringBuilder(1024);
16053        /*
16054        StringWriter oomSw = new StringWriter();
16055        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16056        StringWriter catSw = new StringWriter();
16057        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16058        String[] emptyArgs = new String[] { };
16059        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16060        oomPw.flush();
16061        String oomString = oomSw.toString();
16062        */
16063        dropBuilder.append("Low on memory:");
16064        dropBuilder.append(stack);
16065        dropBuilder.append('\n');
16066        dropBuilder.append(fullNativeBuilder);
16067        dropBuilder.append(fullJavaBuilder);
16068        dropBuilder.append('\n');
16069        dropBuilder.append(memInfoBuilder);
16070        dropBuilder.append('\n');
16071        /*
16072        dropBuilder.append(oomString);
16073        dropBuilder.append('\n');
16074        */
16075        StringWriter catSw = new StringWriter();
16076        synchronized (ActivityManagerService.this) {
16077            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16078            String[] emptyArgs = new String[] { };
16079            catPw.println();
16080            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16081            catPw.println();
16082            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16083                    false, false, null);
16084            catPw.println();
16085            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16086            catPw.flush();
16087        }
16088        dropBuilder.append(catSw.toString());
16089        addErrorToDropBox("lowmem", null, "system_server", null,
16090                null, tag.toString(), dropBuilder.toString(), null, null);
16091        //Slog.i(TAG, "Sent to dropbox:");
16092        //Slog.i(TAG, dropBuilder.toString());
16093        synchronized (ActivityManagerService.this) {
16094            long now = SystemClock.uptimeMillis();
16095            if (mLastMemUsageReportTime < now) {
16096                mLastMemUsageReportTime = now;
16097            }
16098        }
16099    }
16100
16101    /**
16102     * Searches array of arguments for the specified string
16103     * @param args array of argument strings
16104     * @param value value to search for
16105     * @return true if the value is contained in the array
16106     */
16107    private static boolean scanArgs(String[] args, String value) {
16108        if (args != null) {
16109            for (String arg : args) {
16110                if (value.equals(arg)) {
16111                    return true;
16112                }
16113            }
16114        }
16115        return false;
16116    }
16117
16118    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16119            ContentProviderRecord cpr, boolean always) {
16120        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16121
16122        if (!inLaunching || always) {
16123            synchronized (cpr) {
16124                cpr.launchingApp = null;
16125                cpr.notifyAll();
16126            }
16127            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16128            String names[] = cpr.info.authority.split(";");
16129            for (int j = 0; j < names.length; j++) {
16130                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16131            }
16132        }
16133
16134        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16135            ContentProviderConnection conn = cpr.connections.get(i);
16136            if (conn.waiting) {
16137                // If this connection is waiting for the provider, then we don't
16138                // need to mess with its process unless we are always removing
16139                // or for some reason the provider is not currently launching.
16140                if (inLaunching && !always) {
16141                    continue;
16142                }
16143            }
16144            ProcessRecord capp = conn.client;
16145            conn.dead = true;
16146            if (conn.stableCount > 0) {
16147                if (!capp.persistent && capp.thread != null
16148                        && capp.pid != 0
16149                        && capp.pid != MY_PID) {
16150                    capp.kill("depends on provider "
16151                            + cpr.name.flattenToShortString()
16152                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16153                }
16154            } else if (capp.thread != null && conn.provider.provider != null) {
16155                try {
16156                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16157                } catch (RemoteException e) {
16158                }
16159                // In the protocol here, we don't expect the client to correctly
16160                // clean up this connection, we'll just remove it.
16161                cpr.connections.remove(i);
16162                if (conn.client.conProviders.remove(conn)) {
16163                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16164                }
16165            }
16166        }
16167
16168        if (inLaunching && always) {
16169            mLaunchingProviders.remove(cpr);
16170        }
16171        return inLaunching;
16172    }
16173
16174    /**
16175     * Main code for cleaning up a process when it has gone away.  This is
16176     * called both as a result of the process dying, or directly when stopping
16177     * a process when running in single process mode.
16178     *
16179     * @return Returns true if the given process has been restarted, so the
16180     * app that was passed in must remain on the process lists.
16181     */
16182    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16183            boolean restarting, boolean allowRestart, int index) {
16184        if (index >= 0) {
16185            removeLruProcessLocked(app);
16186            ProcessList.remove(app.pid);
16187        }
16188
16189        mProcessesToGc.remove(app);
16190        mPendingPssProcesses.remove(app);
16191
16192        // Dismiss any open dialogs.
16193        if (app.crashDialog != null && !app.forceCrashReport) {
16194            app.crashDialog.dismiss();
16195            app.crashDialog = null;
16196        }
16197        if (app.anrDialog != null) {
16198            app.anrDialog.dismiss();
16199            app.anrDialog = null;
16200        }
16201        if (app.waitDialog != null) {
16202            app.waitDialog.dismiss();
16203            app.waitDialog = null;
16204        }
16205
16206        app.crashing = false;
16207        app.notResponding = false;
16208
16209        app.resetPackageList(mProcessStats);
16210        app.unlinkDeathRecipient();
16211        app.makeInactive(mProcessStats);
16212        app.waitingToKill = null;
16213        app.forcingToForeground = null;
16214        updateProcessForegroundLocked(app, false, false);
16215        app.foregroundActivities = false;
16216        app.hasShownUi = false;
16217        app.treatLikeActivity = false;
16218        app.hasAboveClient = false;
16219        app.hasClientActivities = false;
16220
16221        mServices.killServicesLocked(app, allowRestart);
16222
16223        boolean restart = false;
16224
16225        // Remove published content providers.
16226        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16227            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16228            final boolean always = app.bad || !allowRestart;
16229            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16230            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16231                // We left the provider in the launching list, need to
16232                // restart it.
16233                restart = true;
16234            }
16235
16236            cpr.provider = null;
16237            cpr.proc = null;
16238        }
16239        app.pubProviders.clear();
16240
16241        // Take care of any launching providers waiting for this process.
16242        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16243            restart = true;
16244        }
16245
16246        // Unregister from connected content providers.
16247        if (!app.conProviders.isEmpty()) {
16248            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16249                ContentProviderConnection conn = app.conProviders.get(i);
16250                conn.provider.connections.remove(conn);
16251                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16252                        conn.provider.name);
16253            }
16254            app.conProviders.clear();
16255        }
16256
16257        // At this point there may be remaining entries in mLaunchingProviders
16258        // where we were the only one waiting, so they are no longer of use.
16259        // Look for these and clean up if found.
16260        // XXX Commented out for now.  Trying to figure out a way to reproduce
16261        // the actual situation to identify what is actually going on.
16262        if (false) {
16263            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16264                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16265                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16266                    synchronized (cpr) {
16267                        cpr.launchingApp = null;
16268                        cpr.notifyAll();
16269                    }
16270                }
16271            }
16272        }
16273
16274        skipCurrentReceiverLocked(app);
16275
16276        // Unregister any receivers.
16277        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16278            removeReceiverLocked(app.receivers.valueAt(i));
16279        }
16280        app.receivers.clear();
16281
16282        // If the app is undergoing backup, tell the backup manager about it
16283        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16284            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16285                    + mBackupTarget.appInfo + " died during backup");
16286            try {
16287                IBackupManager bm = IBackupManager.Stub.asInterface(
16288                        ServiceManager.getService(Context.BACKUP_SERVICE));
16289                bm.agentDisconnected(app.info.packageName);
16290            } catch (RemoteException e) {
16291                // can't happen; backup manager is local
16292            }
16293        }
16294
16295        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16296            ProcessChangeItem item = mPendingProcessChanges.get(i);
16297            if (item.pid == app.pid) {
16298                mPendingProcessChanges.remove(i);
16299                mAvailProcessChanges.add(item);
16300            }
16301        }
16302        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16303                null).sendToTarget();
16304
16305        // If the caller is restarting this app, then leave it in its
16306        // current lists and let the caller take care of it.
16307        if (restarting) {
16308            return false;
16309        }
16310
16311        if (!app.persistent || app.isolated) {
16312            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16313                    "Removing non-persistent process during cleanup: " + app);
16314            removeProcessNameLocked(app.processName, app.uid);
16315            if (mHeavyWeightProcess == app) {
16316                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16317                        mHeavyWeightProcess.userId, 0));
16318                mHeavyWeightProcess = null;
16319            }
16320        } else if (!app.removed) {
16321            // This app is persistent, so we need to keep its record around.
16322            // If it is not already on the pending app list, add it there
16323            // and start a new process for it.
16324            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16325                mPersistentStartingProcesses.add(app);
16326                restart = true;
16327            }
16328        }
16329        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16330                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16331        mProcessesOnHold.remove(app);
16332
16333        if (app == mHomeProcess) {
16334            mHomeProcess = null;
16335        }
16336        if (app == mPreviousProcess) {
16337            mPreviousProcess = null;
16338        }
16339
16340        if (restart && !app.isolated) {
16341            // We have components that still need to be running in the
16342            // process, so re-launch it.
16343            if (index < 0) {
16344                ProcessList.remove(app.pid);
16345            }
16346            addProcessNameLocked(app);
16347            startProcessLocked(app, "restart", app.processName);
16348            return true;
16349        } else if (app.pid > 0 && app.pid != MY_PID) {
16350            // Goodbye!
16351            boolean removed;
16352            synchronized (mPidsSelfLocked) {
16353                mPidsSelfLocked.remove(app.pid);
16354                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16355            }
16356            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16357            if (app.isolated) {
16358                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16359            }
16360            app.setPid(0);
16361        }
16362        return false;
16363    }
16364
16365    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16366        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16367            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16368            if (cpr.launchingApp == app) {
16369                return true;
16370            }
16371        }
16372        return false;
16373    }
16374
16375    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16376        // Look through the content providers we are waiting to have launched,
16377        // and if any run in this process then either schedule a restart of
16378        // the process or kill the client waiting for it if this process has
16379        // gone bad.
16380        boolean restart = false;
16381        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16382            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16383            if (cpr.launchingApp == app) {
16384                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16385                    restart = true;
16386                } else {
16387                    removeDyingProviderLocked(app, cpr, true);
16388                }
16389            }
16390        }
16391        return restart;
16392    }
16393
16394    // =========================================================
16395    // SERVICES
16396    // =========================================================
16397
16398    @Override
16399    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16400            int flags) {
16401        enforceNotIsolatedCaller("getServices");
16402        synchronized (this) {
16403            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16404        }
16405    }
16406
16407    @Override
16408    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16409        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16410        synchronized (this) {
16411            return mServices.getRunningServiceControlPanelLocked(name);
16412        }
16413    }
16414
16415    @Override
16416    public ComponentName startService(IApplicationThread caller, Intent service,
16417            String resolvedType, String callingPackage, int userId)
16418            throws TransactionTooLargeException {
16419        enforceNotIsolatedCaller("startService");
16420        // Refuse possible leaked file descriptors
16421        if (service != null && service.hasFileDescriptors() == true) {
16422            throw new IllegalArgumentException("File descriptors passed in Intent");
16423        }
16424
16425        if (callingPackage == null) {
16426            throw new IllegalArgumentException("callingPackage cannot be null");
16427        }
16428
16429        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16430                "startService: " + service + " type=" + resolvedType);
16431        synchronized(this) {
16432            final int callingPid = Binder.getCallingPid();
16433            final int callingUid = Binder.getCallingUid();
16434            final long origId = Binder.clearCallingIdentity();
16435            ComponentName res = mServices.startServiceLocked(caller, service,
16436                    resolvedType, callingPid, callingUid, callingPackage, userId);
16437            Binder.restoreCallingIdentity(origId);
16438            return res;
16439        }
16440    }
16441
16442    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16443            String callingPackage, int userId)
16444            throws TransactionTooLargeException {
16445        synchronized(this) {
16446            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16447                    "startServiceInPackage: " + service + " type=" + resolvedType);
16448            final long origId = Binder.clearCallingIdentity();
16449            ComponentName res = mServices.startServiceLocked(null, service,
16450                    resolvedType, -1, uid, callingPackage, userId);
16451            Binder.restoreCallingIdentity(origId);
16452            return res;
16453        }
16454    }
16455
16456    @Override
16457    public int stopService(IApplicationThread caller, Intent service,
16458            String resolvedType, int userId) {
16459        enforceNotIsolatedCaller("stopService");
16460        // Refuse possible leaked file descriptors
16461        if (service != null && service.hasFileDescriptors() == true) {
16462            throw new IllegalArgumentException("File descriptors passed in Intent");
16463        }
16464
16465        synchronized(this) {
16466            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16467        }
16468    }
16469
16470    @Override
16471    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16472        enforceNotIsolatedCaller("peekService");
16473        // Refuse possible leaked file descriptors
16474        if (service != null && service.hasFileDescriptors() == true) {
16475            throw new IllegalArgumentException("File descriptors passed in Intent");
16476        }
16477
16478        if (callingPackage == null) {
16479            throw new IllegalArgumentException("callingPackage cannot be null");
16480        }
16481
16482        synchronized(this) {
16483            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16484        }
16485    }
16486
16487    @Override
16488    public boolean stopServiceToken(ComponentName className, IBinder token,
16489            int startId) {
16490        synchronized(this) {
16491            return mServices.stopServiceTokenLocked(className, token, startId);
16492        }
16493    }
16494
16495    @Override
16496    public void setServiceForeground(ComponentName className, IBinder token,
16497            int id, Notification notification, int flags) {
16498        synchronized(this) {
16499            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16500        }
16501    }
16502
16503    @Override
16504    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16505            boolean requireFull, String name, String callerPackage) {
16506        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16507                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16508    }
16509
16510    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16511            String className, int flags) {
16512        boolean result = false;
16513        // For apps that don't have pre-defined UIDs, check for permission
16514        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16515            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16516                if (ActivityManager.checkUidPermission(
16517                        INTERACT_ACROSS_USERS,
16518                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16519                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16520                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16521                            + " requests FLAG_SINGLE_USER, but app does not hold "
16522                            + INTERACT_ACROSS_USERS;
16523                    Slog.w(TAG, msg);
16524                    throw new SecurityException(msg);
16525                }
16526                // Permission passed
16527                result = true;
16528            }
16529        } else if ("system".equals(componentProcessName)) {
16530            result = true;
16531        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16532            // Phone app and persistent apps are allowed to export singleuser providers.
16533            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16534                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16535        }
16536        if (DEBUG_MU) Slog.v(TAG_MU,
16537                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16538                + Integer.toHexString(flags) + ") = " + result);
16539        return result;
16540    }
16541
16542    /**
16543     * Checks to see if the caller is in the same app as the singleton
16544     * component, or the component is in a special app. It allows special apps
16545     * to export singleton components but prevents exporting singleton
16546     * components for regular apps.
16547     */
16548    boolean isValidSingletonCall(int callingUid, int componentUid) {
16549        int componentAppId = UserHandle.getAppId(componentUid);
16550        return UserHandle.isSameApp(callingUid, componentUid)
16551                || componentAppId == Process.SYSTEM_UID
16552                || componentAppId == Process.PHONE_UID
16553                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16554                        == PackageManager.PERMISSION_GRANTED;
16555    }
16556
16557    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16558            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16559            int userId) throws TransactionTooLargeException {
16560        enforceNotIsolatedCaller("bindService");
16561
16562        // Refuse possible leaked file descriptors
16563        if (service != null && service.hasFileDescriptors() == true) {
16564            throw new IllegalArgumentException("File descriptors passed in Intent");
16565        }
16566
16567        if (callingPackage == null) {
16568            throw new IllegalArgumentException("callingPackage cannot be null");
16569        }
16570
16571        synchronized(this) {
16572            return mServices.bindServiceLocked(caller, token, service,
16573                    resolvedType, connection, flags, callingPackage, userId);
16574        }
16575    }
16576
16577    public boolean unbindService(IServiceConnection connection) {
16578        synchronized (this) {
16579            return mServices.unbindServiceLocked(connection);
16580        }
16581    }
16582
16583    public void publishService(IBinder token, Intent intent, IBinder service) {
16584        // Refuse possible leaked file descriptors
16585        if (intent != null && intent.hasFileDescriptors() == true) {
16586            throw new IllegalArgumentException("File descriptors passed in Intent");
16587        }
16588
16589        synchronized(this) {
16590            if (!(token instanceof ServiceRecord)) {
16591                throw new IllegalArgumentException("Invalid service token");
16592            }
16593            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16594        }
16595    }
16596
16597    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16598        // Refuse possible leaked file descriptors
16599        if (intent != null && intent.hasFileDescriptors() == true) {
16600            throw new IllegalArgumentException("File descriptors passed in Intent");
16601        }
16602
16603        synchronized(this) {
16604            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16605        }
16606    }
16607
16608    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16609        synchronized(this) {
16610            if (!(token instanceof ServiceRecord)) {
16611                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16612                throw new IllegalArgumentException("Invalid service token");
16613            }
16614            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16615        }
16616    }
16617
16618    // =========================================================
16619    // BACKUP AND RESTORE
16620    // =========================================================
16621
16622    // Cause the target app to be launched if necessary and its backup agent
16623    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16624    // activity manager to announce its creation.
16625    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16626        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16627                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16628        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16629
16630        synchronized(this) {
16631            // !!! TODO: currently no check here that we're already bound
16632            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16633            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16634            synchronized (stats) {
16635                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16636            }
16637
16638            // Backup agent is now in use, its package can't be stopped.
16639            try {
16640                AppGlobals.getPackageManager().setPackageStoppedState(
16641                        app.packageName, false, UserHandle.getUserId(app.uid));
16642            } catch (RemoteException e) {
16643            } catch (IllegalArgumentException e) {
16644                Slog.w(TAG, "Failed trying to unstop package "
16645                        + app.packageName + ": " + e);
16646            }
16647
16648            BackupRecord r = new BackupRecord(ss, app, backupMode);
16649            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16650                    ? new ComponentName(app.packageName, app.backupAgentName)
16651                    : new ComponentName("android", "FullBackupAgent");
16652            // startProcessLocked() returns existing proc's record if it's already running
16653            ProcessRecord proc = startProcessLocked(app.processName, app,
16654                    false, 0, "backup", hostingName, false, false, false);
16655            if (proc == null) {
16656                Slog.e(TAG, "Unable to start backup agent process " + r);
16657                return false;
16658            }
16659
16660            r.app = proc;
16661            mBackupTarget = r;
16662            mBackupAppName = app.packageName;
16663
16664            // Try not to kill the process during backup
16665            updateOomAdjLocked(proc);
16666
16667            // If the process is already attached, schedule the creation of the backup agent now.
16668            // If it is not yet live, this will be done when it attaches to the framework.
16669            if (proc.thread != null) {
16670                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16671                try {
16672                    proc.thread.scheduleCreateBackupAgent(app,
16673                            compatibilityInfoForPackageLocked(app), backupMode);
16674                } catch (RemoteException e) {
16675                    // Will time out on the backup manager side
16676                }
16677            } else {
16678                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16679            }
16680            // Invariants: at this point, the target app process exists and the application
16681            // is either already running or in the process of coming up.  mBackupTarget and
16682            // mBackupAppName describe the app, so that when it binds back to the AM we
16683            // know that it's scheduled for a backup-agent operation.
16684        }
16685
16686        return true;
16687    }
16688
16689    @Override
16690    public void clearPendingBackup() {
16691        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16692        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16693
16694        synchronized (this) {
16695            mBackupTarget = null;
16696            mBackupAppName = null;
16697        }
16698    }
16699
16700    // A backup agent has just come up
16701    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16702        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16703                + " = " + agent);
16704
16705        synchronized(this) {
16706            if (!agentPackageName.equals(mBackupAppName)) {
16707                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16708                return;
16709            }
16710        }
16711
16712        long oldIdent = Binder.clearCallingIdentity();
16713        try {
16714            IBackupManager bm = IBackupManager.Stub.asInterface(
16715                    ServiceManager.getService(Context.BACKUP_SERVICE));
16716            bm.agentConnected(agentPackageName, agent);
16717        } catch (RemoteException e) {
16718            // can't happen; the backup manager service is local
16719        } catch (Exception e) {
16720            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16721            e.printStackTrace();
16722        } finally {
16723            Binder.restoreCallingIdentity(oldIdent);
16724        }
16725    }
16726
16727    // done with this agent
16728    public void unbindBackupAgent(ApplicationInfo appInfo) {
16729        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16730        if (appInfo == null) {
16731            Slog.w(TAG, "unbind backup agent for null app");
16732            return;
16733        }
16734
16735        synchronized(this) {
16736            try {
16737                if (mBackupAppName == null) {
16738                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16739                    return;
16740                }
16741
16742                if (!mBackupAppName.equals(appInfo.packageName)) {
16743                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16744                    return;
16745                }
16746
16747                // Not backing this app up any more; reset its OOM adjustment
16748                final ProcessRecord proc = mBackupTarget.app;
16749                updateOomAdjLocked(proc);
16750
16751                // If the app crashed during backup, 'thread' will be null here
16752                if (proc.thread != null) {
16753                    try {
16754                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16755                                compatibilityInfoForPackageLocked(appInfo));
16756                    } catch (Exception e) {
16757                        Slog.e(TAG, "Exception when unbinding backup agent:");
16758                        e.printStackTrace();
16759                    }
16760                }
16761            } finally {
16762                mBackupTarget = null;
16763                mBackupAppName = null;
16764            }
16765        }
16766    }
16767    // =========================================================
16768    // BROADCASTS
16769    // =========================================================
16770
16771    boolean isPendingBroadcastProcessLocked(int pid) {
16772        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16773                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16774    }
16775
16776    void skipPendingBroadcastLocked(int pid) {
16777            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16778            for (BroadcastQueue queue : mBroadcastQueues) {
16779                queue.skipPendingBroadcastLocked(pid);
16780            }
16781    }
16782
16783    // The app just attached; send any pending broadcasts that it should receive
16784    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16785        boolean didSomething = false;
16786        for (BroadcastQueue queue : mBroadcastQueues) {
16787            didSomething |= queue.sendPendingBroadcastsLocked(app);
16788        }
16789        return didSomething;
16790    }
16791
16792    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16793            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16794        enforceNotIsolatedCaller("registerReceiver");
16795        ArrayList<Intent> stickyIntents = null;
16796        ProcessRecord callerApp = null;
16797        int callingUid;
16798        int callingPid;
16799        synchronized(this) {
16800            if (caller != null) {
16801                callerApp = getRecordForAppLocked(caller);
16802                if (callerApp == null) {
16803                    throw new SecurityException(
16804                            "Unable to find app for caller " + caller
16805                            + " (pid=" + Binder.getCallingPid()
16806                            + ") when registering receiver " + receiver);
16807                }
16808                if (callerApp.info.uid != Process.SYSTEM_UID &&
16809                        !callerApp.pkgList.containsKey(callerPackage) &&
16810                        !"android".equals(callerPackage)) {
16811                    throw new SecurityException("Given caller package " + callerPackage
16812                            + " is not running in process " + callerApp);
16813                }
16814                callingUid = callerApp.info.uid;
16815                callingPid = callerApp.pid;
16816            } else {
16817                callerPackage = null;
16818                callingUid = Binder.getCallingUid();
16819                callingPid = Binder.getCallingPid();
16820            }
16821
16822            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16823                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16824
16825            Iterator<String> actions = filter.actionsIterator();
16826            if (actions == null) {
16827                ArrayList<String> noAction = new ArrayList<String>(1);
16828                noAction.add(null);
16829                actions = noAction.iterator();
16830            }
16831
16832            // Collect stickies of users
16833            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16834            while (actions.hasNext()) {
16835                String action = actions.next();
16836                for (int id : userIds) {
16837                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16838                    if (stickies != null) {
16839                        ArrayList<Intent> intents = stickies.get(action);
16840                        if (intents != null) {
16841                            if (stickyIntents == null) {
16842                                stickyIntents = new ArrayList<Intent>();
16843                            }
16844                            stickyIntents.addAll(intents);
16845                        }
16846                    }
16847                }
16848            }
16849        }
16850
16851        ArrayList<Intent> allSticky = null;
16852        if (stickyIntents != null) {
16853            final ContentResolver resolver = mContext.getContentResolver();
16854            // Look for any matching sticky broadcasts...
16855            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16856                Intent intent = stickyIntents.get(i);
16857                // If intent has scheme "content", it will need to acccess
16858                // provider that needs to lock mProviderMap in ActivityThread
16859                // and also it may need to wait application response, so we
16860                // cannot lock ActivityManagerService here.
16861                if (filter.match(resolver, intent, true, TAG) >= 0) {
16862                    if (allSticky == null) {
16863                        allSticky = new ArrayList<Intent>();
16864                    }
16865                    allSticky.add(intent);
16866                }
16867            }
16868        }
16869
16870        // The first sticky in the list is returned directly back to the client.
16871        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16872        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16873        if (receiver == null) {
16874            return sticky;
16875        }
16876
16877        synchronized (this) {
16878            if (callerApp != null && (callerApp.thread == null
16879                    || callerApp.thread.asBinder() != caller.asBinder())) {
16880                // Original caller already died
16881                return null;
16882            }
16883            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16884            if (rl == null) {
16885                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16886                        userId, receiver);
16887                if (rl.app != null) {
16888                    rl.app.receivers.add(rl);
16889                } else {
16890                    try {
16891                        receiver.asBinder().linkToDeath(rl, 0);
16892                    } catch (RemoteException e) {
16893                        return sticky;
16894                    }
16895                    rl.linkedToDeath = true;
16896                }
16897                mRegisteredReceivers.put(receiver.asBinder(), rl);
16898            } else if (rl.uid != callingUid) {
16899                throw new IllegalArgumentException(
16900                        "Receiver requested to register for uid " + callingUid
16901                        + " was previously registered for uid " + rl.uid);
16902            } else if (rl.pid != callingPid) {
16903                throw new IllegalArgumentException(
16904                        "Receiver requested to register for pid " + callingPid
16905                        + " was previously registered for pid " + rl.pid);
16906            } else if (rl.userId != userId) {
16907                throw new IllegalArgumentException(
16908                        "Receiver requested to register for user " + userId
16909                        + " was previously registered for user " + rl.userId);
16910            }
16911            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16912                    permission, callingUid, userId);
16913            rl.add(bf);
16914            if (!bf.debugCheck()) {
16915                Slog.w(TAG, "==> For Dynamic broadcast");
16916            }
16917            mReceiverResolver.addFilter(bf);
16918
16919            // Enqueue broadcasts for all existing stickies that match
16920            // this filter.
16921            if (allSticky != null) {
16922                ArrayList receivers = new ArrayList();
16923                receivers.add(bf);
16924
16925                final int stickyCount = allSticky.size();
16926                for (int i = 0; i < stickyCount; i++) {
16927                    Intent intent = allSticky.get(i);
16928                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16929                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16930                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16931                            null, 0, null, null, false, true, true, -1);
16932                    queue.enqueueParallelBroadcastLocked(r);
16933                    queue.scheduleBroadcastsLocked();
16934                }
16935            }
16936
16937            return sticky;
16938        }
16939    }
16940
16941    public void unregisterReceiver(IIntentReceiver receiver) {
16942        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16943
16944        final long origId = Binder.clearCallingIdentity();
16945        try {
16946            boolean doTrim = false;
16947
16948            synchronized(this) {
16949                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16950                if (rl != null) {
16951                    final BroadcastRecord r = rl.curBroadcast;
16952                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16953                        final boolean doNext = r.queue.finishReceiverLocked(
16954                                r, r.resultCode, r.resultData, r.resultExtras,
16955                                r.resultAbort, false);
16956                        if (doNext) {
16957                            doTrim = true;
16958                            r.queue.processNextBroadcast(false);
16959                        }
16960                    }
16961
16962                    if (rl.app != null) {
16963                        rl.app.receivers.remove(rl);
16964                    }
16965                    removeReceiverLocked(rl);
16966                    if (rl.linkedToDeath) {
16967                        rl.linkedToDeath = false;
16968                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16969                    }
16970                }
16971            }
16972
16973            // If we actually concluded any broadcasts, we might now be able
16974            // to trim the recipients' apps from our working set
16975            if (doTrim) {
16976                trimApplications();
16977                return;
16978            }
16979
16980        } finally {
16981            Binder.restoreCallingIdentity(origId);
16982        }
16983    }
16984
16985    void removeReceiverLocked(ReceiverList rl) {
16986        mRegisteredReceivers.remove(rl.receiver.asBinder());
16987        for (int i = rl.size() - 1; i >= 0; i--) {
16988            mReceiverResolver.removeFilter(rl.get(i));
16989        }
16990    }
16991
16992    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16993        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16994            ProcessRecord r = mLruProcesses.get(i);
16995            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16996                try {
16997                    r.thread.dispatchPackageBroadcast(cmd, packages);
16998                } catch (RemoteException ex) {
16999                }
17000            }
17001        }
17002    }
17003
17004    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17005            int callingUid, int[] users) {
17006        // TODO: come back and remove this assumption to triage all broadcasts
17007        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17008
17009        List<ResolveInfo> receivers = null;
17010        try {
17011            HashSet<ComponentName> singleUserReceivers = null;
17012            boolean scannedFirstReceivers = false;
17013            for (int user : users) {
17014                // Skip users that have Shell restrictions, with exception of always permitted
17015                // Shell broadcasts
17016                if (callingUid == Process.SHELL_UID
17017                        && mUserController.hasUserRestriction(
17018                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17019                        && !isPermittedShellBroadcast(intent)) {
17020                    continue;
17021                }
17022                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17023                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17024                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17025                    // If this is not the system user, we need to check for
17026                    // any receivers that should be filtered out.
17027                    for (int i=0; i<newReceivers.size(); i++) {
17028                        ResolveInfo ri = newReceivers.get(i);
17029                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17030                            newReceivers.remove(i);
17031                            i--;
17032                        }
17033                    }
17034                }
17035                if (newReceivers != null && newReceivers.size() == 0) {
17036                    newReceivers = null;
17037                }
17038                if (receivers == null) {
17039                    receivers = newReceivers;
17040                } else if (newReceivers != null) {
17041                    // We need to concatenate the additional receivers
17042                    // found with what we have do far.  This would be easy,
17043                    // but we also need to de-dup any receivers that are
17044                    // singleUser.
17045                    if (!scannedFirstReceivers) {
17046                        // Collect any single user receivers we had already retrieved.
17047                        scannedFirstReceivers = true;
17048                        for (int i=0; i<receivers.size(); i++) {
17049                            ResolveInfo ri = receivers.get(i);
17050                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17051                                ComponentName cn = new ComponentName(
17052                                        ri.activityInfo.packageName, ri.activityInfo.name);
17053                                if (singleUserReceivers == null) {
17054                                    singleUserReceivers = new HashSet<ComponentName>();
17055                                }
17056                                singleUserReceivers.add(cn);
17057                            }
17058                        }
17059                    }
17060                    // Add the new results to the existing results, tracking
17061                    // and de-dupping single user receivers.
17062                    for (int i=0; i<newReceivers.size(); i++) {
17063                        ResolveInfo ri = newReceivers.get(i);
17064                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17065                            ComponentName cn = new ComponentName(
17066                                    ri.activityInfo.packageName, ri.activityInfo.name);
17067                            if (singleUserReceivers == null) {
17068                                singleUserReceivers = new HashSet<ComponentName>();
17069                            }
17070                            if (!singleUserReceivers.contains(cn)) {
17071                                singleUserReceivers.add(cn);
17072                                receivers.add(ri);
17073                            }
17074                        } else {
17075                            receivers.add(ri);
17076                        }
17077                    }
17078                }
17079            }
17080        } catch (RemoteException ex) {
17081            // pm is in same process, this will never happen.
17082        }
17083        return receivers;
17084    }
17085
17086    private boolean isPermittedShellBroadcast(Intent intent) {
17087        // remote bugreport should always be allowed to be taken
17088        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17089    }
17090
17091    final int broadcastIntentLocked(ProcessRecord callerApp,
17092            String callerPackage, Intent intent, String resolvedType,
17093            IIntentReceiver resultTo, int resultCode, String resultData,
17094            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17095            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17096        intent = new Intent(intent);
17097
17098        // By default broadcasts do not go to stopped apps.
17099        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17100
17101        // If we have not finished booting, don't allow this to launch new processes.
17102        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17103            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17104        }
17105
17106        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17107                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17108                + " ordered=" + ordered + " userid=" + userId);
17109        if ((resultTo != null) && !ordered) {
17110            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17111        }
17112
17113        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17114                ALLOW_NON_FULL, "broadcast", callerPackage);
17115
17116        // Make sure that the user who is receiving this broadcast is running.
17117        // If not, we will just skip it. Make an exception for shutdown broadcasts
17118        // and upgrade steps.
17119
17120        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17121            if ((callingUid != Process.SYSTEM_UID
17122                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17123                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17124                Slog.w(TAG, "Skipping broadcast of " + intent
17125                        + ": user " + userId + " is stopped");
17126                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17127            }
17128        }
17129
17130        BroadcastOptions brOptions = null;
17131        if (bOptions != null) {
17132            brOptions = new BroadcastOptions(bOptions);
17133            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17134                // See if the caller is allowed to do this.  Note we are checking against
17135                // the actual real caller (not whoever provided the operation as say a
17136                // PendingIntent), because that who is actually supplied the arguments.
17137                if (checkComponentPermission(
17138                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17139                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17140                        != PackageManager.PERMISSION_GRANTED) {
17141                    String msg = "Permission Denial: " + intent.getAction()
17142                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17143                            + ", uid=" + callingUid + ")"
17144                            + " requires "
17145                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17146                    Slog.w(TAG, msg);
17147                    throw new SecurityException(msg);
17148                }
17149            }
17150        }
17151
17152        // Verify that protected broadcasts are only being sent by system code,
17153        // and that system code is only sending protected broadcasts.
17154        final String action = intent.getAction();
17155        final boolean isProtectedBroadcast;
17156        try {
17157            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17158        } catch (RemoteException e) {
17159            Slog.w(TAG, "Remote exception", e);
17160            return ActivityManager.BROADCAST_SUCCESS;
17161        }
17162
17163        final boolean isCallerSystem;
17164        switch (UserHandle.getAppId(callingUid)) {
17165            case Process.ROOT_UID:
17166            case Process.SYSTEM_UID:
17167            case Process.PHONE_UID:
17168            case Process.BLUETOOTH_UID:
17169            case Process.NFC_UID:
17170                isCallerSystem = true;
17171                break;
17172            default:
17173                isCallerSystem = (callerApp != null) && callerApp.persistent;
17174                break;
17175        }
17176
17177        if (isCallerSystem) {
17178            if (isProtectedBroadcast
17179                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17180                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17181                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17182                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17183                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17184                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17185                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17186                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17187                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17188                // Broadcast is either protected, or it's a public action that
17189                // we've relaxed, so it's fine for system internals to send.
17190            } else {
17191                // The vast majority of broadcasts sent from system internals
17192                // should be protected to avoid security holes, so yell loudly
17193                // to ensure we examine these cases.
17194                Log.wtf(TAG, "Sending non-protected broadcast " + action
17195                        + " from system", new Throwable());
17196            }
17197
17198        } else {
17199            if (isProtectedBroadcast) {
17200                String msg = "Permission Denial: not allowed to send broadcast "
17201                        + action + " from pid="
17202                        + callingPid + ", uid=" + callingUid;
17203                Slog.w(TAG, msg);
17204                throw new SecurityException(msg);
17205
17206            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17207                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17208                // Special case for compatibility: we don't want apps to send this,
17209                // but historically it has not been protected and apps may be using it
17210                // to poke their own app widget.  So, instead of making it protected,
17211                // just limit it to the caller.
17212                if (callerPackage == null) {
17213                    String msg = "Permission Denial: not allowed to send broadcast "
17214                            + action + " from unknown caller.";
17215                    Slog.w(TAG, msg);
17216                    throw new SecurityException(msg);
17217                } else if (intent.getComponent() != null) {
17218                    // They are good enough to send to an explicit component...  verify
17219                    // it is being sent to the calling app.
17220                    if (!intent.getComponent().getPackageName().equals(
17221                            callerPackage)) {
17222                        String msg = "Permission Denial: not allowed to send broadcast "
17223                                + action + " to "
17224                                + intent.getComponent().getPackageName() + " from "
17225                                + callerPackage;
17226                        Slog.w(TAG, msg);
17227                        throw new SecurityException(msg);
17228                    }
17229                } else {
17230                    // Limit broadcast to their own package.
17231                    intent.setPackage(callerPackage);
17232                }
17233            }
17234        }
17235
17236        if (action != null) {
17237            switch (action) {
17238                case Intent.ACTION_UID_REMOVED:
17239                case Intent.ACTION_PACKAGE_REMOVED:
17240                case Intent.ACTION_PACKAGE_CHANGED:
17241                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17242                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17243                case Intent.ACTION_PACKAGES_SUSPENDED:
17244                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17245                    // Handle special intents: if this broadcast is from the package
17246                    // manager about a package being removed, we need to remove all of
17247                    // its activities from the history stack.
17248                    if (checkComponentPermission(
17249                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17250                            callingPid, callingUid, -1, true)
17251                            != PackageManager.PERMISSION_GRANTED) {
17252                        String msg = "Permission Denial: " + intent.getAction()
17253                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17254                                + ", uid=" + callingUid + ")"
17255                                + " requires "
17256                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17257                        Slog.w(TAG, msg);
17258                        throw new SecurityException(msg);
17259                    }
17260                    switch (action) {
17261                        case Intent.ACTION_UID_REMOVED:
17262                            final Bundle intentExtras = intent.getExtras();
17263                            final int uid = intentExtras != null
17264                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17265                            if (uid >= 0) {
17266                                mBatteryStatsService.removeUid(uid);
17267                                mAppOpsService.uidRemoved(uid);
17268                            }
17269                            break;
17270                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17271                            // If resources are unavailable just force stop all those packages
17272                            // and flush the attribute cache as well.
17273                            String list[] =
17274                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17275                            if (list != null && list.length > 0) {
17276                                for (int i = 0; i < list.length; i++) {
17277                                    forceStopPackageLocked(list[i], -1, false, true, true,
17278                                            false, false, userId, "storage unmount");
17279                                }
17280                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17281                                sendPackageBroadcastLocked(
17282                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17283                                        userId);
17284                            }
17285                            break;
17286                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17287                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17288                            break;
17289                        case Intent.ACTION_PACKAGE_REMOVED:
17290                        case Intent.ACTION_PACKAGE_CHANGED:
17291                            Uri data = intent.getData();
17292                            String ssp;
17293                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17294                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17295                                final boolean replacing =
17296                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17297                                final boolean killProcess =
17298                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17299                                final boolean fullUninstall = removed && !replacing;
17300                                if (killProcess) {
17301                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17302                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17303                                            false, true, true, false, fullUninstall, userId,
17304                                            removed ? "pkg removed" : "pkg changed");
17305                                }
17306                                if (removed) {
17307                                    final int cmd = killProcess
17308                                            ? IApplicationThread.PACKAGE_REMOVED
17309                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17310                                    sendPackageBroadcastLocked(cmd,
17311                                            new String[] {ssp}, userId);
17312                                    if (fullUninstall) {
17313                                        mAppOpsService.packageRemoved(
17314                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17315
17316                                        // Remove all permissions granted from/to this package
17317                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17318
17319                                        removeTasksByPackageNameLocked(ssp, userId);
17320                                        mBatteryStatsService.notePackageUninstalled(ssp);
17321                                    }
17322                                } else {
17323                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17324                                            intent.getStringArrayExtra(
17325                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17326                                }
17327                            }
17328                            break;
17329                        case Intent.ACTION_PACKAGES_SUSPENDED:
17330                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17331                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17332                                    intent.getAction());
17333                            final String[] packageNames = intent.getStringArrayExtra(
17334                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17335                            final int userHandle = intent.getIntExtra(
17336                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17337
17338                            synchronized(ActivityManagerService.this) {
17339                                mRecentTasks.onPackagesSuspendedChanged(
17340                                        packageNames, suspended, userHandle);
17341                            }
17342                            break;
17343                    }
17344                    break;
17345                case Intent.ACTION_PACKAGE_REPLACED:
17346                {
17347                    final Uri data = intent.getData();
17348                    final String ssp;
17349                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17350                        final ApplicationInfo aInfo =
17351                                getPackageManagerInternalLocked().getApplicationInfo(
17352                                        ssp,
17353                                        userId);
17354                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17355                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17356                                new String[] {ssp}, userId);
17357                    }
17358                    break;
17359                }
17360                case Intent.ACTION_PACKAGE_ADDED:
17361                {
17362                    // Special case for adding a package: by default turn on compatibility mode.
17363                    Uri data = intent.getData();
17364                    String ssp;
17365                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17366                        final boolean replacing =
17367                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17368                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17369
17370                        try {
17371                            ApplicationInfo ai = AppGlobals.getPackageManager().
17372                                    getApplicationInfo(ssp, 0, 0);
17373                            mBatteryStatsService.notePackageInstalled(ssp,
17374                                    ai != null ? ai.versionCode : 0);
17375                        } catch (RemoteException e) {
17376                        }
17377                    }
17378                    break;
17379                }
17380                case Intent.ACTION_TIMEZONE_CHANGED:
17381                    // If this is the time zone changed action, queue up a message that will reset
17382                    // the timezone of all currently running processes. This message will get
17383                    // queued up before the broadcast happens.
17384                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17385                    break;
17386                case Intent.ACTION_TIME_CHANGED:
17387                    // If the user set the time, let all running processes know.
17388                    final int is24Hour =
17389                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17390                                    : 0;
17391                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17392                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17393                    synchronized (stats) {
17394                        stats.noteCurrentTimeChangedLocked();
17395                    }
17396                    break;
17397                case Intent.ACTION_CLEAR_DNS_CACHE:
17398                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17399                    break;
17400                case Proxy.PROXY_CHANGE_ACTION:
17401                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17402                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17403                    break;
17404                case android.hardware.Camera.ACTION_NEW_PICTURE:
17405                case android.hardware.Camera.ACTION_NEW_VIDEO:
17406                    // These broadcasts are no longer allowed by the system, since they can
17407                    // cause significant thrashing at a crictical point (using the camera).
17408                    // Apps should use JobScehduler to monitor for media provider changes.
17409                    Slog.w(TAG, action + " no longer allowed; dropping from "
17410                            + UserHandle.formatUid(callingUid));
17411                    // Lie; we don't want to crash the app.
17412                    return ActivityManager.BROADCAST_SUCCESS;
17413            }
17414        }
17415
17416        // Add to the sticky list if requested.
17417        if (sticky) {
17418            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17419                    callingPid, callingUid)
17420                    != PackageManager.PERMISSION_GRANTED) {
17421                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17422                        + callingPid + ", uid=" + callingUid
17423                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17424                Slog.w(TAG, msg);
17425                throw new SecurityException(msg);
17426            }
17427            if (requiredPermissions != null && requiredPermissions.length > 0) {
17428                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17429                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17430                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17431            }
17432            if (intent.getComponent() != null) {
17433                throw new SecurityException(
17434                        "Sticky broadcasts can't target a specific component");
17435            }
17436            // We use userId directly here, since the "all" target is maintained
17437            // as a separate set of sticky broadcasts.
17438            if (userId != UserHandle.USER_ALL) {
17439                // But first, if this is not a broadcast to all users, then
17440                // make sure it doesn't conflict with an existing broadcast to
17441                // all users.
17442                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17443                        UserHandle.USER_ALL);
17444                if (stickies != null) {
17445                    ArrayList<Intent> list = stickies.get(intent.getAction());
17446                    if (list != null) {
17447                        int N = list.size();
17448                        int i;
17449                        for (i=0; i<N; i++) {
17450                            if (intent.filterEquals(list.get(i))) {
17451                                throw new IllegalArgumentException(
17452                                        "Sticky broadcast " + intent + " for user "
17453                                        + userId + " conflicts with existing global broadcast");
17454                            }
17455                        }
17456                    }
17457                }
17458            }
17459            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17460            if (stickies == null) {
17461                stickies = new ArrayMap<>();
17462                mStickyBroadcasts.put(userId, stickies);
17463            }
17464            ArrayList<Intent> list = stickies.get(intent.getAction());
17465            if (list == null) {
17466                list = new ArrayList<>();
17467                stickies.put(intent.getAction(), list);
17468            }
17469            final int stickiesCount = list.size();
17470            int i;
17471            for (i = 0; i < stickiesCount; i++) {
17472                if (intent.filterEquals(list.get(i))) {
17473                    // This sticky already exists, replace it.
17474                    list.set(i, new Intent(intent));
17475                    break;
17476                }
17477            }
17478            if (i >= stickiesCount) {
17479                list.add(new Intent(intent));
17480            }
17481        }
17482
17483        int[] users;
17484        if (userId == UserHandle.USER_ALL) {
17485            // Caller wants broadcast to go to all started users.
17486            users = mUserController.getStartedUserArrayLocked();
17487        } else {
17488            // Caller wants broadcast to go to one specific user.
17489            users = new int[] {userId};
17490        }
17491
17492        // Figure out who all will receive this broadcast.
17493        List receivers = null;
17494        List<BroadcastFilter> registeredReceivers = null;
17495        // Need to resolve the intent to interested receivers...
17496        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17497                 == 0) {
17498            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17499        }
17500        if (intent.getComponent() == null) {
17501            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17502                // Query one target user at a time, excluding shell-restricted users
17503                for (int i = 0; i < users.length; i++) {
17504                    if (mUserController.hasUserRestriction(
17505                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17506                        continue;
17507                    }
17508                    List<BroadcastFilter> registeredReceiversForUser =
17509                            mReceiverResolver.queryIntent(intent,
17510                                    resolvedType, false, users[i]);
17511                    if (registeredReceivers == null) {
17512                        registeredReceivers = registeredReceiversForUser;
17513                    } else if (registeredReceiversForUser != null) {
17514                        registeredReceivers.addAll(registeredReceiversForUser);
17515                    }
17516                }
17517            } else {
17518                registeredReceivers = mReceiverResolver.queryIntent(intent,
17519                        resolvedType, false, userId);
17520            }
17521        }
17522
17523        final boolean replacePending =
17524                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17525
17526        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17527                + " replacePending=" + replacePending);
17528
17529        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17530        if (!ordered && NR > 0) {
17531            // If we are not serializing this broadcast, then send the
17532            // registered receivers separately so they don't wait for the
17533            // components to be launched.
17534            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17535            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17536                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17537                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17538                    resultExtras, ordered, sticky, false, userId);
17539            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17540            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17541            if (!replaced) {
17542                queue.enqueueParallelBroadcastLocked(r);
17543                queue.scheduleBroadcastsLocked();
17544            }
17545            registeredReceivers = null;
17546            NR = 0;
17547        }
17548
17549        // Merge into one list.
17550        int ir = 0;
17551        if (receivers != null) {
17552            // A special case for PACKAGE_ADDED: do not allow the package
17553            // being added to see this broadcast.  This prevents them from
17554            // using this as a back door to get run as soon as they are
17555            // installed.  Maybe in the future we want to have a special install
17556            // broadcast or such for apps, but we'd like to deliberately make
17557            // this decision.
17558            String skipPackages[] = null;
17559            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17560                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17561                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17562                Uri data = intent.getData();
17563                if (data != null) {
17564                    String pkgName = data.getSchemeSpecificPart();
17565                    if (pkgName != null) {
17566                        skipPackages = new String[] { pkgName };
17567                    }
17568                }
17569            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17570                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17571            }
17572            if (skipPackages != null && (skipPackages.length > 0)) {
17573                for (String skipPackage : skipPackages) {
17574                    if (skipPackage != null) {
17575                        int NT = receivers.size();
17576                        for (int it=0; it<NT; it++) {
17577                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17578                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17579                                receivers.remove(it);
17580                                it--;
17581                                NT--;
17582                            }
17583                        }
17584                    }
17585                }
17586            }
17587
17588            int NT = receivers != null ? receivers.size() : 0;
17589            int it = 0;
17590            ResolveInfo curt = null;
17591            BroadcastFilter curr = null;
17592            while (it < NT && ir < NR) {
17593                if (curt == null) {
17594                    curt = (ResolveInfo)receivers.get(it);
17595                }
17596                if (curr == null) {
17597                    curr = registeredReceivers.get(ir);
17598                }
17599                if (curr.getPriority() >= curt.priority) {
17600                    // Insert this broadcast record into the final list.
17601                    receivers.add(it, curr);
17602                    ir++;
17603                    curr = null;
17604                    it++;
17605                    NT++;
17606                } else {
17607                    // Skip to the next ResolveInfo in the final list.
17608                    it++;
17609                    curt = null;
17610                }
17611            }
17612        }
17613        while (ir < NR) {
17614            if (receivers == null) {
17615                receivers = new ArrayList();
17616            }
17617            receivers.add(registeredReceivers.get(ir));
17618            ir++;
17619        }
17620
17621        if ((receivers != null && receivers.size() > 0)
17622                || resultTo != null) {
17623            BroadcastQueue queue = broadcastQueueForIntent(intent);
17624            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17625                    callerPackage, callingPid, callingUid, resolvedType,
17626                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17627                    resultData, resultExtras, ordered, sticky, false, userId);
17628
17629            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17630                    + ": prev had " + queue.mOrderedBroadcasts.size());
17631            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17632                    "Enqueueing broadcast " + r.intent.getAction());
17633
17634            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17635            if (!replaced) {
17636                queue.enqueueOrderedBroadcastLocked(r);
17637                queue.scheduleBroadcastsLocked();
17638            }
17639        }
17640
17641        return ActivityManager.BROADCAST_SUCCESS;
17642    }
17643
17644    final Intent verifyBroadcastLocked(Intent intent) {
17645        // Refuse possible leaked file descriptors
17646        if (intent != null && intent.hasFileDescriptors() == true) {
17647            throw new IllegalArgumentException("File descriptors passed in Intent");
17648        }
17649
17650        int flags = intent.getFlags();
17651
17652        if (!mProcessesReady) {
17653            // if the caller really truly claims to know what they're doing, go
17654            // ahead and allow the broadcast without launching any receivers
17655            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17656                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17657            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17658                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17659                        + " before boot completion");
17660                throw new IllegalStateException("Cannot broadcast before boot completed");
17661            }
17662        }
17663
17664        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17665            throw new IllegalArgumentException(
17666                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17667        }
17668
17669        return intent;
17670    }
17671
17672    public final int broadcastIntent(IApplicationThread caller,
17673            Intent intent, String resolvedType, IIntentReceiver resultTo,
17674            int resultCode, String resultData, Bundle resultExtras,
17675            String[] requiredPermissions, int appOp, Bundle bOptions,
17676            boolean serialized, boolean sticky, int userId) {
17677        enforceNotIsolatedCaller("broadcastIntent");
17678        synchronized(this) {
17679            intent = verifyBroadcastLocked(intent);
17680
17681            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17682            final int callingPid = Binder.getCallingPid();
17683            final int callingUid = Binder.getCallingUid();
17684            final long origId = Binder.clearCallingIdentity();
17685            int res = broadcastIntentLocked(callerApp,
17686                    callerApp != null ? callerApp.info.packageName : null,
17687                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17688                    requiredPermissions, appOp, bOptions, serialized, sticky,
17689                    callingPid, callingUid, userId);
17690            Binder.restoreCallingIdentity(origId);
17691            return res;
17692        }
17693    }
17694
17695
17696    int broadcastIntentInPackage(String packageName, int uid,
17697            Intent intent, String resolvedType, IIntentReceiver resultTo,
17698            int resultCode, String resultData, Bundle resultExtras,
17699            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17700            int userId) {
17701        synchronized(this) {
17702            intent = verifyBroadcastLocked(intent);
17703
17704            final long origId = Binder.clearCallingIdentity();
17705            String[] requiredPermissions = requiredPermission == null ? null
17706                    : new String[] {requiredPermission};
17707            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17708                    resultTo, resultCode, resultData, resultExtras,
17709                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17710                    sticky, -1, uid, userId);
17711            Binder.restoreCallingIdentity(origId);
17712            return res;
17713        }
17714    }
17715
17716    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17717        // Refuse possible leaked file descriptors
17718        if (intent != null && intent.hasFileDescriptors() == true) {
17719            throw new IllegalArgumentException("File descriptors passed in Intent");
17720        }
17721
17722        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17723                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17724
17725        synchronized(this) {
17726            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17727                    != PackageManager.PERMISSION_GRANTED) {
17728                String msg = "Permission Denial: unbroadcastIntent() from pid="
17729                        + Binder.getCallingPid()
17730                        + ", uid=" + Binder.getCallingUid()
17731                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17732                Slog.w(TAG, msg);
17733                throw new SecurityException(msg);
17734            }
17735            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17736            if (stickies != null) {
17737                ArrayList<Intent> list = stickies.get(intent.getAction());
17738                if (list != null) {
17739                    int N = list.size();
17740                    int i;
17741                    for (i=0; i<N; i++) {
17742                        if (intent.filterEquals(list.get(i))) {
17743                            list.remove(i);
17744                            break;
17745                        }
17746                    }
17747                    if (list.size() <= 0) {
17748                        stickies.remove(intent.getAction());
17749                    }
17750                }
17751                if (stickies.size() <= 0) {
17752                    mStickyBroadcasts.remove(userId);
17753                }
17754            }
17755        }
17756    }
17757
17758    void backgroundServicesFinishedLocked(int userId) {
17759        for (BroadcastQueue queue : mBroadcastQueues) {
17760            queue.backgroundServicesFinishedLocked(userId);
17761        }
17762    }
17763
17764    public void finishReceiver(IBinder who, int resultCode, String resultData,
17765            Bundle resultExtras, boolean resultAbort, int flags) {
17766        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17767
17768        // Refuse possible leaked file descriptors
17769        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17770            throw new IllegalArgumentException("File descriptors passed in Bundle");
17771        }
17772
17773        final long origId = Binder.clearCallingIdentity();
17774        try {
17775            boolean doNext = false;
17776            BroadcastRecord r;
17777
17778            synchronized(this) {
17779                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17780                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17781                r = queue.getMatchingOrderedReceiver(who);
17782                if (r != null) {
17783                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17784                        resultData, resultExtras, resultAbort, true);
17785                }
17786            }
17787
17788            if (doNext) {
17789                r.queue.processNextBroadcast(false);
17790            }
17791            trimApplications();
17792        } finally {
17793            Binder.restoreCallingIdentity(origId);
17794        }
17795    }
17796
17797    // =========================================================
17798    // INSTRUMENTATION
17799    // =========================================================
17800
17801    public boolean startInstrumentation(ComponentName className,
17802            String profileFile, int flags, Bundle arguments,
17803            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17804            int userId, String abiOverride) {
17805        enforceNotIsolatedCaller("startInstrumentation");
17806        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17807                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17808        // Refuse possible leaked file descriptors
17809        if (arguments != null && arguments.hasFileDescriptors()) {
17810            throw new IllegalArgumentException("File descriptors passed in Bundle");
17811        }
17812
17813        synchronized(this) {
17814            InstrumentationInfo ii = null;
17815            ApplicationInfo ai = null;
17816            try {
17817                ii = mContext.getPackageManager().getInstrumentationInfo(
17818                    className, STOCK_PM_FLAGS);
17819                ai = AppGlobals.getPackageManager().getApplicationInfo(
17820                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17821            } catch (PackageManager.NameNotFoundException e) {
17822            } catch (RemoteException e) {
17823            }
17824            if (ii == null) {
17825                reportStartInstrumentationFailureLocked(watcher, className,
17826                        "Unable to find instrumentation info for: " + className);
17827                return false;
17828            }
17829            if (ai == null) {
17830                reportStartInstrumentationFailureLocked(watcher, className,
17831                        "Unable to find instrumentation target package: " + ii.targetPackage);
17832                return false;
17833            }
17834            if (!ai.hasCode()) {
17835                reportStartInstrumentationFailureLocked(watcher, className,
17836                        "Instrumentation target has no code: " + ii.targetPackage);
17837                return false;
17838            }
17839
17840            int match = mContext.getPackageManager().checkSignatures(
17841                    ii.targetPackage, ii.packageName);
17842            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17843                String msg = "Permission Denial: starting instrumentation "
17844                        + className + " from pid="
17845                        + Binder.getCallingPid()
17846                        + ", uid=" + Binder.getCallingPid()
17847                        + " not allowed because package " + ii.packageName
17848                        + " does not have a signature matching the target "
17849                        + ii.targetPackage;
17850                reportStartInstrumentationFailureLocked(watcher, className, msg);
17851                throw new SecurityException(msg);
17852            }
17853
17854            final long origId = Binder.clearCallingIdentity();
17855            // Instrumentation can kill and relaunch even persistent processes
17856            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17857                    "start instr");
17858            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17859            app.instrumentationClass = className;
17860            app.instrumentationInfo = ai;
17861            app.instrumentationProfileFile = profileFile;
17862            app.instrumentationArguments = arguments;
17863            app.instrumentationWatcher = watcher;
17864            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17865            app.instrumentationResultClass = className;
17866            Binder.restoreCallingIdentity(origId);
17867        }
17868
17869        return true;
17870    }
17871
17872    /**
17873     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17874     * error to the logs, but if somebody is watching, send the report there too.  This enables
17875     * the "am" command to report errors with more information.
17876     *
17877     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17878     * @param cn The component name of the instrumentation.
17879     * @param report The error report.
17880     */
17881    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17882            ComponentName cn, String report) {
17883        Slog.w(TAG, report);
17884        if (watcher != null) {
17885            Bundle results = new Bundle();
17886            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17887            results.putString("Error", report);
17888            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17889        }
17890    }
17891
17892    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17893        if (app.instrumentationWatcher != null) {
17894            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17895                    app.instrumentationClass, resultCode, results);
17896        }
17897
17898        // Can't call out of the system process with a lock held, so post a message.
17899        if (app.instrumentationUiAutomationConnection != null) {
17900            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17901                    app.instrumentationUiAutomationConnection).sendToTarget();
17902        }
17903
17904        app.instrumentationWatcher = null;
17905        app.instrumentationUiAutomationConnection = null;
17906        app.instrumentationClass = null;
17907        app.instrumentationInfo = null;
17908        app.instrumentationProfileFile = null;
17909        app.instrumentationArguments = null;
17910
17911        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17912                "finished inst");
17913    }
17914
17915    public void finishInstrumentation(IApplicationThread target,
17916            int resultCode, Bundle results) {
17917        int userId = UserHandle.getCallingUserId();
17918        // Refuse possible leaked file descriptors
17919        if (results != null && results.hasFileDescriptors()) {
17920            throw new IllegalArgumentException("File descriptors passed in Intent");
17921        }
17922
17923        synchronized(this) {
17924            ProcessRecord app = getRecordForAppLocked(target);
17925            if (app == null) {
17926                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17927                return;
17928            }
17929            final long origId = Binder.clearCallingIdentity();
17930            finishInstrumentationLocked(app, resultCode, results);
17931            Binder.restoreCallingIdentity(origId);
17932        }
17933    }
17934
17935    // =========================================================
17936    // CONFIGURATION
17937    // =========================================================
17938
17939    public ConfigurationInfo getDeviceConfigurationInfo() {
17940        ConfigurationInfo config = new ConfigurationInfo();
17941        synchronized (this) {
17942            config.reqTouchScreen = mConfiguration.touchscreen;
17943            config.reqKeyboardType = mConfiguration.keyboard;
17944            config.reqNavigation = mConfiguration.navigation;
17945            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17946                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17947                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17948            }
17949            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17950                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17951                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17952            }
17953            config.reqGlEsVersion = GL_ES_VERSION;
17954        }
17955        return config;
17956    }
17957
17958    ActivityStack getFocusedStack() {
17959        return mStackSupervisor.getFocusedStack();
17960    }
17961
17962    @Override
17963    public int getFocusedStackId() throws RemoteException {
17964        ActivityStack focusedStack = getFocusedStack();
17965        if (focusedStack != null) {
17966            return focusedStack.getStackId();
17967        }
17968        return -1;
17969    }
17970
17971    public Configuration getConfiguration() {
17972        Configuration ci;
17973        synchronized(this) {
17974            ci = new Configuration(mConfiguration);
17975            ci.userSetLocale = false;
17976        }
17977        return ci;
17978    }
17979
17980    @Override
17981    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17982        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17983        synchronized (this) {
17984            mSuppressResizeConfigChanges = suppress;
17985        }
17986    }
17987
17988    @Override
17989    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17990        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17991        if (fromStackId == HOME_STACK_ID) {
17992            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17993        }
17994        synchronized (this) {
17995            final long origId = Binder.clearCallingIdentity();
17996            try {
17997                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
17998            } finally {
17999                Binder.restoreCallingIdentity(origId);
18000            }
18001        }
18002    }
18003
18004    @Override
18005    public void updatePersistentConfiguration(Configuration values) {
18006        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18007                "updateConfiguration()");
18008        enforceWriteSettingsPermission("updateConfiguration()");
18009        if (values == null) {
18010            throw new NullPointerException("Configuration must not be null");
18011        }
18012
18013        int userId = UserHandle.getCallingUserId();
18014
18015        synchronized(this) {
18016            final long origId = Binder.clearCallingIdentity();
18017            updateConfigurationLocked(values, null, false, true, userId);
18018            Binder.restoreCallingIdentity(origId);
18019        }
18020    }
18021
18022    private void updateFontScaleIfNeeded() {
18023        final int currentUserId;
18024        synchronized(this) {
18025            currentUserId = mUserController.getCurrentUserIdLocked();
18026        }
18027        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18028                FONT_SCALE, 1.0f, currentUserId);
18029        if (mConfiguration.fontScale != scaleFactor) {
18030            final Configuration configuration = mWindowManager.computeNewConfiguration();
18031            configuration.fontScale = scaleFactor;
18032            updatePersistentConfiguration(configuration);
18033        }
18034    }
18035
18036    private void enforceWriteSettingsPermission(String func) {
18037        int uid = Binder.getCallingUid();
18038        if (uid == Process.ROOT_UID) {
18039            return;
18040        }
18041
18042        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18043                Settings.getPackageNameForUid(mContext, uid), false)) {
18044            return;
18045        }
18046
18047        String msg = "Permission Denial: " + func + " from pid="
18048                + Binder.getCallingPid()
18049                + ", uid=" + uid
18050                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18051        Slog.w(TAG, msg);
18052        throw new SecurityException(msg);
18053    }
18054
18055    public void updateConfiguration(Configuration values) {
18056        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18057                "updateConfiguration()");
18058
18059        synchronized(this) {
18060            if (values == null && mWindowManager != null) {
18061                // sentinel: fetch the current configuration from the window manager
18062                values = mWindowManager.computeNewConfiguration();
18063            }
18064
18065            if (mWindowManager != null) {
18066                mProcessList.applyDisplaySize(mWindowManager);
18067            }
18068
18069            final long origId = Binder.clearCallingIdentity();
18070            if (values != null) {
18071                Settings.System.clearConfiguration(values);
18072            }
18073            updateConfigurationLocked(values, null, false);
18074            Binder.restoreCallingIdentity(origId);
18075        }
18076    }
18077
18078    void updateUserConfigurationLocked() {
18079        Configuration configuration = new Configuration(mConfiguration);
18080        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18081                mUserController.getCurrentUserIdLocked());
18082        updateConfigurationLocked(configuration, null, false);
18083    }
18084
18085    boolean updateConfigurationLocked(Configuration values,
18086            ActivityRecord starting, boolean initLocale) {
18087        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18088        return updateConfigurationLocked(values, starting, initLocale, false,
18089                UserHandle.USER_NULL);
18090    }
18091
18092    // To cache the list of supported system locales
18093    private String[] mSupportedSystemLocales = null;
18094
18095    /**
18096     * Do either or both things: (1) change the current configuration, and (2)
18097     * make sure the given activity is running with the (now) current
18098     * configuration.  Returns true if the activity has been left running, or
18099     * false if <var>starting</var> is being destroyed to match the new
18100     * configuration.
18101     *
18102     * @param userId is only used when persistent parameter is set to true to persist configuration
18103     *               for that particular user
18104     */
18105    private boolean updateConfigurationLocked(Configuration values,
18106            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18107        int changes = 0;
18108
18109        if (mWindowManager != null) {
18110            mWindowManager.deferSurfaceLayout();
18111        }
18112        if (values != null) {
18113            Configuration newConfig = new Configuration(mConfiguration);
18114            changes = newConfig.updateFrom(values);
18115            if (changes != 0) {
18116                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18117                        "Updating configuration to: " + values);
18118
18119                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18120
18121                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18122                    final Locale locale;
18123                    if (values.getLocales().size() == 1) {
18124                        // This is an optimization to avoid the JNI call when the result of
18125                        // getFirstMatch() does not depend on the supported locales.
18126                        locale = values.getLocales().get(0);
18127                    } else {
18128                        if (mSupportedSystemLocales == null) {
18129                            mSupportedSystemLocales =
18130                                    Resources.getSystem().getAssets().getLocales();
18131                        }
18132                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18133                    }
18134                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18135                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18136                            locale));
18137                }
18138
18139                mConfigurationSeq++;
18140                if (mConfigurationSeq <= 0) {
18141                    mConfigurationSeq = 1;
18142                }
18143                newConfig.seq = mConfigurationSeq;
18144                mConfiguration = newConfig;
18145                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18146                mUsageStatsService.reportConfigurationChange(newConfig,
18147                        mUserController.getCurrentUserIdLocked());
18148                //mUsageStatsService.noteStartConfig(newConfig);
18149
18150                final Configuration configCopy = new Configuration(mConfiguration);
18151
18152                // TODO: If our config changes, should we auto dismiss any currently
18153                // showing dialogs?
18154                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18155
18156                AttributeCache ac = AttributeCache.instance();
18157                if (ac != null) {
18158                    ac.updateConfiguration(configCopy);
18159                }
18160
18161                // Make sure all resources in our process are updated
18162                // right now, so that anyone who is going to retrieve
18163                // resource values after we return will be sure to get
18164                // the new ones.  This is especially important during
18165                // boot, where the first config change needs to guarantee
18166                // all resources have that config before following boot
18167                // code is executed.
18168                mSystemThread.applyConfigurationToResources(configCopy);
18169
18170                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18171                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18172                    msg.obj = new Configuration(configCopy);
18173                    msg.arg1 = userId;
18174                    mHandler.sendMessage(msg);
18175                }
18176
18177                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18178                if (isDensityChange) {
18179                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18180                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18181                }
18182
18183                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18184                    ProcessRecord app = mLruProcesses.get(i);
18185                    try {
18186                        if (app.thread != null) {
18187                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18188                                    + app.processName + " new config " + mConfiguration);
18189                            app.thread.scheduleConfigurationChanged(configCopy);
18190                        }
18191                    } catch (Exception e) {
18192                    }
18193                }
18194                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18195                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18196                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18197                        | Intent.FLAG_RECEIVER_FOREGROUND);
18198                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18199                        null, AppOpsManager.OP_NONE, null, false, false,
18200                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18201                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18202                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18203                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18204                    if (!mProcessesReady) {
18205                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18206                    }
18207                    broadcastIntentLocked(null, null, intent,
18208                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18209                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18210                }
18211            }
18212            // Update the configuration with WM first and check if any of the stacks need to be
18213            // resized due to the configuration change. If so, resize the stacks now and do any
18214            // relaunches if necessary. This way we don't need to relaunch again below in
18215            // ensureActivityConfigurationLocked().
18216            if (mWindowManager != null) {
18217                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18218                if (resizedStacks != null) {
18219                    for (int stackId : resizedStacks) {
18220                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18221                        mStackSupervisor.resizeStackLocked(
18222                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18223                    }
18224                }
18225            }
18226        }
18227
18228        boolean kept = true;
18229        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18230        // mainStack is null during startup.
18231        if (mainStack != null) {
18232            if (changes != 0 && starting == null) {
18233                // If the configuration changed, and the caller is not already
18234                // in the process of starting an activity, then find the top
18235                // activity to check if its configuration needs to change.
18236                starting = mainStack.topRunningActivityLocked();
18237            }
18238
18239            if (starting != null) {
18240                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18241                // And we need to make sure at this point that all other activities
18242                // are made visible with the correct configuration.
18243                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18244                        !PRESERVE_WINDOWS);
18245            }
18246        }
18247        if (mWindowManager != null) {
18248            mWindowManager.continueSurfaceLayout();
18249        }
18250        return kept;
18251    }
18252
18253    /**
18254     * Decide based on the configuration whether we should shouw the ANR,
18255     * crash, etc dialogs.  The idea is that if there is no affordnace to
18256     * press the on-screen buttons, we shouldn't show the dialog.
18257     *
18258     * A thought: SystemUI might also want to get told about this, the Power
18259     * dialog / global actions also might want different behaviors.
18260     */
18261    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18262        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18263                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18264                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18265        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18266                                    == Configuration.UI_MODE_TYPE_CAR);
18267        return inputMethodExists && uiIsNotCarType && !inVrMode;
18268    }
18269
18270    @Override
18271    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18272        synchronized (this) {
18273            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18274            if (srec != null) {
18275                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18276            }
18277        }
18278        return false;
18279    }
18280
18281    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18282            Intent resultData) {
18283
18284        synchronized (this) {
18285            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18286            if (r != null) {
18287                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18288            }
18289            return false;
18290        }
18291    }
18292
18293    public int getLaunchedFromUid(IBinder activityToken) {
18294        ActivityRecord srec;
18295        synchronized (this) {
18296            srec = ActivityRecord.forTokenLocked(activityToken);
18297        }
18298        if (srec == null) {
18299            return -1;
18300        }
18301        return srec.launchedFromUid;
18302    }
18303
18304    public String getLaunchedFromPackage(IBinder activityToken) {
18305        ActivityRecord srec;
18306        synchronized (this) {
18307            srec = ActivityRecord.forTokenLocked(activityToken);
18308        }
18309        if (srec == null) {
18310            return null;
18311        }
18312        return srec.launchedFromPackage;
18313    }
18314
18315    // =========================================================
18316    // LIFETIME MANAGEMENT
18317    // =========================================================
18318
18319    // Returns which broadcast queue the app is the current [or imminent] receiver
18320    // on, or 'null' if the app is not an active broadcast recipient.
18321    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18322        BroadcastRecord r = app.curReceiver;
18323        if (r != null) {
18324            return r.queue;
18325        }
18326
18327        // It's not the current receiver, but it might be starting up to become one
18328        synchronized (this) {
18329            for (BroadcastQueue queue : mBroadcastQueues) {
18330                r = queue.mPendingBroadcast;
18331                if (r != null && r.curApp == app) {
18332                    // found it; report which queue it's in
18333                    return queue;
18334                }
18335            }
18336        }
18337
18338        return null;
18339    }
18340
18341    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18342            int targetUid, ComponentName targetComponent, String targetProcess) {
18343        if (!mTrackingAssociations) {
18344            return null;
18345        }
18346        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18347                = mAssociations.get(targetUid);
18348        if (components == null) {
18349            components = new ArrayMap<>();
18350            mAssociations.put(targetUid, components);
18351        }
18352        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18353        if (sourceUids == null) {
18354            sourceUids = new SparseArray<>();
18355            components.put(targetComponent, sourceUids);
18356        }
18357        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18358        if (sourceProcesses == null) {
18359            sourceProcesses = new ArrayMap<>();
18360            sourceUids.put(sourceUid, sourceProcesses);
18361        }
18362        Association ass = sourceProcesses.get(sourceProcess);
18363        if (ass == null) {
18364            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18365                    targetProcess);
18366            sourceProcesses.put(sourceProcess, ass);
18367        }
18368        ass.mCount++;
18369        ass.mNesting++;
18370        if (ass.mNesting == 1) {
18371            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18372            ass.mLastState = sourceState;
18373        }
18374        return ass;
18375    }
18376
18377    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18378            ComponentName targetComponent) {
18379        if (!mTrackingAssociations) {
18380            return;
18381        }
18382        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18383                = mAssociations.get(targetUid);
18384        if (components == null) {
18385            return;
18386        }
18387        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18388        if (sourceUids == null) {
18389            return;
18390        }
18391        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18392        if (sourceProcesses == null) {
18393            return;
18394        }
18395        Association ass = sourceProcesses.get(sourceProcess);
18396        if (ass == null || ass.mNesting <= 0) {
18397            return;
18398        }
18399        ass.mNesting--;
18400        if (ass.mNesting == 0) {
18401            long uptime = SystemClock.uptimeMillis();
18402            ass.mTime += uptime - ass.mStartTime;
18403            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18404                    += uptime - ass.mLastStateUptime;
18405            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18406        }
18407    }
18408
18409    private void noteUidProcessState(final int uid, final int state) {
18410        mBatteryStatsService.noteUidProcessState(uid, state);
18411        if (mTrackingAssociations) {
18412            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18413                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18414                        = mAssociations.valueAt(i1);
18415                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18416                    SparseArray<ArrayMap<String, Association>> sourceUids
18417                            = targetComponents.valueAt(i2);
18418                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18419                    if (sourceProcesses != null) {
18420                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18421                            Association ass = sourceProcesses.valueAt(i4);
18422                            if (ass.mNesting >= 1) {
18423                                // currently associated
18424                                long uptime = SystemClock.uptimeMillis();
18425                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18426                                        += uptime - ass.mLastStateUptime;
18427                                ass.mLastState = state;
18428                                ass.mLastStateUptime = uptime;
18429                            }
18430                        }
18431                    }
18432                }
18433            }
18434        }
18435    }
18436
18437    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18438            boolean doingAll, long now) {
18439        if (mAdjSeq == app.adjSeq) {
18440            // This adjustment has already been computed.
18441            return app.curRawAdj;
18442        }
18443
18444        if (app.thread == null) {
18445            app.adjSeq = mAdjSeq;
18446            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18447            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18448            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18449        }
18450
18451        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18452        app.adjSource = null;
18453        app.adjTarget = null;
18454        app.empty = false;
18455        app.cached = false;
18456
18457        final int activitiesSize = app.activities.size();
18458
18459        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18460            // The max adjustment doesn't allow this app to be anything
18461            // below foreground, so it is not worth doing work for it.
18462            app.adjType = "fixed";
18463            app.adjSeq = mAdjSeq;
18464            app.curRawAdj = app.maxAdj;
18465            app.foregroundActivities = false;
18466            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18467            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18468            // System processes can do UI, and when they do we want to have
18469            // them trim their memory after the user leaves the UI.  To
18470            // facilitate this, here we need to determine whether or not it
18471            // is currently showing UI.
18472            app.systemNoUi = true;
18473            if (app == TOP_APP) {
18474                app.systemNoUi = false;
18475            } else if (activitiesSize > 0) {
18476                for (int j = 0; j < activitiesSize; j++) {
18477                    final ActivityRecord r = app.activities.get(j);
18478                    if (r.visible) {
18479                        app.systemNoUi = false;
18480                    }
18481                }
18482            }
18483            if (!app.systemNoUi) {
18484                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18485            }
18486            return (app.curAdj=app.maxAdj);
18487        }
18488
18489        app.systemNoUi = false;
18490
18491        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18492
18493        // Determine the importance of the process, starting with most
18494        // important to least, and assign an appropriate OOM adjustment.
18495        int adj;
18496        int schedGroup;
18497        int procState;
18498        boolean foregroundActivities = false;
18499        BroadcastQueue queue;
18500        if (app == TOP_APP) {
18501            // The last app on the list is the foreground app.
18502            adj = ProcessList.FOREGROUND_APP_ADJ;
18503            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18504            app.adjType = "top-activity";
18505            foregroundActivities = true;
18506            procState = PROCESS_STATE_CUR_TOP;
18507        } else if (app.instrumentationClass != null) {
18508            // Don't want to kill running instrumentation.
18509            adj = ProcessList.FOREGROUND_APP_ADJ;
18510            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18511            app.adjType = "instrumentation";
18512            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18513        } else if ((queue = isReceivingBroadcast(app)) != null) {
18514            // An app that is currently receiving a broadcast also
18515            // counts as being in the foreground for OOM killer purposes.
18516            // It's placed in a sched group based on the nature of the
18517            // broadcast as reflected by which queue it's active in.
18518            adj = ProcessList.FOREGROUND_APP_ADJ;
18519            schedGroup = (queue == mFgBroadcastQueue)
18520                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18521            app.adjType = "broadcast";
18522            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18523        } else if (app.executingServices.size() > 0) {
18524            // An app that is currently executing a service callback also
18525            // counts as being in the foreground.
18526            adj = ProcessList.FOREGROUND_APP_ADJ;
18527            schedGroup = app.execServicesFg ?
18528                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18529            app.adjType = "exec-service";
18530            procState = ActivityManager.PROCESS_STATE_SERVICE;
18531            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18532        } else {
18533            // As far as we know the process is empty.  We may change our mind later.
18534            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18535            // At this point we don't actually know the adjustment.  Use the cached adj
18536            // value that the caller wants us to.
18537            adj = cachedAdj;
18538            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18539            app.cached = true;
18540            app.empty = true;
18541            app.adjType = "cch-empty";
18542        }
18543
18544        // Examine all activities if not already foreground.
18545        if (!foregroundActivities && activitiesSize > 0) {
18546            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18547            for (int j = 0; j < activitiesSize; j++) {
18548                final ActivityRecord r = app.activities.get(j);
18549                if (r.app != app) {
18550                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18551                            + " instead of expected " + app);
18552                    if (r.app == null || (r.app.uid == app.uid)) {
18553                        // Only fix things up when they look sane
18554                        r.app = app;
18555                    } else {
18556                        continue;
18557                    }
18558                }
18559                if (r.visible) {
18560                    // App has a visible activity; only upgrade adjustment.
18561                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18562                        adj = ProcessList.VISIBLE_APP_ADJ;
18563                        app.adjType = "visible";
18564                    }
18565                    if (procState > PROCESS_STATE_CUR_TOP) {
18566                        procState = PROCESS_STATE_CUR_TOP;
18567                    }
18568                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18569                    app.cached = false;
18570                    app.empty = false;
18571                    foregroundActivities = true;
18572                    if (r.task != null && minLayer > 0) {
18573                        final int layer = r.task.mLayerRank;
18574                        if (layer >= 0 && minLayer > layer) {
18575                            minLayer = layer;
18576                        }
18577                    }
18578                    break;
18579                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18580                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18581                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18582                        app.adjType = "pausing";
18583                    }
18584                    if (procState > PROCESS_STATE_CUR_TOP) {
18585                        procState = PROCESS_STATE_CUR_TOP;
18586                    }
18587                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18588                    app.cached = false;
18589                    app.empty = false;
18590                    foregroundActivities = true;
18591                } else if (r.state == ActivityState.STOPPING) {
18592                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18593                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18594                        app.adjType = "stopping";
18595                    }
18596                    // For the process state, we will at this point consider the
18597                    // process to be cached.  It will be cached either as an activity
18598                    // or empty depending on whether the activity is finishing.  We do
18599                    // this so that we can treat the process as cached for purposes of
18600                    // memory trimming (determing current memory level, trim command to
18601                    // send to process) since there can be an arbitrary number of stopping
18602                    // processes and they should soon all go into the cached state.
18603                    if (!r.finishing) {
18604                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18605                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18606                        }
18607                    }
18608                    app.cached = false;
18609                    app.empty = false;
18610                    foregroundActivities = true;
18611                } else {
18612                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18613                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18614                        app.adjType = "cch-act";
18615                    }
18616                }
18617            }
18618            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18619                adj += minLayer;
18620            }
18621        }
18622
18623        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18624                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18625            if (app.foregroundServices) {
18626                // The user is aware of this app, so make it visible.
18627                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18628                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18629                app.cached = false;
18630                app.adjType = "fg-service";
18631                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18632            } else if (app.forcingToForeground != null) {
18633                // The user is aware of this app, so make it visible.
18634                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18635                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18636                app.cached = false;
18637                app.adjType = "force-fg";
18638                app.adjSource = app.forcingToForeground;
18639                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18640            }
18641        }
18642
18643        if (app == mHeavyWeightProcess) {
18644            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18645                // We don't want to kill the current heavy-weight process.
18646                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18647                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18648                app.cached = false;
18649                app.adjType = "heavy";
18650            }
18651            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18652                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18653            }
18654        }
18655
18656        if (app == mHomeProcess) {
18657            if (adj > ProcessList.HOME_APP_ADJ) {
18658                // This process is hosting what we currently consider to be the
18659                // home app, so we don't want to let it go into the background.
18660                adj = ProcessList.HOME_APP_ADJ;
18661                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18662                app.cached = false;
18663                app.adjType = "home";
18664            }
18665            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18666                procState = ActivityManager.PROCESS_STATE_HOME;
18667            }
18668        }
18669
18670        if (app == mPreviousProcess && app.activities.size() > 0) {
18671            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18672                // This was the previous process that showed UI to the user.
18673                // We want to try to keep it around more aggressively, to give
18674                // a good experience around switching between two apps.
18675                adj = ProcessList.PREVIOUS_APP_ADJ;
18676                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18677                app.cached = false;
18678                app.adjType = "previous";
18679            }
18680            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18681                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18682            }
18683        }
18684
18685        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18686                + " reason=" + app.adjType);
18687
18688        // By default, we use the computed adjustment.  It may be changed if
18689        // there are applications dependent on our services or providers, but
18690        // this gives us a baseline and makes sure we don't get into an
18691        // infinite recursion.
18692        app.adjSeq = mAdjSeq;
18693        app.curRawAdj = adj;
18694        app.hasStartedServices = false;
18695
18696        if (mBackupTarget != null && app == mBackupTarget.app) {
18697            // If possible we want to avoid killing apps while they're being backed up
18698            if (adj > ProcessList.BACKUP_APP_ADJ) {
18699                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18700                adj = ProcessList.BACKUP_APP_ADJ;
18701                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18702                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18703                }
18704                app.adjType = "backup";
18705                app.cached = false;
18706            }
18707            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18708                procState = ActivityManager.PROCESS_STATE_BACKUP;
18709            }
18710        }
18711
18712        boolean mayBeTop = false;
18713
18714        for (int is = app.services.size()-1;
18715                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18716                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18717                        || procState > ActivityManager.PROCESS_STATE_TOP);
18718                is--) {
18719            ServiceRecord s = app.services.valueAt(is);
18720            if (s.startRequested) {
18721                app.hasStartedServices = true;
18722                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18723                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18724                }
18725                if (app.hasShownUi && app != mHomeProcess) {
18726                    // If this process has shown some UI, let it immediately
18727                    // go to the LRU list because it may be pretty heavy with
18728                    // UI stuff.  We'll tag it with a label just to help
18729                    // debug and understand what is going on.
18730                    if (adj > ProcessList.SERVICE_ADJ) {
18731                        app.adjType = "cch-started-ui-services";
18732                    }
18733                } else {
18734                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18735                        // This service has seen some activity within
18736                        // recent memory, so we will keep its process ahead
18737                        // of the background processes.
18738                        if (adj > ProcessList.SERVICE_ADJ) {
18739                            adj = ProcessList.SERVICE_ADJ;
18740                            app.adjType = "started-services";
18741                            app.cached = false;
18742                        }
18743                    }
18744                    // If we have let the service slide into the background
18745                    // state, still have some text describing what it is doing
18746                    // even though the service no longer has an impact.
18747                    if (adj > ProcessList.SERVICE_ADJ) {
18748                        app.adjType = "cch-started-services";
18749                    }
18750                }
18751            }
18752            for (int conni = s.connections.size()-1;
18753                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18754                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18755                            || procState > ActivityManager.PROCESS_STATE_TOP);
18756                    conni--) {
18757                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18758                for (int i = 0;
18759                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18760                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18761                                || procState > ActivityManager.PROCESS_STATE_TOP);
18762                        i++) {
18763                    // XXX should compute this based on the max of
18764                    // all connected clients.
18765                    ConnectionRecord cr = clist.get(i);
18766                    if (cr.binding.client == app) {
18767                        // Binding to ourself is not interesting.
18768                        continue;
18769                    }
18770                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18771                        ProcessRecord client = cr.binding.client;
18772                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18773                                TOP_APP, doingAll, now);
18774                        int clientProcState = client.curProcState;
18775                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18776                            // If the other app is cached for any reason, for purposes here
18777                            // we are going to consider it empty.  The specific cached state
18778                            // doesn't propagate except under certain conditions.
18779                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18780                        }
18781                        String adjType = null;
18782                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18783                            // Not doing bind OOM management, so treat
18784                            // this guy more like a started service.
18785                            if (app.hasShownUi && app != mHomeProcess) {
18786                                // If this process has shown some UI, let it immediately
18787                                // go to the LRU list because it may be pretty heavy with
18788                                // UI stuff.  We'll tag it with a label just to help
18789                                // debug and understand what is going on.
18790                                if (adj > clientAdj) {
18791                                    adjType = "cch-bound-ui-services";
18792                                }
18793                                app.cached = false;
18794                                clientAdj = adj;
18795                                clientProcState = procState;
18796                            } else {
18797                                if (now >= (s.lastActivity
18798                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18799                                    // This service has not seen activity within
18800                                    // recent memory, so allow it to drop to the
18801                                    // LRU list if there is no other reason to keep
18802                                    // it around.  We'll also tag it with a label just
18803                                    // to help debug and undertand what is going on.
18804                                    if (adj > clientAdj) {
18805                                        adjType = "cch-bound-services";
18806                                    }
18807                                    clientAdj = adj;
18808                                }
18809                            }
18810                        }
18811                        if (adj > clientAdj) {
18812                            // If this process has recently shown UI, and
18813                            // the process that is binding to it is less
18814                            // important than being visible, then we don't
18815                            // care about the binding as much as we care
18816                            // about letting this process get into the LRU
18817                            // list to be killed and restarted if needed for
18818                            // memory.
18819                            if (app.hasShownUi && app != mHomeProcess
18820                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18821                                adjType = "cch-bound-ui-services";
18822                            } else {
18823                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18824                                        |Context.BIND_IMPORTANT)) != 0) {
18825                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18826                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18827                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18828                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18829                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18830                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18831                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18832                                    adj = clientAdj;
18833                                } else {
18834                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18835                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18836                                    }
18837                                }
18838                                if (!client.cached) {
18839                                    app.cached = false;
18840                                }
18841                                adjType = "service";
18842                            }
18843                        }
18844                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18845                            // This will treat important bound services identically to
18846                            // the top app, which may behave differently than generic
18847                            // foreground work.
18848                            if (client.curSchedGroup > schedGroup) {
18849                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18850                                    schedGroup = client.curSchedGroup;
18851                                } else {
18852                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18853                                }
18854                            }
18855                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18856                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18857                                    // Special handling of clients who are in the top state.
18858                                    // We *may* want to consider this process to be in the
18859                                    // top state as well, but only if there is not another
18860                                    // reason for it to be running.  Being on the top is a
18861                                    // special state, meaning you are specifically running
18862                                    // for the current top app.  If the process is already
18863                                    // running in the background for some other reason, it
18864                                    // is more important to continue considering it to be
18865                                    // in the background state.
18866                                    mayBeTop = true;
18867                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18868                                } else {
18869                                    // Special handling for above-top states (persistent
18870                                    // processes).  These should not bring the current process
18871                                    // into the top state, since they are not on top.  Instead
18872                                    // give them the best state after that.
18873                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18874                                        clientProcState =
18875                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18876                                    } else if (mWakefulness
18877                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18878                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18879                                                    != 0) {
18880                                        clientProcState =
18881                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18882                                    } else {
18883                                        clientProcState =
18884                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18885                                    }
18886                                }
18887                            }
18888                        } else {
18889                            if (clientProcState <
18890                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18891                                clientProcState =
18892                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18893                            }
18894                        }
18895                        if (procState > clientProcState) {
18896                            procState = clientProcState;
18897                        }
18898                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18899                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18900                            app.pendingUiClean = true;
18901                        }
18902                        if (adjType != null) {
18903                            app.adjType = adjType;
18904                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18905                                    .REASON_SERVICE_IN_USE;
18906                            app.adjSource = cr.binding.client;
18907                            app.adjSourceProcState = clientProcState;
18908                            app.adjTarget = s.name;
18909                        }
18910                    }
18911                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18912                        app.treatLikeActivity = true;
18913                    }
18914                    final ActivityRecord a = cr.activity;
18915                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18916                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18917                            (a.visible || a.state == ActivityState.RESUMED ||
18918                             a.state == ActivityState.PAUSING)) {
18919                            adj = ProcessList.FOREGROUND_APP_ADJ;
18920                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18921                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18922                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18923                                } else {
18924                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18925                                }
18926                            }
18927                            app.cached = false;
18928                            app.adjType = "service";
18929                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18930                                    .REASON_SERVICE_IN_USE;
18931                            app.adjSource = a;
18932                            app.adjSourceProcState = procState;
18933                            app.adjTarget = s.name;
18934                        }
18935                    }
18936                }
18937            }
18938        }
18939
18940        for (int provi = app.pubProviders.size()-1;
18941                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18942                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18943                        || procState > ActivityManager.PROCESS_STATE_TOP);
18944                provi--) {
18945            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18946            for (int i = cpr.connections.size()-1;
18947                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18948                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18949                            || procState > ActivityManager.PROCESS_STATE_TOP);
18950                    i--) {
18951                ContentProviderConnection conn = cpr.connections.get(i);
18952                ProcessRecord client = conn.client;
18953                if (client == app) {
18954                    // Being our own client is not interesting.
18955                    continue;
18956                }
18957                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18958                int clientProcState = client.curProcState;
18959                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18960                    // If the other app is cached for any reason, for purposes here
18961                    // we are going to consider it empty.
18962                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18963                }
18964                if (adj > clientAdj) {
18965                    if (app.hasShownUi && app != mHomeProcess
18966                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18967                        app.adjType = "cch-ui-provider";
18968                    } else {
18969                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18970                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18971                        app.adjType = "provider";
18972                    }
18973                    app.cached &= client.cached;
18974                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18975                            .REASON_PROVIDER_IN_USE;
18976                    app.adjSource = client;
18977                    app.adjSourceProcState = clientProcState;
18978                    app.adjTarget = cpr.name;
18979                }
18980                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18981                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18982                        // Special handling of clients who are in the top state.
18983                        // We *may* want to consider this process to be in the
18984                        // top state as well, but only if there is not another
18985                        // reason for it to be running.  Being on the top is a
18986                        // special state, meaning you are specifically running
18987                        // for the current top app.  If the process is already
18988                        // running in the background for some other reason, it
18989                        // is more important to continue considering it to be
18990                        // in the background state.
18991                        mayBeTop = true;
18992                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18993                    } else {
18994                        // Special handling for above-top states (persistent
18995                        // processes).  These should not bring the current process
18996                        // into the top state, since they are not on top.  Instead
18997                        // give them the best state after that.
18998                        clientProcState =
18999                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19000                    }
19001                }
19002                if (procState > clientProcState) {
19003                    procState = clientProcState;
19004                }
19005                if (client.curSchedGroup > schedGroup) {
19006                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19007                }
19008            }
19009            // If the provider has external (non-framework) process
19010            // dependencies, ensure that its adjustment is at least
19011            // FOREGROUND_APP_ADJ.
19012            if (cpr.hasExternalProcessHandles()) {
19013                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19014                    adj = ProcessList.FOREGROUND_APP_ADJ;
19015                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19016                    app.cached = false;
19017                    app.adjType = "provider";
19018                    app.adjTarget = cpr.name;
19019                }
19020                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19021                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19022                }
19023            }
19024        }
19025
19026        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19027            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19028                adj = ProcessList.PREVIOUS_APP_ADJ;
19029                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19030                app.cached = false;
19031                app.adjType = "provider";
19032            }
19033            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19034                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19035            }
19036        }
19037
19038        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19039            // A client of one of our services or providers is in the top state.  We
19040            // *may* want to be in the top state, but not if we are already running in
19041            // the background for some other reason.  For the decision here, we are going
19042            // to pick out a few specific states that we want to remain in when a client
19043            // is top (states that tend to be longer-term) and otherwise allow it to go
19044            // to the top state.
19045            switch (procState) {
19046                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19047                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19048                case ActivityManager.PROCESS_STATE_SERVICE:
19049                    // These all are longer-term states, so pull them up to the top
19050                    // of the background states, but not all the way to the top state.
19051                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19052                    break;
19053                default:
19054                    // Otherwise, top is a better choice, so take it.
19055                    procState = ActivityManager.PROCESS_STATE_TOP;
19056                    break;
19057            }
19058        }
19059
19060        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19061            if (app.hasClientActivities) {
19062                // This is a cached process, but with client activities.  Mark it so.
19063                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19064                app.adjType = "cch-client-act";
19065            } else if (app.treatLikeActivity) {
19066                // This is a cached process, but somebody wants us to treat it like it has
19067                // an activity, okay!
19068                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19069                app.adjType = "cch-as-act";
19070            }
19071        }
19072
19073        if (adj == ProcessList.SERVICE_ADJ) {
19074            if (doingAll) {
19075                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19076                mNewNumServiceProcs++;
19077                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19078                if (!app.serviceb) {
19079                    // This service isn't far enough down on the LRU list to
19080                    // normally be a B service, but if we are low on RAM and it
19081                    // is large we want to force it down since we would prefer to
19082                    // keep launcher over it.
19083                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19084                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19085                        app.serviceHighRam = true;
19086                        app.serviceb = true;
19087                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19088                    } else {
19089                        mNewNumAServiceProcs++;
19090                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19091                    }
19092                } else {
19093                    app.serviceHighRam = false;
19094                }
19095            }
19096            if (app.serviceb) {
19097                adj = ProcessList.SERVICE_B_ADJ;
19098            }
19099        }
19100
19101        app.curRawAdj = adj;
19102
19103        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19104        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19105        if (adj > app.maxAdj) {
19106            adj = app.maxAdj;
19107            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19108                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19109            }
19110        }
19111
19112        // Do final modification to adj.  Everything we do between here and applying
19113        // the final setAdj must be done in this function, because we will also use
19114        // it when computing the final cached adj later.  Note that we don't need to
19115        // worry about this for max adj above, since max adj will always be used to
19116        // keep it out of the cached vaues.
19117        app.curAdj = app.modifyRawOomAdj(adj);
19118        app.curSchedGroup = schedGroup;
19119        app.curProcState = procState;
19120        app.foregroundActivities = foregroundActivities;
19121
19122        return app.curRawAdj;
19123    }
19124
19125    /**
19126     * Record new PSS sample for a process.
19127     */
19128    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19129            long now) {
19130        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19131                swapPss * 1024);
19132        proc.lastPssTime = now;
19133        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19134        if (DEBUG_PSS) Slog.d(TAG_PSS,
19135                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19136                + " state=" + ProcessList.makeProcStateString(procState));
19137        if (proc.initialIdlePss == 0) {
19138            proc.initialIdlePss = pss;
19139        }
19140        proc.lastPss = pss;
19141        proc.lastSwapPss = swapPss;
19142        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19143            proc.lastCachedPss = pss;
19144            proc.lastCachedSwapPss = swapPss;
19145        }
19146
19147        final SparseArray<Pair<Long, String>> watchUids
19148                = mMemWatchProcesses.getMap().get(proc.processName);
19149        Long check = null;
19150        if (watchUids != null) {
19151            Pair<Long, String> val = watchUids.get(proc.uid);
19152            if (val == null) {
19153                val = watchUids.get(0);
19154            }
19155            if (val != null) {
19156                check = val.first;
19157            }
19158        }
19159        if (check != null) {
19160            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19161                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19162                if (!isDebuggable) {
19163                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19164                        isDebuggable = true;
19165                    }
19166                }
19167                if (isDebuggable) {
19168                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19169                    final ProcessRecord myProc = proc;
19170                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19171                    mMemWatchDumpProcName = proc.processName;
19172                    mMemWatchDumpFile = heapdumpFile.toString();
19173                    mMemWatchDumpPid = proc.pid;
19174                    mMemWatchDumpUid = proc.uid;
19175                    BackgroundThread.getHandler().post(new Runnable() {
19176                        @Override
19177                        public void run() {
19178                            revokeUriPermission(ActivityThread.currentActivityThread()
19179                                            .getApplicationThread(),
19180                                    DumpHeapActivity.JAVA_URI,
19181                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19182                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19183                                    UserHandle.myUserId());
19184                            ParcelFileDescriptor fd = null;
19185                            try {
19186                                heapdumpFile.delete();
19187                                fd = ParcelFileDescriptor.open(heapdumpFile,
19188                                        ParcelFileDescriptor.MODE_CREATE |
19189                                                ParcelFileDescriptor.MODE_TRUNCATE |
19190                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19191                                                ParcelFileDescriptor.MODE_APPEND);
19192                                IApplicationThread thread = myProc.thread;
19193                                if (thread != null) {
19194                                    try {
19195                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19196                                                "Requesting dump heap from "
19197                                                + myProc + " to " + heapdumpFile);
19198                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19199                                    } catch (RemoteException e) {
19200                                    }
19201                                }
19202                            } catch (FileNotFoundException e) {
19203                                e.printStackTrace();
19204                            } finally {
19205                                if (fd != null) {
19206                                    try {
19207                                        fd.close();
19208                                    } catch (IOException e) {
19209                                    }
19210                                }
19211                            }
19212                        }
19213                    });
19214                } else {
19215                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19216                            + ", but debugging not enabled");
19217                }
19218            }
19219        }
19220    }
19221
19222    /**
19223     * Schedule PSS collection of a process.
19224     */
19225    void requestPssLocked(ProcessRecord proc, int procState) {
19226        if (mPendingPssProcesses.contains(proc)) {
19227            return;
19228        }
19229        if (mPendingPssProcesses.size() == 0) {
19230            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19231        }
19232        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19233        proc.pssProcState = procState;
19234        mPendingPssProcesses.add(proc);
19235    }
19236
19237    /**
19238     * Schedule PSS collection of all processes.
19239     */
19240    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19241        if (!always) {
19242            if (now < (mLastFullPssTime +
19243                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19244                return;
19245            }
19246        }
19247        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19248        mLastFullPssTime = now;
19249        mFullPssPending = true;
19250        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19251        mPendingPssProcesses.clear();
19252        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19253            ProcessRecord app = mLruProcesses.get(i);
19254            if (app.thread == null
19255                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19256                continue;
19257            }
19258            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19259                app.pssProcState = app.setProcState;
19260                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19261                        mTestPssMode, isSleeping(), now);
19262                mPendingPssProcesses.add(app);
19263            }
19264        }
19265        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19266    }
19267
19268    public void setTestPssMode(boolean enabled) {
19269        synchronized (this) {
19270            mTestPssMode = enabled;
19271            if (enabled) {
19272                // Whenever we enable the mode, we want to take a snapshot all of current
19273                // process mem use.
19274                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19275            }
19276        }
19277    }
19278
19279    /**
19280     * Ask a given process to GC right now.
19281     */
19282    final void performAppGcLocked(ProcessRecord app) {
19283        try {
19284            app.lastRequestedGc = SystemClock.uptimeMillis();
19285            if (app.thread != null) {
19286                if (app.reportLowMemory) {
19287                    app.reportLowMemory = false;
19288                    app.thread.scheduleLowMemory();
19289                } else {
19290                    app.thread.processInBackground();
19291                }
19292            }
19293        } catch (Exception e) {
19294            // whatever.
19295        }
19296    }
19297
19298    /**
19299     * Returns true if things are idle enough to perform GCs.
19300     */
19301    private final boolean canGcNowLocked() {
19302        boolean processingBroadcasts = false;
19303        for (BroadcastQueue q : mBroadcastQueues) {
19304            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19305                processingBroadcasts = true;
19306            }
19307        }
19308        return !processingBroadcasts
19309                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19310    }
19311
19312    /**
19313     * Perform GCs on all processes that are waiting for it, but only
19314     * if things are idle.
19315     */
19316    final void performAppGcsLocked() {
19317        final int N = mProcessesToGc.size();
19318        if (N <= 0) {
19319            return;
19320        }
19321        if (canGcNowLocked()) {
19322            while (mProcessesToGc.size() > 0) {
19323                ProcessRecord proc = mProcessesToGc.remove(0);
19324                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19325                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19326                            <= SystemClock.uptimeMillis()) {
19327                        // To avoid spamming the system, we will GC processes one
19328                        // at a time, waiting a few seconds between each.
19329                        performAppGcLocked(proc);
19330                        scheduleAppGcsLocked();
19331                        return;
19332                    } else {
19333                        // It hasn't been long enough since we last GCed this
19334                        // process...  put it in the list to wait for its time.
19335                        addProcessToGcListLocked(proc);
19336                        break;
19337                    }
19338                }
19339            }
19340
19341            scheduleAppGcsLocked();
19342        }
19343    }
19344
19345    /**
19346     * If all looks good, perform GCs on all processes waiting for them.
19347     */
19348    final void performAppGcsIfAppropriateLocked() {
19349        if (canGcNowLocked()) {
19350            performAppGcsLocked();
19351            return;
19352        }
19353        // Still not idle, wait some more.
19354        scheduleAppGcsLocked();
19355    }
19356
19357    /**
19358     * Schedule the execution of all pending app GCs.
19359     */
19360    final void scheduleAppGcsLocked() {
19361        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19362
19363        if (mProcessesToGc.size() > 0) {
19364            // Schedule a GC for the time to the next process.
19365            ProcessRecord proc = mProcessesToGc.get(0);
19366            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19367
19368            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19369            long now = SystemClock.uptimeMillis();
19370            if (when < (now+GC_TIMEOUT)) {
19371                when = now + GC_TIMEOUT;
19372            }
19373            mHandler.sendMessageAtTime(msg, when);
19374        }
19375    }
19376
19377    /**
19378     * Add a process to the array of processes waiting to be GCed.  Keeps the
19379     * list in sorted order by the last GC time.  The process can't already be
19380     * on the list.
19381     */
19382    final void addProcessToGcListLocked(ProcessRecord proc) {
19383        boolean added = false;
19384        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19385            if (mProcessesToGc.get(i).lastRequestedGc <
19386                    proc.lastRequestedGc) {
19387                added = true;
19388                mProcessesToGc.add(i+1, proc);
19389                break;
19390            }
19391        }
19392        if (!added) {
19393            mProcessesToGc.add(0, proc);
19394        }
19395    }
19396
19397    /**
19398     * Set up to ask a process to GC itself.  This will either do it
19399     * immediately, or put it on the list of processes to gc the next
19400     * time things are idle.
19401     */
19402    final void scheduleAppGcLocked(ProcessRecord app) {
19403        long now = SystemClock.uptimeMillis();
19404        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19405            return;
19406        }
19407        if (!mProcessesToGc.contains(app)) {
19408            addProcessToGcListLocked(app);
19409            scheduleAppGcsLocked();
19410        }
19411    }
19412
19413    final void checkExcessivePowerUsageLocked(boolean doKills) {
19414        updateCpuStatsNow();
19415
19416        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19417        boolean doWakeKills = doKills;
19418        boolean doCpuKills = doKills;
19419        if (mLastPowerCheckRealtime == 0) {
19420            doWakeKills = false;
19421        }
19422        if (mLastPowerCheckUptime == 0) {
19423            doCpuKills = false;
19424        }
19425        if (stats.isScreenOn()) {
19426            doWakeKills = false;
19427        }
19428        final long curRealtime = SystemClock.elapsedRealtime();
19429        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19430        final long curUptime = SystemClock.uptimeMillis();
19431        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19432        mLastPowerCheckRealtime = curRealtime;
19433        mLastPowerCheckUptime = curUptime;
19434        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19435            doWakeKills = false;
19436        }
19437        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19438            doCpuKills = false;
19439        }
19440        int i = mLruProcesses.size();
19441        while (i > 0) {
19442            i--;
19443            ProcessRecord app = mLruProcesses.get(i);
19444            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19445                long wtime;
19446                synchronized (stats) {
19447                    wtime = stats.getProcessWakeTime(app.info.uid,
19448                            app.pid, curRealtime);
19449                }
19450                long wtimeUsed = wtime - app.lastWakeTime;
19451                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19452                if (DEBUG_POWER) {
19453                    StringBuilder sb = new StringBuilder(128);
19454                    sb.append("Wake for ");
19455                    app.toShortString(sb);
19456                    sb.append(": over ");
19457                    TimeUtils.formatDuration(realtimeSince, sb);
19458                    sb.append(" used ");
19459                    TimeUtils.formatDuration(wtimeUsed, sb);
19460                    sb.append(" (");
19461                    sb.append((wtimeUsed*100)/realtimeSince);
19462                    sb.append("%)");
19463                    Slog.i(TAG_POWER, sb.toString());
19464                    sb.setLength(0);
19465                    sb.append("CPU for ");
19466                    app.toShortString(sb);
19467                    sb.append(": over ");
19468                    TimeUtils.formatDuration(uptimeSince, sb);
19469                    sb.append(" used ");
19470                    TimeUtils.formatDuration(cputimeUsed, sb);
19471                    sb.append(" (");
19472                    sb.append((cputimeUsed*100)/uptimeSince);
19473                    sb.append("%)");
19474                    Slog.i(TAG_POWER, sb.toString());
19475                }
19476                // If a process has held a wake lock for more
19477                // than 50% of the time during this period,
19478                // that sounds bad.  Kill!
19479                if (doWakeKills && realtimeSince > 0
19480                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19481                    synchronized (stats) {
19482                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19483                                realtimeSince, wtimeUsed);
19484                    }
19485                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19486                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19487                } else if (doCpuKills && uptimeSince > 0
19488                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19489                    synchronized (stats) {
19490                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19491                                uptimeSince, cputimeUsed);
19492                    }
19493                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19494                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19495                } else {
19496                    app.lastWakeTime = wtime;
19497                    app.lastCpuTime = app.curCpuTime;
19498                }
19499            }
19500        }
19501    }
19502
19503    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19504            long nowElapsed) {
19505        boolean success = true;
19506
19507        if (app.curRawAdj != app.setRawAdj) {
19508            app.setRawAdj = app.curRawAdj;
19509        }
19510
19511        int changes = 0;
19512
19513        if (app.curAdj != app.setAdj) {
19514            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19515            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19516                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19517                    + app.adjType);
19518            app.setAdj = app.curAdj;
19519        }
19520
19521        if (app.setSchedGroup != app.curSchedGroup) {
19522            app.setSchedGroup = app.curSchedGroup;
19523            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19524                    "Setting sched group of " + app.processName
19525                    + " to " + app.curSchedGroup);
19526            if (app.waitingToKill != null && app.curReceiver == null
19527                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19528                app.kill(app.waitingToKill, true);
19529                success = false;
19530            } else {
19531                int processGroup;
19532                switch (app.curSchedGroup) {
19533                    case ProcessList.SCHED_GROUP_BACKGROUND:
19534                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19535                        break;
19536                    case ProcessList.SCHED_GROUP_TOP_APP:
19537                        processGroup = Process.THREAD_GROUP_TOP_APP;
19538                        break;
19539                    default:
19540                        processGroup = Process.THREAD_GROUP_DEFAULT;
19541                        break;
19542                }
19543                if (true) {
19544                    long oldId = Binder.clearCallingIdentity();
19545                    try {
19546                        Process.setProcessGroup(app.pid, processGroup);
19547                    } catch (Exception e) {
19548                        Slog.w(TAG, "Failed setting process group of " + app.pid
19549                                + " to " + app.curSchedGroup);
19550                        e.printStackTrace();
19551                    } finally {
19552                        Binder.restoreCallingIdentity(oldId);
19553                    }
19554                } else {
19555                    if (app.thread != null) {
19556                        try {
19557                            app.thread.setSchedulingGroup(processGroup);
19558                        } catch (RemoteException e) {
19559                        }
19560                    }
19561                }
19562            }
19563        }
19564        if (app.repForegroundActivities != app.foregroundActivities) {
19565            app.repForegroundActivities = app.foregroundActivities;
19566            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19567        }
19568        if (app.repProcState != app.curProcState) {
19569            app.repProcState = app.curProcState;
19570            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19571            if (app.thread != null) {
19572                try {
19573                    if (false) {
19574                        //RuntimeException h = new RuntimeException("here");
19575                        Slog.i(TAG, "Sending new process state " + app.repProcState
19576                                + " to " + app /*, h*/);
19577                    }
19578                    app.thread.setProcessState(app.repProcState);
19579                } catch (RemoteException e) {
19580                }
19581            }
19582        }
19583        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19584                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19585            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19586                // Experimental code to more aggressively collect pss while
19587                // running test...  the problem is that this tends to collect
19588                // the data right when a process is transitioning between process
19589                // states, which well tend to give noisy data.
19590                long start = SystemClock.uptimeMillis();
19591                long pss = Debug.getPss(app.pid, mTmpLong, null);
19592                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19593                mPendingPssProcesses.remove(app);
19594                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19595                        + " to " + app.curProcState + ": "
19596                        + (SystemClock.uptimeMillis()-start) + "ms");
19597            }
19598            app.lastStateTime = now;
19599            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19600                    mTestPssMode, isSleeping(), now);
19601            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19602                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19603                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19604                    + (app.nextPssTime-now) + ": " + app);
19605        } else {
19606            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19607                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19608                    mTestPssMode)))) {
19609                requestPssLocked(app, app.setProcState);
19610                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19611                        mTestPssMode, isSleeping(), now);
19612            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19613                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19614        }
19615        if (app.setProcState != app.curProcState) {
19616            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19617                    "Proc state change of " + app.processName
19618                            + " to " + app.curProcState);
19619            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19620            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19621            if (setImportant && !curImportant) {
19622                // This app is no longer something we consider important enough to allow to
19623                // use arbitrary amounts of battery power.  Note
19624                // its current wake lock time to later know to kill it if
19625                // it is not behaving well.
19626                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19627                synchronized (stats) {
19628                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19629                            app.pid, nowElapsed);
19630                }
19631                app.lastCpuTime = app.curCpuTime;
19632
19633            }
19634            // Inform UsageStats of important process state change
19635            // Must be called before updating setProcState
19636            maybeUpdateUsageStatsLocked(app, nowElapsed);
19637
19638            app.setProcState = app.curProcState;
19639            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19640                app.notCachedSinceIdle = false;
19641            }
19642            if (!doingAll) {
19643                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19644            } else {
19645                app.procStateChanged = true;
19646            }
19647        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19648                > USAGE_STATS_INTERACTION_INTERVAL) {
19649            // For apps that sit around for a long time in the interactive state, we need
19650            // to report this at least once a day so they don't go idle.
19651            maybeUpdateUsageStatsLocked(app, nowElapsed);
19652        }
19653
19654        if (changes != 0) {
19655            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19656                    "Changes in " + app + ": " + changes);
19657            int i = mPendingProcessChanges.size()-1;
19658            ProcessChangeItem item = null;
19659            while (i >= 0) {
19660                item = mPendingProcessChanges.get(i);
19661                if (item.pid == app.pid) {
19662                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19663                            "Re-using existing item: " + item);
19664                    break;
19665                }
19666                i--;
19667            }
19668            if (i < 0) {
19669                // No existing item in pending changes; need a new one.
19670                final int NA = mAvailProcessChanges.size();
19671                if (NA > 0) {
19672                    item = mAvailProcessChanges.remove(NA-1);
19673                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19674                            "Retrieving available item: " + item);
19675                } else {
19676                    item = new ProcessChangeItem();
19677                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19678                            "Allocating new item: " + item);
19679                }
19680                item.changes = 0;
19681                item.pid = app.pid;
19682                item.uid = app.info.uid;
19683                if (mPendingProcessChanges.size() == 0) {
19684                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19685                            "*** Enqueueing dispatch processes changed!");
19686                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19687                }
19688                mPendingProcessChanges.add(item);
19689            }
19690            item.changes |= changes;
19691            item.processState = app.repProcState;
19692            item.foregroundActivities = app.repForegroundActivities;
19693            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19694                    "Item " + Integer.toHexString(System.identityHashCode(item))
19695                    + " " + app.toShortString() + ": changes=" + item.changes
19696                    + " procState=" + item.processState
19697                    + " foreground=" + item.foregroundActivities
19698                    + " type=" + app.adjType + " source=" + app.adjSource
19699                    + " target=" + app.adjTarget);
19700        }
19701
19702        return success;
19703    }
19704
19705    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19706        final UidRecord.ChangeItem pendingChange;
19707        if (uidRec == null || uidRec.pendingChange == null) {
19708            if (mPendingUidChanges.size() == 0) {
19709                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19710                        "*** Enqueueing dispatch uid changed!");
19711                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19712            }
19713            final int NA = mAvailUidChanges.size();
19714            if (NA > 0) {
19715                pendingChange = mAvailUidChanges.remove(NA-1);
19716                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19717                        "Retrieving available item: " + pendingChange);
19718            } else {
19719                pendingChange = new UidRecord.ChangeItem();
19720                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19721                        "Allocating new item: " + pendingChange);
19722            }
19723            if (uidRec != null) {
19724                uidRec.pendingChange = pendingChange;
19725                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19726                    // If this uid is going away, and we haven't yet reported it is gone,
19727                    // then do so now.
19728                    change = UidRecord.CHANGE_GONE_IDLE;
19729                }
19730            } else if (uid < 0) {
19731                throw new IllegalArgumentException("No UidRecord or uid");
19732            }
19733            pendingChange.uidRecord = uidRec;
19734            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19735            mPendingUidChanges.add(pendingChange);
19736        } else {
19737            pendingChange = uidRec.pendingChange;
19738            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19739                change = UidRecord.CHANGE_GONE_IDLE;
19740            }
19741        }
19742        pendingChange.change = change;
19743        pendingChange.processState = uidRec != null
19744                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19745    }
19746
19747    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19748            String authority) {
19749        if (app == null) return;
19750        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19751            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19752            if (userState == null) return;
19753            final long now = SystemClock.elapsedRealtime();
19754            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19755            if (lastReported == null || lastReported < now - 60 * 1000L) {
19756                mUsageStatsService.reportContentProviderUsage(
19757                        authority, providerPkgName, app.userId);
19758                userState.mProviderLastReportedFg.put(authority, now);
19759            }
19760        }
19761    }
19762
19763    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19764        if (DEBUG_USAGE_STATS) {
19765            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19766                    + "] state changes: old = " + app.setProcState + ", new = "
19767                    + app.curProcState);
19768        }
19769        if (mUsageStatsService == null) {
19770            return;
19771        }
19772        boolean isInteraction;
19773        // To avoid some abuse patterns, we are going to be careful about what we consider
19774        // to be an app interaction.  Being the top activity doesn't count while the display
19775        // is sleeping, nor do short foreground services.
19776        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19777            isInteraction = true;
19778            app.fgInteractionTime = 0;
19779        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19780            if (app.fgInteractionTime == 0) {
19781                app.fgInteractionTime = nowElapsed;
19782                isInteraction = false;
19783            } else {
19784                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19785            }
19786        } else {
19787            isInteraction = app.curProcState
19788                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19789            app.fgInteractionTime = 0;
19790        }
19791        if (isInteraction && (!app.reportedInteraction
19792                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19793            app.interactionEventTime = nowElapsed;
19794            String[] packages = app.getPackageList();
19795            if (packages != null) {
19796                for (int i = 0; i < packages.length; i++) {
19797                    mUsageStatsService.reportEvent(packages[i], app.userId,
19798                            UsageEvents.Event.SYSTEM_INTERACTION);
19799                }
19800            }
19801        }
19802        app.reportedInteraction = isInteraction;
19803        if (!isInteraction) {
19804            app.interactionEventTime = 0;
19805        }
19806    }
19807
19808    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19809        if (proc.thread != null) {
19810            if (proc.baseProcessTracker != null) {
19811                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19812            }
19813        }
19814    }
19815
19816    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19817            ProcessRecord TOP_APP, boolean doingAll, long now) {
19818        if (app.thread == null) {
19819            return false;
19820        }
19821
19822        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19823
19824        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19825    }
19826
19827    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19828            boolean oomAdj) {
19829        if (isForeground != proc.foregroundServices) {
19830            proc.foregroundServices = isForeground;
19831            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19832                    proc.info.uid);
19833            if (isForeground) {
19834                if (curProcs == null) {
19835                    curProcs = new ArrayList<ProcessRecord>();
19836                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19837                }
19838                if (!curProcs.contains(proc)) {
19839                    curProcs.add(proc);
19840                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19841                            proc.info.packageName, proc.info.uid);
19842                }
19843            } else {
19844                if (curProcs != null) {
19845                    if (curProcs.remove(proc)) {
19846                        mBatteryStatsService.noteEvent(
19847                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19848                                proc.info.packageName, proc.info.uid);
19849                        if (curProcs.size() <= 0) {
19850                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19851                        }
19852                    }
19853                }
19854            }
19855            if (oomAdj) {
19856                updateOomAdjLocked();
19857            }
19858        }
19859    }
19860
19861    private final ActivityRecord resumedAppLocked() {
19862        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19863        String pkg;
19864        int uid;
19865        if (act != null) {
19866            pkg = act.packageName;
19867            uid = act.info.applicationInfo.uid;
19868        } else {
19869            pkg = null;
19870            uid = -1;
19871        }
19872        // Has the UID or resumed package name changed?
19873        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19874                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19875            if (mCurResumedPackage != null) {
19876                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19877                        mCurResumedPackage, mCurResumedUid);
19878            }
19879            mCurResumedPackage = pkg;
19880            mCurResumedUid = uid;
19881            if (mCurResumedPackage != null) {
19882                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19883                        mCurResumedPackage, mCurResumedUid);
19884            }
19885        }
19886        return act;
19887    }
19888
19889    final boolean updateOomAdjLocked(ProcessRecord app) {
19890        final ActivityRecord TOP_ACT = resumedAppLocked();
19891        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19892        final boolean wasCached = app.cached;
19893
19894        mAdjSeq++;
19895
19896        // This is the desired cached adjusment we want to tell it to use.
19897        // If our app is currently cached, we know it, and that is it.  Otherwise,
19898        // we don't know it yet, and it needs to now be cached we will then
19899        // need to do a complete oom adj.
19900        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19901                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19902        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19903                SystemClock.uptimeMillis());
19904        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19905            // Changed to/from cached state, so apps after it in the LRU
19906            // list may also be changed.
19907            updateOomAdjLocked();
19908        }
19909        return success;
19910    }
19911
19912    final void updateOomAdjLocked() {
19913        final ActivityRecord TOP_ACT = resumedAppLocked();
19914        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19915        final long now = SystemClock.uptimeMillis();
19916        final long nowElapsed = SystemClock.elapsedRealtime();
19917        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19918        final int N = mLruProcesses.size();
19919
19920        if (false) {
19921            RuntimeException e = new RuntimeException();
19922            e.fillInStackTrace();
19923            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19924        }
19925
19926        // Reset state in all uid records.
19927        for (int i=mActiveUids.size()-1; i>=0; i--) {
19928            final UidRecord uidRec = mActiveUids.valueAt(i);
19929            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19930                    "Starting update of " + uidRec);
19931            uidRec.reset();
19932        }
19933
19934        mStackSupervisor.rankTaskLayersIfNeeded();
19935
19936        mAdjSeq++;
19937        mNewNumServiceProcs = 0;
19938        mNewNumAServiceProcs = 0;
19939
19940        final int emptyProcessLimit;
19941        final int cachedProcessLimit;
19942        if (mProcessLimit <= 0) {
19943            emptyProcessLimit = cachedProcessLimit = 0;
19944        } else if (mProcessLimit == 1) {
19945            emptyProcessLimit = 1;
19946            cachedProcessLimit = 0;
19947        } else {
19948            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19949            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19950        }
19951
19952        // Let's determine how many processes we have running vs.
19953        // how many slots we have for background processes; we may want
19954        // to put multiple processes in a slot of there are enough of
19955        // them.
19956        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19957                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19958        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19959        if (numEmptyProcs > cachedProcessLimit) {
19960            // If there are more empty processes than our limit on cached
19961            // processes, then use the cached process limit for the factor.
19962            // This ensures that the really old empty processes get pushed
19963            // down to the bottom, so if we are running low on memory we will
19964            // have a better chance at keeping around more cached processes
19965            // instead of a gazillion empty processes.
19966            numEmptyProcs = cachedProcessLimit;
19967        }
19968        int emptyFactor = numEmptyProcs/numSlots;
19969        if (emptyFactor < 1) emptyFactor = 1;
19970        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19971        if (cachedFactor < 1) cachedFactor = 1;
19972        int stepCached = 0;
19973        int stepEmpty = 0;
19974        int numCached = 0;
19975        int numEmpty = 0;
19976        int numTrimming = 0;
19977
19978        mNumNonCachedProcs = 0;
19979        mNumCachedHiddenProcs = 0;
19980
19981        // First update the OOM adjustment for each of the
19982        // application processes based on their current state.
19983        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19984        int nextCachedAdj = curCachedAdj+1;
19985        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19986        int nextEmptyAdj = curEmptyAdj+2;
19987        for (int i=N-1; i>=0; i--) {
19988            ProcessRecord app = mLruProcesses.get(i);
19989            if (!app.killedByAm && app.thread != null) {
19990                app.procStateChanged = false;
19991                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19992
19993                // If we haven't yet assigned the final cached adj
19994                // to the process, do that now.
19995                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19996                    switch (app.curProcState) {
19997                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19998                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19999                            // This process is a cached process holding activities...
20000                            // assign it the next cached value for that type, and then
20001                            // step that cached level.
20002                            app.curRawAdj = curCachedAdj;
20003                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20004                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20005                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20006                                    + ")");
20007                            if (curCachedAdj != nextCachedAdj) {
20008                                stepCached++;
20009                                if (stepCached >= cachedFactor) {
20010                                    stepCached = 0;
20011                                    curCachedAdj = nextCachedAdj;
20012                                    nextCachedAdj += 2;
20013                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20014                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20015                                    }
20016                                }
20017                            }
20018                            break;
20019                        default:
20020                            // For everything else, assign next empty cached process
20021                            // level and bump that up.  Note that this means that
20022                            // long-running services that have dropped down to the
20023                            // cached level will be treated as empty (since their process
20024                            // state is still as a service), which is what we want.
20025                            app.curRawAdj = curEmptyAdj;
20026                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20027                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20028                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20029                                    + ")");
20030                            if (curEmptyAdj != nextEmptyAdj) {
20031                                stepEmpty++;
20032                                if (stepEmpty >= emptyFactor) {
20033                                    stepEmpty = 0;
20034                                    curEmptyAdj = nextEmptyAdj;
20035                                    nextEmptyAdj += 2;
20036                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20037                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20038                                    }
20039                                }
20040                            }
20041                            break;
20042                    }
20043                }
20044
20045                applyOomAdjLocked(app, true, now, nowElapsed);
20046
20047                // Count the number of process types.
20048                switch (app.curProcState) {
20049                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20050                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20051                        mNumCachedHiddenProcs++;
20052                        numCached++;
20053                        if (numCached > cachedProcessLimit) {
20054                            app.kill("cached #" + numCached, true);
20055                        }
20056                        break;
20057                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20058                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20059                                && app.lastActivityTime < oldTime) {
20060                            app.kill("empty for "
20061                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20062                                    / 1000) + "s", true);
20063                        } else {
20064                            numEmpty++;
20065                            if (numEmpty > emptyProcessLimit) {
20066                                app.kill("empty #" + numEmpty, true);
20067                            }
20068                        }
20069                        break;
20070                    default:
20071                        mNumNonCachedProcs++;
20072                        break;
20073                }
20074
20075                if (app.isolated && app.services.size() <= 0) {
20076                    // If this is an isolated process, and there are no
20077                    // services running in it, then the process is no longer
20078                    // needed.  We agressively kill these because we can by
20079                    // definition not re-use the same process again, and it is
20080                    // good to avoid having whatever code was running in them
20081                    // left sitting around after no longer needed.
20082                    app.kill("isolated not needed", true);
20083                } else {
20084                    // Keeping this process, update its uid.
20085                    final UidRecord uidRec = app.uidRecord;
20086                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20087                        uidRec.curProcState = app.curProcState;
20088                    }
20089                }
20090
20091                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20092                        && !app.killedByAm) {
20093                    numTrimming++;
20094                }
20095            }
20096        }
20097
20098        mNumServiceProcs = mNewNumServiceProcs;
20099
20100        // Now determine the memory trimming level of background processes.
20101        // Unfortunately we need to start at the back of the list to do this
20102        // properly.  We only do this if the number of background apps we
20103        // are managing to keep around is less than half the maximum we desire;
20104        // if we are keeping a good number around, we'll let them use whatever
20105        // memory they want.
20106        final int numCachedAndEmpty = numCached + numEmpty;
20107        int memFactor;
20108        if (numCached <= ProcessList.TRIM_CACHED_APPS
20109                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20110            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20111                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20112            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20113                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20114            } else {
20115                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20116            }
20117        } else {
20118            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20119        }
20120        // We always allow the memory level to go up (better).  We only allow it to go
20121        // down if we are in a state where that is allowed, *and* the total number of processes
20122        // has gone down since last time.
20123        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20124                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20125                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20126        if (memFactor > mLastMemoryLevel) {
20127            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20128                memFactor = mLastMemoryLevel;
20129                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20130            }
20131        }
20132        if (memFactor != mLastMemoryLevel) {
20133            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20134        }
20135        mLastMemoryLevel = memFactor;
20136        mLastNumProcesses = mLruProcesses.size();
20137        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20138        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20139        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20140            if (mLowRamStartTime == 0) {
20141                mLowRamStartTime = now;
20142            }
20143            int step = 0;
20144            int fgTrimLevel;
20145            switch (memFactor) {
20146                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20147                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20148                    break;
20149                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20150                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20151                    break;
20152                default:
20153                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20154                    break;
20155            }
20156            int factor = numTrimming/3;
20157            int minFactor = 2;
20158            if (mHomeProcess != null) minFactor++;
20159            if (mPreviousProcess != null) minFactor++;
20160            if (factor < minFactor) factor = minFactor;
20161            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20162            for (int i=N-1; i>=0; i--) {
20163                ProcessRecord app = mLruProcesses.get(i);
20164                if (allChanged || app.procStateChanged) {
20165                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20166                    app.procStateChanged = false;
20167                }
20168                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20169                        && !app.killedByAm) {
20170                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20171                        try {
20172                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20173                                    "Trimming memory of " + app.processName + " to " + curLevel);
20174                            app.thread.scheduleTrimMemory(curLevel);
20175                        } catch (RemoteException e) {
20176                        }
20177                        if (false) {
20178                            // For now we won't do this; our memory trimming seems
20179                            // to be good enough at this point that destroying
20180                            // activities causes more harm than good.
20181                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20182                                    && app != mHomeProcess && app != mPreviousProcess) {
20183                                // Need to do this on its own message because the stack may not
20184                                // be in a consistent state at this point.
20185                                // For these apps we will also finish their activities
20186                                // to help them free memory.
20187                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20188                            }
20189                        }
20190                    }
20191                    app.trimMemoryLevel = curLevel;
20192                    step++;
20193                    if (step >= factor) {
20194                        step = 0;
20195                        switch (curLevel) {
20196                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20197                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20198                                break;
20199                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20200                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20201                                break;
20202                        }
20203                    }
20204                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20205                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20206                            && app.thread != null) {
20207                        try {
20208                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20209                                    "Trimming memory of heavy-weight " + app.processName
20210                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20211                            app.thread.scheduleTrimMemory(
20212                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20213                        } catch (RemoteException e) {
20214                        }
20215                    }
20216                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20217                } else {
20218                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20219                            || app.systemNoUi) && app.pendingUiClean) {
20220                        // If this application is now in the background and it
20221                        // had done UI, then give it the special trim level to
20222                        // have it free UI resources.
20223                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20224                        if (app.trimMemoryLevel < level && app.thread != null) {
20225                            try {
20226                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20227                                        "Trimming memory of bg-ui " + app.processName
20228                                        + " to " + level);
20229                                app.thread.scheduleTrimMemory(level);
20230                            } catch (RemoteException e) {
20231                            }
20232                        }
20233                        app.pendingUiClean = false;
20234                    }
20235                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20236                        try {
20237                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20238                                    "Trimming memory of fg " + app.processName
20239                                    + " to " + fgTrimLevel);
20240                            app.thread.scheduleTrimMemory(fgTrimLevel);
20241                        } catch (RemoteException e) {
20242                        }
20243                    }
20244                    app.trimMemoryLevel = fgTrimLevel;
20245                }
20246            }
20247        } else {
20248            if (mLowRamStartTime != 0) {
20249                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20250                mLowRamStartTime = 0;
20251            }
20252            for (int i=N-1; i>=0; i--) {
20253                ProcessRecord app = mLruProcesses.get(i);
20254                if (allChanged || app.procStateChanged) {
20255                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20256                    app.procStateChanged = false;
20257                }
20258                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20259                        || app.systemNoUi) && app.pendingUiClean) {
20260                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20261                            && app.thread != null) {
20262                        try {
20263                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20264                                    "Trimming memory of ui hidden " + app.processName
20265                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20266                            app.thread.scheduleTrimMemory(
20267                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20268                        } catch (RemoteException e) {
20269                        }
20270                    }
20271                    app.pendingUiClean = false;
20272                }
20273                app.trimMemoryLevel = 0;
20274            }
20275        }
20276
20277        if (mAlwaysFinishActivities) {
20278            // Need to do this on its own message because the stack may not
20279            // be in a consistent state at this point.
20280            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20281        }
20282
20283        if (allChanged) {
20284            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20285        }
20286
20287        // Update from any uid changes.
20288        for (int i=mActiveUids.size()-1; i>=0; i--) {
20289            final UidRecord uidRec = mActiveUids.valueAt(i);
20290            int uidChange = UidRecord.CHANGE_PROCSTATE;
20291            if (uidRec.setProcState != uidRec.curProcState) {
20292                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20293                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20294                        + " to " + uidRec.curProcState);
20295                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20296                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20297                        uidRec.lastBackgroundTime = nowElapsed;
20298                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20299                            // Note: the background settle time is in elapsed realtime, while
20300                            // the handler time base is uptime.  All this means is that we may
20301                            // stop background uids later than we had intended, but that only
20302                            // happens because the device was sleeping so we are okay anyway.
20303                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20304                        }
20305                    }
20306                } else {
20307                    if (uidRec.idle) {
20308                        uidChange = UidRecord.CHANGE_ACTIVE;
20309                        uidRec.idle = false;
20310                    }
20311                    uidRec.lastBackgroundTime = 0;
20312                }
20313                uidRec.setProcState = uidRec.curProcState;
20314                enqueueUidChangeLocked(uidRec, -1, uidChange);
20315                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20316            }
20317        }
20318
20319        if (mProcessStats.shouldWriteNowLocked(now)) {
20320            mHandler.post(new Runnable() {
20321                @Override public void run() {
20322                    synchronized (ActivityManagerService.this) {
20323                        mProcessStats.writeStateAsyncLocked();
20324                    }
20325                }
20326            });
20327        }
20328
20329        if (DEBUG_OOM_ADJ) {
20330            final long duration = SystemClock.uptimeMillis() - now;
20331            if (false) {
20332                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20333                        new RuntimeException("here").fillInStackTrace());
20334            } else {
20335                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20336            }
20337        }
20338    }
20339
20340    final void idleUids() {
20341        synchronized (this) {
20342            final long nowElapsed = SystemClock.elapsedRealtime();
20343            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20344            long nextTime = 0;
20345            for (int i=mActiveUids.size()-1; i>=0; i--) {
20346                final UidRecord uidRec = mActiveUids.valueAt(i);
20347                final long bgTime = uidRec.lastBackgroundTime;
20348                if (bgTime > 0 && !uidRec.idle) {
20349                    if (bgTime <= maxBgTime) {
20350                        uidRec.idle = true;
20351                        doStopUidLocked(uidRec.uid, uidRec);
20352                    } else {
20353                        if (nextTime == 0 || nextTime > bgTime) {
20354                            nextTime = bgTime;
20355                        }
20356                    }
20357                }
20358            }
20359            if (nextTime > 0) {
20360                mHandler.removeMessages(IDLE_UIDS_MSG);
20361                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20362                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20363            }
20364        }
20365    }
20366
20367    final void runInBackgroundDisabled(int uid) {
20368        synchronized (this) {
20369            UidRecord uidRec = mActiveUids.get(uid);
20370            if (uidRec != null) {
20371                // This uid is actually running...  should it be considered background now?
20372                if (uidRec.idle) {
20373                    doStopUidLocked(uidRec.uid, uidRec);
20374                }
20375            } else {
20376                // This uid isn't actually running...  still send a report about it being "stopped".
20377                doStopUidLocked(uid, null);
20378            }
20379        }
20380    }
20381
20382    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20383        mServices.stopInBackgroundLocked(uid);
20384        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20385    }
20386
20387    final void trimApplications() {
20388        synchronized (this) {
20389            int i;
20390
20391            // First remove any unused application processes whose package
20392            // has been removed.
20393            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20394                final ProcessRecord app = mRemovedProcesses.get(i);
20395                if (app.activities.size() == 0
20396                        && app.curReceiver == null && app.services.size() == 0) {
20397                    Slog.i(
20398                        TAG, "Exiting empty application process "
20399                        + app.processName + " ("
20400                        + (app.thread != null ? app.thread.asBinder() : null)
20401                        + ")\n");
20402                    if (app.pid > 0 && app.pid != MY_PID) {
20403                        app.kill("empty", false);
20404                    } else {
20405                        try {
20406                            app.thread.scheduleExit();
20407                        } catch (Exception e) {
20408                            // Ignore exceptions.
20409                        }
20410                    }
20411                    cleanUpApplicationRecordLocked(app, false, true, -1);
20412                    mRemovedProcesses.remove(i);
20413
20414                    if (app.persistent) {
20415                        addAppLocked(app.info, false, null /* ABI override */);
20416                    }
20417                }
20418            }
20419
20420            // Now update the oom adj for all processes.
20421            updateOomAdjLocked();
20422        }
20423    }
20424
20425    /** This method sends the specified signal to each of the persistent apps */
20426    public void signalPersistentProcesses(int sig) throws RemoteException {
20427        if (sig != Process.SIGNAL_USR1) {
20428            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20429        }
20430
20431        synchronized (this) {
20432            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20433                    != PackageManager.PERMISSION_GRANTED) {
20434                throw new SecurityException("Requires permission "
20435                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20436            }
20437
20438            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20439                ProcessRecord r = mLruProcesses.get(i);
20440                if (r.thread != null && r.persistent) {
20441                    Process.sendSignal(r.pid, sig);
20442                }
20443            }
20444        }
20445    }
20446
20447    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20448        if (proc == null || proc == mProfileProc) {
20449            proc = mProfileProc;
20450            profileType = mProfileType;
20451            clearProfilerLocked();
20452        }
20453        if (proc == null) {
20454            return;
20455        }
20456        try {
20457            proc.thread.profilerControl(false, null, profileType);
20458        } catch (RemoteException e) {
20459            throw new IllegalStateException("Process disappeared");
20460        }
20461    }
20462
20463    private void clearProfilerLocked() {
20464        if (mProfileFd != null) {
20465            try {
20466                mProfileFd.close();
20467            } catch (IOException e) {
20468            }
20469        }
20470        mProfileApp = null;
20471        mProfileProc = null;
20472        mProfileFile = null;
20473        mProfileType = 0;
20474        mAutoStopProfiler = false;
20475        mSamplingInterval = 0;
20476    }
20477
20478    public boolean profileControl(String process, int userId, boolean start,
20479            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20480
20481        try {
20482            synchronized (this) {
20483                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20484                // its own permission.
20485                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20486                        != PackageManager.PERMISSION_GRANTED) {
20487                    throw new SecurityException("Requires permission "
20488                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20489                }
20490
20491                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20492                    throw new IllegalArgumentException("null profile info or fd");
20493                }
20494
20495                ProcessRecord proc = null;
20496                if (process != null) {
20497                    proc = findProcessLocked(process, userId, "profileControl");
20498                }
20499
20500                if (start && (proc == null || proc.thread == null)) {
20501                    throw new IllegalArgumentException("Unknown process: " + process);
20502                }
20503
20504                if (start) {
20505                    stopProfilerLocked(null, 0);
20506                    setProfileApp(proc.info, proc.processName, profilerInfo);
20507                    mProfileProc = proc;
20508                    mProfileType = profileType;
20509                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20510                    try {
20511                        fd = fd.dup();
20512                    } catch (IOException e) {
20513                        fd = null;
20514                    }
20515                    profilerInfo.profileFd = fd;
20516                    proc.thread.profilerControl(start, profilerInfo, profileType);
20517                    fd = null;
20518                    mProfileFd = null;
20519                } else {
20520                    stopProfilerLocked(proc, profileType);
20521                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20522                        try {
20523                            profilerInfo.profileFd.close();
20524                        } catch (IOException e) {
20525                        }
20526                    }
20527                }
20528
20529                return true;
20530            }
20531        } catch (RemoteException e) {
20532            throw new IllegalStateException("Process disappeared");
20533        } finally {
20534            if (profilerInfo != null && profilerInfo.profileFd != null) {
20535                try {
20536                    profilerInfo.profileFd.close();
20537                } catch (IOException e) {
20538                }
20539            }
20540        }
20541    }
20542
20543    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20544        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20545                userId, true, ALLOW_FULL_ONLY, callName, null);
20546        ProcessRecord proc = null;
20547        try {
20548            int pid = Integer.parseInt(process);
20549            synchronized (mPidsSelfLocked) {
20550                proc = mPidsSelfLocked.get(pid);
20551            }
20552        } catch (NumberFormatException e) {
20553        }
20554
20555        if (proc == null) {
20556            ArrayMap<String, SparseArray<ProcessRecord>> all
20557                    = mProcessNames.getMap();
20558            SparseArray<ProcessRecord> procs = all.get(process);
20559            if (procs != null && procs.size() > 0) {
20560                proc = procs.valueAt(0);
20561                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20562                    for (int i=1; i<procs.size(); i++) {
20563                        ProcessRecord thisProc = procs.valueAt(i);
20564                        if (thisProc.userId == userId) {
20565                            proc = thisProc;
20566                            break;
20567                        }
20568                    }
20569                }
20570            }
20571        }
20572
20573        return proc;
20574    }
20575
20576    public boolean dumpHeap(String process, int userId, boolean managed,
20577            String path, ParcelFileDescriptor fd) throws RemoteException {
20578
20579        try {
20580            synchronized (this) {
20581                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20582                // its own permission (same as profileControl).
20583                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20584                        != PackageManager.PERMISSION_GRANTED) {
20585                    throw new SecurityException("Requires permission "
20586                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20587                }
20588
20589                if (fd == null) {
20590                    throw new IllegalArgumentException("null fd");
20591                }
20592
20593                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20594                if (proc == null || proc.thread == null) {
20595                    throw new IllegalArgumentException("Unknown process: " + process);
20596                }
20597
20598                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20599                if (!isDebuggable) {
20600                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20601                        throw new SecurityException("Process not debuggable: " + proc);
20602                    }
20603                }
20604
20605                proc.thread.dumpHeap(managed, path, fd);
20606                fd = null;
20607                return true;
20608            }
20609        } catch (RemoteException e) {
20610            throw new IllegalStateException("Process disappeared");
20611        } finally {
20612            if (fd != null) {
20613                try {
20614                    fd.close();
20615                } catch (IOException e) {
20616                }
20617            }
20618        }
20619    }
20620
20621    @Override
20622    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20623            String reportPackage) {
20624        if (processName != null) {
20625            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20626                    "setDumpHeapDebugLimit()");
20627        } else {
20628            synchronized (mPidsSelfLocked) {
20629                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20630                if (proc == null) {
20631                    throw new SecurityException("No process found for calling pid "
20632                            + Binder.getCallingPid());
20633                }
20634                if (!Build.IS_DEBUGGABLE
20635                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20636                    throw new SecurityException("Not running a debuggable build");
20637                }
20638                processName = proc.processName;
20639                uid = proc.uid;
20640                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20641                    throw new SecurityException("Package " + reportPackage + " is not running in "
20642                            + proc);
20643                }
20644            }
20645        }
20646        synchronized (this) {
20647            if (maxMemSize > 0) {
20648                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20649            } else {
20650                if (uid != 0) {
20651                    mMemWatchProcesses.remove(processName, uid);
20652                } else {
20653                    mMemWatchProcesses.getMap().remove(processName);
20654                }
20655            }
20656        }
20657    }
20658
20659    @Override
20660    public void dumpHeapFinished(String path) {
20661        synchronized (this) {
20662            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20663                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20664                        + " does not match last pid " + mMemWatchDumpPid);
20665                return;
20666            }
20667            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20668                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20669                        + " does not match last path " + mMemWatchDumpFile);
20670                return;
20671            }
20672            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20673            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20674        }
20675    }
20676
20677    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20678    public void monitor() {
20679        synchronized (this) { }
20680    }
20681
20682    void onCoreSettingsChange(Bundle settings) {
20683        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20684            ProcessRecord processRecord = mLruProcesses.get(i);
20685            try {
20686                if (processRecord.thread != null) {
20687                    processRecord.thread.setCoreSettings(settings);
20688                }
20689            } catch (RemoteException re) {
20690                /* ignore */
20691            }
20692        }
20693    }
20694
20695    // Multi-user methods
20696
20697    /**
20698     * Start user, if its not already running, but don't bring it to foreground.
20699     */
20700    @Override
20701    public boolean startUserInBackground(final int userId) {
20702        return mUserController.startUser(userId, /* foreground */ false);
20703    }
20704
20705    @Override
20706    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20707        return mUserController.unlockUser(userId, token, secret, listener);
20708    }
20709
20710    @Override
20711    public boolean switchUser(final int targetUserId) {
20712        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20713        UserInfo currentUserInfo;
20714        UserInfo targetUserInfo;
20715        synchronized (this) {
20716            int currentUserId = mUserController.getCurrentUserIdLocked();
20717            currentUserInfo = mUserController.getUserInfo(currentUserId);
20718            targetUserInfo = mUserController.getUserInfo(targetUserId);
20719            if (targetUserInfo == null) {
20720                Slog.w(TAG, "No user info for user #" + targetUserId);
20721                return false;
20722            }
20723            if (!targetUserInfo.supportsSwitchTo()) {
20724                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20725                return false;
20726            }
20727            if (targetUserInfo.isManagedProfile()) {
20728                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20729                return false;
20730            }
20731            mUserController.setTargetUserIdLocked(targetUserId);
20732        }
20733        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20734        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20735        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20736        return true;
20737    }
20738
20739    void scheduleStartProfilesLocked() {
20740        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20741            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20742                    DateUtils.SECOND_IN_MILLIS);
20743        }
20744    }
20745
20746    @Override
20747    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20748        return mUserController.stopUser(userId, force, callback);
20749    }
20750
20751    @Override
20752    public UserInfo getCurrentUser() {
20753        return mUserController.getCurrentUser();
20754    }
20755
20756    @Override
20757    public boolean isUserRunning(int userId, int flags) {
20758        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20759                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20760            String msg = "Permission Denial: isUserRunning() from pid="
20761                    + Binder.getCallingPid()
20762                    + ", uid=" + Binder.getCallingUid()
20763                    + " requires " + INTERACT_ACROSS_USERS;
20764            Slog.w(TAG, msg);
20765            throw new SecurityException(msg);
20766        }
20767        synchronized (this) {
20768            return mUserController.isUserRunningLocked(userId, flags);
20769        }
20770    }
20771
20772    @Override
20773    public int[] getRunningUserIds() {
20774        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20775                != PackageManager.PERMISSION_GRANTED) {
20776            String msg = "Permission Denial: isUserRunning() from pid="
20777                    + Binder.getCallingPid()
20778                    + ", uid=" + Binder.getCallingUid()
20779                    + " requires " + INTERACT_ACROSS_USERS;
20780            Slog.w(TAG, msg);
20781            throw new SecurityException(msg);
20782        }
20783        synchronized (this) {
20784            return mUserController.getStartedUserArrayLocked();
20785        }
20786    }
20787
20788    @Override
20789    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20790        mUserController.registerUserSwitchObserver(observer);
20791    }
20792
20793    @Override
20794    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20795        mUserController.unregisterUserSwitchObserver(observer);
20796    }
20797
20798    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20799        if (info == null) return null;
20800        ApplicationInfo newInfo = new ApplicationInfo(info);
20801        newInfo.initForUser(userId);
20802        return newInfo;
20803    }
20804
20805    public boolean isUserStopped(int userId) {
20806        synchronized (this) {
20807            return mUserController.getStartedUserStateLocked(userId) == null;
20808        }
20809    }
20810
20811    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20812        if (aInfo == null
20813                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20814            return aInfo;
20815        }
20816
20817        ActivityInfo info = new ActivityInfo(aInfo);
20818        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20819        return info;
20820    }
20821
20822    private boolean processSanityChecksLocked(ProcessRecord process) {
20823        if (process == null || process.thread == null) {
20824            return false;
20825        }
20826
20827        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20828        if (!isDebuggable) {
20829            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20830                return false;
20831            }
20832        }
20833
20834        return true;
20835    }
20836
20837    public boolean startBinderTracking() throws RemoteException {
20838        synchronized (this) {
20839            mBinderTransactionTrackingEnabled = true;
20840            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20841            // permission (same as profileControl).
20842            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20843                    != PackageManager.PERMISSION_GRANTED) {
20844                throw new SecurityException("Requires permission "
20845                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20846            }
20847
20848            for (int i = 0; i < mLruProcesses.size(); i++) {
20849                ProcessRecord process = mLruProcesses.get(i);
20850                if (!processSanityChecksLocked(process)) {
20851                    continue;
20852                }
20853                try {
20854                    process.thread.startBinderTracking();
20855                } catch (RemoteException e) {
20856                    Log.v(TAG, "Process disappared");
20857                }
20858            }
20859            return true;
20860        }
20861    }
20862
20863    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20864        try {
20865            synchronized (this) {
20866                mBinderTransactionTrackingEnabled = false;
20867                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20868                // permission (same as profileControl).
20869                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20870                        != PackageManager.PERMISSION_GRANTED) {
20871                    throw new SecurityException("Requires permission "
20872                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20873                }
20874
20875                if (fd == null) {
20876                    throw new IllegalArgumentException("null fd");
20877                }
20878
20879                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20880                pw.println("Binder transaction traces for all processes.\n");
20881                for (ProcessRecord process : mLruProcesses) {
20882                    if (!processSanityChecksLocked(process)) {
20883                        continue;
20884                    }
20885
20886                    pw.println("Traces for process: " + process.processName);
20887                    pw.flush();
20888                    try {
20889                        TransferPipe tp = new TransferPipe();
20890                        try {
20891                            process.thread.stopBinderTrackingAndDump(
20892                                    tp.getWriteFd().getFileDescriptor());
20893                            tp.go(fd.getFileDescriptor());
20894                        } finally {
20895                            tp.kill();
20896                        }
20897                    } catch (IOException e) {
20898                        pw.println("Failure while dumping IPC traces from " + process +
20899                                ".  Exception: " + e);
20900                        pw.flush();
20901                    } catch (RemoteException e) {
20902                        pw.println("Got a RemoteException while dumping IPC traces from " +
20903                                process + ".  Exception: " + e);
20904                        pw.flush();
20905                    }
20906                }
20907                fd = null;
20908                return true;
20909            }
20910        } finally {
20911            if (fd != null) {
20912                try {
20913                    fd.close();
20914                } catch (IOException e) {
20915                }
20916            }
20917        }
20918    }
20919
20920    private final class LocalService extends ActivityManagerInternal {
20921        @Override
20922        public void onWakefulnessChanged(int wakefulness) {
20923            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20924        }
20925
20926        @Override
20927        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20928                String processName, String abiOverride, int uid, Runnable crashHandler) {
20929            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20930                    processName, abiOverride, uid, crashHandler);
20931        }
20932
20933        @Override
20934        public SleepToken acquireSleepToken(String tag) {
20935            Preconditions.checkNotNull(tag);
20936
20937            synchronized (ActivityManagerService.this) {
20938                SleepTokenImpl token = new SleepTokenImpl(tag);
20939                mSleepTokens.add(token);
20940                updateSleepIfNeededLocked();
20941                applyVrModeIfNeededLocked(mFocusedActivity, false);
20942                return token;
20943            }
20944        }
20945
20946        @Override
20947        public ComponentName getHomeActivityForUser(int userId) {
20948            synchronized (ActivityManagerService.this) {
20949                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20950                return homeActivity == null ? null : homeActivity.realActivity;
20951            }
20952        }
20953
20954        @Override
20955        public void onUserRemoved(int userId) {
20956            synchronized (ActivityManagerService.this) {
20957                ActivityManagerService.this.onUserStoppedLocked(userId);
20958            }
20959        }
20960
20961        @Override
20962        public void onLocalVoiceInteractionStarted(IBinder activity,
20963                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20964            synchronized (ActivityManagerService.this) {
20965                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20966                        voiceSession, voiceInteractor);
20967            }
20968        }
20969
20970        @Override
20971        public void notifyStartingWindowDrawn() {
20972            synchronized (ActivityManagerService.this) {
20973                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20974            }
20975        }
20976
20977        @Override
20978        public void notifyAppTransitionStarting(int reason) {
20979            synchronized (ActivityManagerService.this) {
20980                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20981            }
20982        }
20983
20984        @Override
20985        public void notifyAppTransitionFinished() {
20986            synchronized (ActivityManagerService.this) {
20987                mStackSupervisor.notifyAppTransitionDone();
20988            }
20989        }
20990
20991        @Override
20992        public void notifyAppTransitionCancelled() {
20993            synchronized (ActivityManagerService.this) {
20994                mStackSupervisor.notifyAppTransitionDone();
20995            }
20996        }
20997
20998        @Override
20999        public List<IBinder> getTopVisibleActivities() {
21000            synchronized (ActivityManagerService.this) {
21001                return mStackSupervisor.getTopVisibleActivities();
21002            }
21003        }
21004
21005        @Override
21006        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21007            synchronized (ActivityManagerService.this) {
21008                mStackSupervisor.setDockedStackMinimized(minimized);
21009            }
21010        }
21011
21012        @Override
21013        public void killForegroundAppsForUser(int userHandle) {
21014            synchronized (ActivityManagerService.this) {
21015                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21016                final int NP = mProcessNames.getMap().size();
21017                for (int ip = 0; ip < NP; ip++) {
21018                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21019                    final int NA = apps.size();
21020                    for (int ia = 0; ia < NA; ia++) {
21021                        final ProcessRecord app = apps.valueAt(ia);
21022                        if (app.persistent) {
21023                            // We don't kill persistent processes.
21024                            continue;
21025                        }
21026                        if (app.removed) {
21027                            procs.add(app);
21028                        } else if (app.userId == userHandle && app.foregroundActivities) {
21029                            app.removed = true;
21030                            procs.add(app);
21031                        }
21032                    }
21033                }
21034
21035                final int N = procs.size();
21036                for (int i = 0; i < N; i++) {
21037                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21038                }
21039            }
21040        }
21041    }
21042
21043    private final class SleepTokenImpl extends SleepToken {
21044        private final String mTag;
21045        private final long mAcquireTime;
21046
21047        public SleepTokenImpl(String tag) {
21048            mTag = tag;
21049            mAcquireTime = SystemClock.uptimeMillis();
21050        }
21051
21052        @Override
21053        public void release() {
21054            synchronized (ActivityManagerService.this) {
21055                if (mSleepTokens.remove(this)) {
21056                    updateSleepIfNeededLocked();
21057                }
21058            }
21059        }
21060
21061        @Override
21062        public String toString() {
21063            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21064        }
21065    }
21066
21067    /**
21068     * An implementation of IAppTask, that allows an app to manage its own tasks via
21069     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21070     * only the process that calls getAppTasks() can call the AppTask methods.
21071     */
21072    class AppTaskImpl extends IAppTask.Stub {
21073        private int mTaskId;
21074        private int mCallingUid;
21075
21076        public AppTaskImpl(int taskId, int callingUid) {
21077            mTaskId = taskId;
21078            mCallingUid = callingUid;
21079        }
21080
21081        private void checkCaller() {
21082            if (mCallingUid != Binder.getCallingUid()) {
21083                throw new SecurityException("Caller " + mCallingUid
21084                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21085            }
21086        }
21087
21088        @Override
21089        public void finishAndRemoveTask() {
21090            checkCaller();
21091
21092            synchronized (ActivityManagerService.this) {
21093                long origId = Binder.clearCallingIdentity();
21094                try {
21095                    // We remove the task from recents to preserve backwards
21096                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21097                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21098                    }
21099                } finally {
21100                    Binder.restoreCallingIdentity(origId);
21101                }
21102            }
21103        }
21104
21105        @Override
21106        public ActivityManager.RecentTaskInfo getTaskInfo() {
21107            checkCaller();
21108
21109            synchronized (ActivityManagerService.this) {
21110                long origId = Binder.clearCallingIdentity();
21111                try {
21112                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21113                    if (tr == null) {
21114                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21115                    }
21116                    return createRecentTaskInfoFromTaskRecord(tr);
21117                } finally {
21118                    Binder.restoreCallingIdentity(origId);
21119                }
21120            }
21121        }
21122
21123        @Override
21124        public void moveToFront() {
21125            checkCaller();
21126            // Will bring task to front if it already has a root activity.
21127            final long origId = Binder.clearCallingIdentity();
21128            try {
21129                synchronized (this) {
21130                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21131                }
21132            } finally {
21133                Binder.restoreCallingIdentity(origId);
21134            }
21135        }
21136
21137        @Override
21138        public int startActivity(IBinder whoThread, String callingPackage,
21139                Intent intent, String resolvedType, Bundle bOptions) {
21140            checkCaller();
21141
21142            int callingUser = UserHandle.getCallingUserId();
21143            TaskRecord tr;
21144            IApplicationThread appThread;
21145            synchronized (ActivityManagerService.this) {
21146                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21147                if (tr == null) {
21148                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21149                }
21150                appThread = ApplicationThreadNative.asInterface(whoThread);
21151                if (appThread == null) {
21152                    throw new IllegalArgumentException("Bad app thread " + appThread);
21153                }
21154            }
21155            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21156                    resolvedType, null, null, null, null, 0, 0, null, null,
21157                    null, bOptions, false, callingUser, null, tr);
21158        }
21159
21160        @Override
21161        public void setExcludeFromRecents(boolean exclude) {
21162            checkCaller();
21163
21164            synchronized (ActivityManagerService.this) {
21165                long origId = Binder.clearCallingIdentity();
21166                try {
21167                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21168                    if (tr == null) {
21169                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21170                    }
21171                    Intent intent = tr.getBaseIntent();
21172                    if (exclude) {
21173                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21174                    } else {
21175                        intent.setFlags(intent.getFlags()
21176                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21177                    }
21178                } finally {
21179                    Binder.restoreCallingIdentity(origId);
21180                }
21181            }
21182        }
21183    }
21184
21185    /**
21186     * Kill processes for the user with id userId and that depend on the package named packageName
21187     */
21188    @Override
21189    public void killPackageDependents(String packageName, int userId) {
21190        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21191        if (packageName == null) {
21192            throw new NullPointerException(
21193                    "Cannot kill the dependents of a package without its name.");
21194        }
21195
21196        long callingId = Binder.clearCallingIdentity();
21197        IPackageManager pm = AppGlobals.getPackageManager();
21198        int pkgUid = -1;
21199        try {
21200            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21201        } catch (RemoteException e) {
21202        }
21203        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21204            throw new IllegalArgumentException(
21205                    "Cannot kill dependents of non-existing package " + packageName);
21206        }
21207        try {
21208            synchronized(this) {
21209                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21210                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21211                        "dep: " + packageName);
21212            }
21213        } finally {
21214            Binder.restoreCallingIdentity(callingId);
21215        }
21216    }
21217}
21218