ActivityManagerService.java revision 9536c809dda20bd01c3d5c30df046b271ba2ec4f
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.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.Notification;
101import android.app.NotificationManager;
102import android.app.PendingIntent;
103import android.app.ProfilerInfo;
104import android.app.admin.DevicePolicyManager;
105import android.app.assist.AssistContent;
106import android.app.assist.AssistStructure;
107import android.app.backup.IBackupManager;
108import android.app.usage.UsageEvents;
109import android.app.usage.UsageStatsManagerInternal;
110import android.appwidget.AppWidgetManager;
111import android.content.ActivityNotFoundException;
112import android.content.BroadcastReceiver;
113import android.content.ClipData;
114import android.content.ComponentCallbacks2;
115import android.content.ComponentName;
116import android.content.ContentProvider;
117import android.content.ContentResolver;
118import android.content.Context;
119import android.content.DialogInterface;
120import android.content.IContentProvider;
121import android.content.IIntentReceiver;
122import android.content.IIntentSender;
123import android.content.Intent;
124import android.content.IntentFilter;
125import android.content.IntentSender;
126import android.content.pm.ActivityInfo;
127import android.content.pm.ApplicationInfo;
128import android.content.pm.ConfigurationInfo;
129import android.content.pm.IPackageDataObserver;
130import android.content.pm.IPackageManager;
131import android.content.pm.InstrumentationInfo;
132import android.content.pm.PackageInfo;
133import android.content.pm.PackageManager;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PackageManagerInternal;
136import android.content.pm.ParceledListSlice;
137import android.content.pm.PathPermission;
138import android.content.pm.PermissionInfo;
139import android.content.pm.ProviderInfo;
140import android.content.pm.ResolveInfo;
141import android.content.pm.ServiceInfo;
142import android.content.pm.ShortcutServiceInternal;
143import android.content.pm.UserInfo;
144import android.content.res.CompatibilityInfo;
145import android.content.res.Configuration;
146import android.content.res.Resources;
147import android.database.ContentObserver;
148import android.graphics.Bitmap;
149import android.graphics.Point;
150import android.graphics.Rect;
151import android.location.LocationManager;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.BatteryStats;
156import android.os.Binder;
157import android.os.Build;
158import android.os.Bundle;
159import android.os.Debug;
160import android.os.DropBoxManager;
161import android.os.Environment;
162import android.os.FactoryTest;
163import android.os.FileObserver;
164import android.os.FileUtils;
165import android.os.Handler;
166import android.os.IBinder;
167import android.os.IPermissionController;
168import android.os.IProcessInfoService;
169import android.os.IProgressListener;
170import android.os.LocaleList;
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.telecom.TelecomManager;
200import android.text.format.DateUtils;
201import android.text.format.Time;
202import android.text.style.SuggestionSpan;
203import android.util.ArrayMap;
204import android.util.ArraySet;
205import android.util.AtomicFile;
206import android.util.DebugUtils;
207import android.util.DisplayMetrics;
208import android.util.EventLog;
209import android.util.Log;
210import android.util.Pair;
211import android.util.PrintWriterPrinter;
212import android.util.Slog;
213import android.util.SparseArray;
214import android.util.TimeUtils;
215import android.util.Xml;
216import android.view.Display;
217import android.view.Gravity;
218import android.view.LayoutInflater;
219import android.view.View;
220import android.view.WindowManager;
221
222import java.io.File;
223import java.io.FileDescriptor;
224import java.io.FileInputStream;
225import java.io.FileNotFoundException;
226import java.io.FileOutputStream;
227import java.io.IOException;
228import java.io.InputStreamReader;
229import java.io.PrintWriter;
230import java.io.StringWriter;
231import java.lang.ref.WeakReference;
232import java.nio.charset.StandardCharsets;
233import java.util.ArrayList;
234import java.util.Arrays;
235import java.util.Collections;
236import java.util.Comparator;
237import java.util.HashMap;
238import java.util.HashSet;
239import java.util.Iterator;
240import java.util.List;
241import java.util.Locale;
242import java.util.Map;
243import java.util.Objects;
244import java.util.Set;
245import java.util.concurrent.atomic.AtomicBoolean;
246import java.util.concurrent.atomic.AtomicLong;
247
248import dalvik.system.VMRuntime;
249
250import libcore.io.IoUtils;
251import libcore.util.EmptyArray;
252
253import static android.Manifest.permission.INTERACT_ACROSS_USERS;
254import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
255import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
256import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
257import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
258import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
259import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
260import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.HOME_STACK_ID;
263import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
264import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
265import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
266import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
267import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
268import static android.content.pm.PackageManager.GET_PROVIDERS;
269import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
270import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
272import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
276import static android.os.Process.PROC_CHAR;
277import static android.os.Process.PROC_OUT_LONG;
278import static android.os.Process.PROC_PARENS;
279import static android.os.Process.PROC_SPACE_TERM;
280import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
281import static android.provider.Settings.Global.DEBUG_APP;
282import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
283import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
284import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
285import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
286import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
287import static android.provider.Settings.System.FONT_SCALE;
288import static com.android.internal.util.XmlUtils.readBooleanAttribute;
289import static com.android.internal.util.XmlUtils.readIntAttribute;
290import static com.android.internal.util.XmlUtils.readLongAttribute;
291import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
292import static com.android.internal.util.XmlUtils.writeIntAttribute;
293import static com.android.internal.util.XmlUtils.writeLongAttribute;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
351import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
352import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
353import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
354import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
355import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
356import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
357import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
358import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
359import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
360import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
361import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
362import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
363import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
364import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
365import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
366import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
367import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
368import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
369import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
370import static org.xmlpull.v1.XmlPullParser.START_TAG;
371
372public final class ActivityManagerService extends ActivityManagerNative
373        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
374
375    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
376    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
377    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
378    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
379    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
380    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
381    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
382    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
383    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
384    private static final String TAG_LRU = TAG + POSTFIX_LRU;
385    private static final String TAG_MU = TAG + POSTFIX_MU;
386    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
387    private static final String TAG_POWER = TAG + POSTFIX_POWER;
388    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
389    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
390    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
391    private static final String TAG_PSS = TAG + POSTFIX_PSS;
392    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
393    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
394    private static final String TAG_STACK = TAG + POSTFIX_STACK;
395    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
396    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
397    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
398    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
399    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
400
401    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
402    // here so that while the job scheduler can depend on AMS, the other way around
403    // need not be the case.
404    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
405
406    /** Control over CPU and battery monitoring */
407    // write battery stats every 30 minutes.
408    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
409    static final boolean MONITOR_CPU_USAGE = true;
410    // don't sample cpu less than every 5 seconds.
411    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
412    // wait possibly forever for next cpu sample.
413    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
414    static final boolean MONITOR_THREAD_CPU_USAGE = false;
415
416    // The flags that are set for all calls we make to the package manager.
417    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
418
419    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
420
421    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
422
423    // Amount of time after a call to stopAppSwitches() during which we will
424    // prevent further untrusted switches from happening.
425    static final long APP_SWITCH_DELAY_TIME = 5*1000;
426
427    // How long we wait for a launched process to attach to the activity manager
428    // before we decide it's never going to come up for real.
429    static final int PROC_START_TIMEOUT = 10*1000;
430    // How long we wait for an attached process to publish its content providers
431    // before we decide it must be hung.
432    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
433
434    // How long we will retain processes hosting content providers in the "last activity"
435    // state before allowing them to drop down to the regular cached LRU list.  This is
436    // to avoid thrashing of provider processes under low memory situations.
437    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
438
439    // How long we wait for a launched process to attach to the activity manager
440    // before we decide it's never going to come up for real, when the process was
441    // started with a wrapper for instrumentation (such as Valgrind) because it
442    // could take much longer than usual.
443    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
444
445    // How long to wait after going idle before forcing apps to GC.
446    static final int GC_TIMEOUT = 5*1000;
447
448    // The minimum amount of time between successive GC requests for a process.
449    static final int GC_MIN_INTERVAL = 60*1000;
450
451    // The minimum amount of time between successive PSS requests for a process.
452    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
453
454    // The minimum amount of time between successive PSS requests for a process
455    // when the request is due to the memory state being lowered.
456    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
457
458    // The rate at which we check for apps using excessive power -- 15 mins.
459    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
460
461    // The minimum sample duration we will allow before deciding we have
462    // enough data on wake locks to start killing things.
463    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464
465    // The minimum sample duration we will allow before deciding we have
466    // enough data on CPU usage to start killing things.
467    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
468
469    // How long we allow a receiver to run before giving up on it.
470    static final int BROADCAST_FG_TIMEOUT = 10*1000;
471    static final int BROADCAST_BG_TIMEOUT = 60*1000;
472
473    // How long we wait until we timeout on key dispatching.
474    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
475
476    // How long we wait until we timeout on key dispatching during instrumentation.
477    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
478
479    // This is the amount of time an app needs to be running a foreground service before
480    // we will consider it to be doing interaction for usage stats.
481    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
482
483    // Maximum amount of time we will allow to elapse before re-reporting usage stats
484    // interaction with foreground processes.
485    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
486
487    // This is the amount of time we allow an app to settle after it goes into the background,
488    // before we start restricting what it can do.
489    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
490
491    // How long to wait in getAssistContextExtras for the activity and foreground services
492    // to respond with the result.
493    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
494
495    // How long top wait when going through the modern assist (which doesn't need to block
496    // on getting this result before starting to launch its UI).
497    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
498
499    // Maximum number of persisted Uri grants a package is allowed
500    static final int MAX_PERSISTED_URI_GRANTS = 128;
501
502    static final int MY_PID = Process.myPid();
503
504    static final String[] EMPTY_STRING_ARRAY = new String[0];
505
506    // How many bytes to write into the dropbox log before truncating
507    static final int DROPBOX_MAX_SIZE = 192 * 1024;
508    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
509    // as one line, but close enough for now.
510    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
511
512    // Access modes for handleIncomingUser.
513    static final int ALLOW_NON_FULL = 0;
514    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
515    static final int ALLOW_FULL_ONLY = 2;
516
517    // Delay in notifying task stack change listeners (in millis)
518    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
519
520    // Necessary ApplicationInfo flags to mark an app as persistent
521    private static final int PERSISTENT_MASK =
522            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
523
524    // Intent sent when remote bugreport collection has been completed
525    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
526            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
527
528    // Delay to disable app launch boost
529    static final int APP_BOOST_MESSAGE_DELAY = 3000;
530    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
531    static final int APP_BOOST_TIMEOUT = 2500;
532
533    // Used to indicate that a task is removed it should also be removed from recents.
534    private static final boolean REMOVE_FROM_RECENTS = true;
535    // Used to indicate that an app transition should be animated.
536    static final boolean ANIMATE = true;
537
538    // Determines whether to take full screen screenshots
539    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
540    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
541
542    private static native int nativeMigrateToBoost();
543    private static native int nativeMigrateFromBoost();
544    private boolean mIsBoosted = false;
545    private long mBoostStartTime = 0;
546
547    /** All system services */
548    SystemServiceManager mSystemServiceManager;
549
550    private Installer mInstaller;
551
552    /** Run all ActivityStacks through this */
553    final ActivityStackSupervisor mStackSupervisor;
554
555    final ActivityStarter mActivityStarter;
556
557    /** Task stack change listeners. */
558    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
559            new RemoteCallbackList<ITaskStackListener>();
560
561    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
562
563    public IntentFirewall mIntentFirewall;
564
565    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
566    // default actuion automatically.  Important for devices without direct input
567    // devices.
568    private boolean mShowDialogs = true;
569    private boolean mInVrMode = false;
570
571    BroadcastQueue mFgBroadcastQueue;
572    BroadcastQueue mBgBroadcastQueue;
573    // Convenient for easy iteration over the queues. Foreground is first
574    // so that dispatch of foreground broadcasts gets precedence.
575    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
576
577    BroadcastStats mLastBroadcastStats;
578    BroadcastStats mCurBroadcastStats;
579
580    BroadcastQueue broadcastQueueForIntent(Intent intent) {
581        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
582        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
583                "Broadcast intent " + intent + " on "
584                + (isFg ? "foreground" : "background") + " queue");
585        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
586    }
587
588    /**
589     * Activity we have told the window manager to have key focus.
590     */
591    ActivityRecord mFocusedActivity = null;
592
593    /**
594     * User id of the last activity mFocusedActivity was set to.
595     */
596    private int mLastFocusedUserId;
597
598    /**
599     * If non-null, we are tracking the time the user spends in the currently focused app.
600     */
601    private AppTimeTracker mCurAppTimeTracker;
602
603    /**
604     * List of intents that were used to start the most recent tasks.
605     */
606    final RecentTasks mRecentTasks;
607
608    /**
609     * For addAppTask: cached of the last activity component that was added.
610     */
611    ComponentName mLastAddedTaskComponent;
612
613    /**
614     * For addAppTask: cached of the last activity uid that was added.
615     */
616    int mLastAddedTaskUid;
617
618    /**
619     * For addAppTask: cached of the last ActivityInfo that was added.
620     */
621    ActivityInfo mLastAddedTaskActivity;
622
623    /**
624     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
625     */
626    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
627
628    /**
629     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
630     */
631    String mDeviceOwnerName;
632
633    final UserController mUserController;
634
635    final AppErrors mAppErrors;
636
637    boolean mDoingSetFocusedActivity;
638
639    public boolean canShowErrorDialogs() {
640        return mShowDialogs && !mSleeping && !mShuttingDown;
641    }
642
643    // it's a semaphore; boost when 0->1, reset when 1->0
644    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
645        @Override protected Integer initialValue() {
646            return 0;
647        }
648    };
649
650    static void boostPriorityForLockedSection() {
651        if (sIsBoosted.get() == 0) {
652            // boost to prio 118 while holding a global lock
653            Process.setThreadPriority(Process.myTid(), -2);
654            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
655        }
656        int cur = sIsBoosted.get();
657        sIsBoosted.set(cur + 1);
658    }
659
660    static void resetPriorityAfterLockedSection() {
661        sIsBoosted.set(sIsBoosted.get() - 1);
662        if (sIsBoosted.get() == 0) {
663            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
664            Process.setThreadPriority(Process.myTid(), 0);
665        }
666    }
667    public class PendingAssistExtras extends Binder implements Runnable {
668        public final ActivityRecord activity;
669        public final Bundle extras;
670        public final Intent intent;
671        public final String hint;
672        public final IResultReceiver receiver;
673        public final int userHandle;
674        public boolean haveResult = false;
675        public Bundle result = null;
676        public AssistStructure structure = null;
677        public AssistContent content = null;
678        public Bundle receiverExtras;
679
680        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
681                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
682            activity = _activity;
683            extras = _extras;
684            intent = _intent;
685            hint = _hint;
686            receiver = _receiver;
687            receiverExtras = _receiverExtras;
688            userHandle = _userHandle;
689        }
690        @Override
691        public void run() {
692            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
693            synchronized (this) {
694                haveResult = true;
695                notifyAll();
696            }
697            pendingAssistExtrasTimedOut(this);
698        }
699    }
700
701    final ArrayList<PendingAssistExtras> mPendingAssistExtras
702            = new ArrayList<PendingAssistExtras>();
703
704    /**
705     * Process management.
706     */
707    final ProcessList mProcessList = new ProcessList();
708
709    /**
710     * All of the applications we currently have running organized by name.
711     * The keys are strings of the application package name (as
712     * returned by the package manager), and the keys are ApplicationRecord
713     * objects.
714     */
715    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
716
717    /**
718     * Tracking long-term execution of processes to look for abuse and other
719     * bad app behavior.
720     */
721    final ProcessStatsService mProcessStats;
722
723    /**
724     * The currently running isolated processes.
725     */
726    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
727
728    /**
729     * Counter for assigning isolated process uids, to avoid frequently reusing the
730     * same ones.
731     */
732    int mNextIsolatedProcessUid = 0;
733
734    /**
735     * The currently running heavy-weight process, if any.
736     */
737    ProcessRecord mHeavyWeightProcess = null;
738
739    /**
740     * All of the processes we currently have running organized by pid.
741     * The keys are the pid running the application.
742     *
743     * <p>NOTE: This object is protected by its own lock, NOT the global
744     * activity manager lock!
745     */
746    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
747
748    /**
749     * All of the processes that have been forced to be foreground.  The key
750     * is the pid of the caller who requested it (we hold a death
751     * link on it).
752     */
753    abstract class ForegroundToken implements IBinder.DeathRecipient {
754        int pid;
755        IBinder token;
756    }
757    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
758
759    /**
760     * List of records for processes that someone had tried to start before the
761     * system was ready.  We don't start them at that point, but ensure they
762     * are started by the time booting is complete.
763     */
764    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
765
766    /**
767     * List of persistent applications that are in the process
768     * of being started.
769     */
770    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
771
772    /**
773     * Processes that are being forcibly torn down.
774     */
775    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
776
777    /**
778     * List of running applications, sorted by recent usage.
779     * The first entry in the list is the least recently used.
780     */
781    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
782
783    /**
784     * Where in mLruProcesses that the processes hosting activities start.
785     */
786    int mLruProcessActivityStart = 0;
787
788    /**
789     * Where in mLruProcesses that the processes hosting services start.
790     * This is after (lower index) than mLruProcessesActivityStart.
791     */
792    int mLruProcessServiceStart = 0;
793
794    /**
795     * List of processes that should gc as soon as things are idle.
796     */
797    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
798
799    /**
800     * Processes we want to collect PSS data from.
801     */
802    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
803
804    private boolean mBinderTransactionTrackingEnabled = false;
805
806    /**
807     * Last time we requested PSS data of all processes.
808     */
809    long mLastFullPssTime = SystemClock.uptimeMillis();
810
811    /**
812     * If set, the next time we collect PSS data we should do a full collection
813     * with data from native processes and the kernel.
814     */
815    boolean mFullPssPending = false;
816
817    /**
818     * This is the process holding what we currently consider to be
819     * the "home" activity.
820     */
821    ProcessRecord mHomeProcess;
822
823    /**
824     * This is the process holding the activity the user last visited that
825     * is in a different process from the one they are currently in.
826     */
827    ProcessRecord mPreviousProcess;
828
829    /**
830     * The time at which the previous process was last visible.
831     */
832    long mPreviousProcessVisibleTime;
833
834    /**
835     * Track all uids that have actively running processes.
836     */
837    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
838
839    /**
840     * This is for verifying the UID report flow.
841     */
842    static final boolean VALIDATE_UID_STATES = true;
843    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
844
845    /**
846     * Packages that the user has asked to have run in screen size
847     * compatibility mode instead of filling the screen.
848     */
849    final CompatModePackages mCompatModePackages;
850
851    /**
852     * Set of IntentSenderRecord objects that are currently active.
853     */
854    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
855            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
856
857    /**
858     * Fingerprints (hashCode()) of stack traces that we've
859     * already logged DropBox entries for.  Guarded by itself.  If
860     * something (rogue user app) forces this over
861     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
862     */
863    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
864    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
865
866    /**
867     * Strict Mode background batched logging state.
868     *
869     * The string buffer is guarded by itself, and its lock is also
870     * used to determine if another batched write is already
871     * in-flight.
872     */
873    private final StringBuilder mStrictModeBuffer = new StringBuilder();
874
875    /**
876     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
877     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
878     */
879    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
880
881    /**
882     * Resolver for broadcast intents to registered receivers.
883     * Holds BroadcastFilter (subclass of IntentFilter).
884     */
885    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
886            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
887        @Override
888        protected boolean allowFilterResult(
889                BroadcastFilter filter, List<BroadcastFilter> dest) {
890            IBinder target = filter.receiverList.receiver.asBinder();
891            for (int i = dest.size() - 1; i >= 0; i--) {
892                if (dest.get(i).receiverList.receiver.asBinder() == target) {
893                    return false;
894                }
895            }
896            return true;
897        }
898
899        @Override
900        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
901            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
902                    || userId == filter.owningUserId) {
903                return super.newResult(filter, match, userId);
904            }
905            return null;
906        }
907
908        @Override
909        protected BroadcastFilter[] newArray(int size) {
910            return new BroadcastFilter[size];
911        }
912
913        @Override
914        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
915            return packageName.equals(filter.packageName);
916        }
917    };
918
919    /**
920     * State of all active sticky broadcasts per user.  Keys are the action of the
921     * sticky Intent, values are an ArrayList of all broadcasted intents with
922     * that action (which should usually be one).  The SparseArray is keyed
923     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
924     * for stickies that are sent to all users.
925     */
926    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
927            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
928
929    final ActiveServices mServices;
930
931    final static class Association {
932        final int mSourceUid;
933        final String mSourceProcess;
934        final int mTargetUid;
935        final ComponentName mTargetComponent;
936        final String mTargetProcess;
937
938        int mCount;
939        long mTime;
940
941        int mNesting;
942        long mStartTime;
943
944        // states of the source process when the bind occurred.
945        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
946        long mLastStateUptime;
947        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
948                - ActivityManager.MIN_PROCESS_STATE+1];
949
950        Association(int sourceUid, String sourceProcess, int targetUid,
951                ComponentName targetComponent, String targetProcess) {
952            mSourceUid = sourceUid;
953            mSourceProcess = sourceProcess;
954            mTargetUid = targetUid;
955            mTargetComponent = targetComponent;
956            mTargetProcess = targetProcess;
957        }
958    }
959
960    /**
961     * When service association tracking is enabled, this is all of the associations we
962     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
963     * -> association data.
964     */
965    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
966            mAssociations = new SparseArray<>();
967    boolean mTrackingAssociations;
968
969    /**
970     * Backup/restore process management
971     */
972    String mBackupAppName = null;
973    BackupRecord mBackupTarget = null;
974
975    final ProviderMap mProviderMap;
976
977    /**
978     * List of content providers who have clients waiting for them.  The
979     * application is currently being launched and the provider will be
980     * removed from this list once it is published.
981     */
982    final ArrayList<ContentProviderRecord> mLaunchingProviders
983            = new ArrayList<ContentProviderRecord>();
984
985    /**
986     * File storing persisted {@link #mGrantedUriPermissions}.
987     */
988    private final AtomicFile mGrantFile;
989
990    /** XML constants used in {@link #mGrantFile} */
991    private static final String TAG_URI_GRANTS = "uri-grants";
992    private static final String TAG_URI_GRANT = "uri-grant";
993    private static final String ATTR_USER_HANDLE = "userHandle";
994    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
995    private static final String ATTR_TARGET_USER_ID = "targetUserId";
996    private static final String ATTR_SOURCE_PKG = "sourcePkg";
997    private static final String ATTR_TARGET_PKG = "targetPkg";
998    private static final String ATTR_URI = "uri";
999    private static final String ATTR_MODE_FLAGS = "modeFlags";
1000    private static final String ATTR_CREATED_TIME = "createdTime";
1001    private static final String ATTR_PREFIX = "prefix";
1002
1003    /**
1004     * Global set of specific {@link Uri} permissions that have been granted.
1005     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1006     * to {@link UriPermission#uri} to {@link UriPermission}.
1007     */
1008    @GuardedBy("this")
1009    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1010            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1011
1012    public static class GrantUri {
1013        public final int sourceUserId;
1014        public final Uri uri;
1015        public boolean prefix;
1016
1017        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1018            this.sourceUserId = sourceUserId;
1019            this.uri = uri;
1020            this.prefix = prefix;
1021        }
1022
1023        @Override
1024        public int hashCode() {
1025            int hashCode = 1;
1026            hashCode = 31 * hashCode + sourceUserId;
1027            hashCode = 31 * hashCode + uri.hashCode();
1028            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1029            return hashCode;
1030        }
1031
1032        @Override
1033        public boolean equals(Object o) {
1034            if (o instanceof GrantUri) {
1035                GrantUri other = (GrantUri) o;
1036                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1037                        && prefix == other.prefix;
1038            }
1039            return false;
1040        }
1041
1042        @Override
1043        public String toString() {
1044            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1045            if (prefix) result += " [prefix]";
1046            return result;
1047        }
1048
1049        public String toSafeString() {
1050            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1051            if (prefix) result += " [prefix]";
1052            return result;
1053        }
1054
1055        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1056            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1057                    ContentProvider.getUriWithoutUserId(uri), false);
1058        }
1059    }
1060
1061    CoreSettingsObserver mCoreSettingsObserver;
1062
1063    FontScaleSettingObserver mFontScaleSettingObserver;
1064
1065    private final class FontScaleSettingObserver extends ContentObserver {
1066        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1067
1068        public FontScaleSettingObserver() {
1069            super(mHandler);
1070            ContentResolver resolver = mContext.getContentResolver();
1071            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1072        }
1073
1074        @Override
1075        public void onChange(boolean selfChange, Uri uri) {
1076            if (mFontScaleUri.equals(uri)) {
1077                updateFontScaleIfNeeded();
1078            }
1079        }
1080    }
1081
1082    /**
1083     * Thread-local storage used to carry caller permissions over through
1084     * indirect content-provider access.
1085     */
1086    private class Identity {
1087        public final IBinder token;
1088        public final int pid;
1089        public final int uid;
1090
1091        Identity(IBinder _token, int _pid, int _uid) {
1092            token = _token;
1093            pid = _pid;
1094            uid = _uid;
1095        }
1096    }
1097
1098    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1099
1100    /**
1101     * All information we have collected about the runtime performance of
1102     * any user id that can impact battery performance.
1103     */
1104    final BatteryStatsService mBatteryStatsService;
1105
1106    /**
1107     * Information about component usage
1108     */
1109    UsageStatsManagerInternal mUsageStatsService;
1110
1111    /**
1112     * Access to DeviceIdleController service.
1113     */
1114    DeviceIdleController.LocalService mLocalDeviceIdleController;
1115
1116    /**
1117     * Information about and control over application operations
1118     */
1119    final AppOpsService mAppOpsService;
1120
1121    /**
1122     * Current configuration information.  HistoryRecord objects are given
1123     * a reference to this object to indicate which configuration they are
1124     * currently running in, so this object must be kept immutable.
1125     */
1126    Configuration mConfiguration = new Configuration();
1127
1128    /**
1129     * Current sequencing integer of the configuration, for skipping old
1130     * configurations.
1131     */
1132    int mConfigurationSeq = 0;
1133
1134    boolean mSuppressResizeConfigChanges = false;
1135
1136    /**
1137     * Hardware-reported OpenGLES version.
1138     */
1139    final int GL_ES_VERSION;
1140
1141    /**
1142     * List of initialization arguments to pass to all processes when binding applications to them.
1143     * For example, references to the commonly used services.
1144     */
1145    HashMap<String, IBinder> mAppBindArgs;
1146
1147    /**
1148     * Temporary to avoid allocations.  Protected by main lock.
1149     */
1150    final StringBuilder mStringBuilder = new StringBuilder(256);
1151
1152    /**
1153     * Used to control how we initialize the service.
1154     */
1155    ComponentName mTopComponent;
1156    String mTopAction = Intent.ACTION_MAIN;
1157    String mTopData;
1158
1159    volatile boolean mProcessesReady = false;
1160    volatile boolean mSystemReady = false;
1161    volatile boolean mOnBattery = false;
1162    volatile int mFactoryTest;
1163
1164    @GuardedBy("this") boolean mBooting = false;
1165    @GuardedBy("this") boolean mCallFinishBooting = false;
1166    @GuardedBy("this") boolean mBootAnimationComplete = false;
1167    @GuardedBy("this") boolean mLaunchWarningShown = false;
1168    @GuardedBy("this") boolean mCheckedForSetup = false;
1169
1170    Context mContext;
1171
1172    /**
1173     * The time at which we will allow normal application switches again,
1174     * after a call to {@link #stopAppSwitches()}.
1175     */
1176    long mAppSwitchesAllowedTime;
1177
1178    /**
1179     * This is set to true after the first switch after mAppSwitchesAllowedTime
1180     * is set; any switches after that will clear the time.
1181     */
1182    boolean mDidAppSwitch;
1183
1184    /**
1185     * Last time (in realtime) at which we checked for power usage.
1186     */
1187    long mLastPowerCheckRealtime;
1188
1189    /**
1190     * Last time (in uptime) at which we checked for power usage.
1191     */
1192    long mLastPowerCheckUptime;
1193
1194    /**
1195     * Set while we are wanting to sleep, to prevent any
1196     * activities from being started/resumed.
1197     */
1198    private boolean mSleeping = false;
1199
1200    /**
1201     * The process state used for processes that are running the top activities.
1202     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1203     */
1204    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1205
1206    /**
1207     * Set while we are running a voice interaction.  This overrides
1208     * sleeping while it is active.
1209     */
1210    private IVoiceInteractionSession mRunningVoice;
1211
1212    /**
1213     * For some direct access we need to power manager.
1214     */
1215    PowerManagerInternal mLocalPowerManager;
1216
1217    /**
1218     * We want to hold a wake lock while running a voice interaction session, since
1219     * this may happen with the screen off and we need to keep the CPU running to
1220     * be able to continue to interact with the user.
1221     */
1222    PowerManager.WakeLock mVoiceWakeLock;
1223
1224    /**
1225     * State of external calls telling us if the device is awake or asleep.
1226     */
1227    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1228
1229    /**
1230     * A list of tokens that cause the top activity to be put to sleep.
1231     * They are used by components that may hide and block interaction with underlying
1232     * activities.
1233     */
1234    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1235
1236    static final int LOCK_SCREEN_HIDDEN = 0;
1237    static final int LOCK_SCREEN_LEAVING = 1;
1238    static final int LOCK_SCREEN_SHOWN = 2;
1239    /**
1240     * State of external call telling us if the lock screen is shown.
1241     */
1242    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1243
1244    /**
1245     * Set if we are shutting down the system, similar to sleeping.
1246     */
1247    boolean mShuttingDown = false;
1248
1249    /**
1250     * Current sequence id for oom_adj computation traversal.
1251     */
1252    int mAdjSeq = 0;
1253
1254    /**
1255     * Current sequence id for process LRU updating.
1256     */
1257    int mLruSeq = 0;
1258
1259    /**
1260     * Keep track of the non-cached/empty process we last found, to help
1261     * determine how to distribute cached/empty processes next time.
1262     */
1263    int mNumNonCachedProcs = 0;
1264
1265    /**
1266     * Keep track of the number of cached hidden procs, to balance oom adj
1267     * distribution between those and empty procs.
1268     */
1269    int mNumCachedHiddenProcs = 0;
1270
1271    /**
1272     * Keep track of the number of service processes we last found, to
1273     * determine on the next iteration which should be B services.
1274     */
1275    int mNumServiceProcs = 0;
1276    int mNewNumAServiceProcs = 0;
1277    int mNewNumServiceProcs = 0;
1278
1279    /**
1280     * Allow the current computed overall memory level of the system to go down?
1281     * This is set to false when we are killing processes for reasons other than
1282     * memory management, so that the now smaller process list will not be taken as
1283     * an indication that memory is tighter.
1284     */
1285    boolean mAllowLowerMemLevel = false;
1286
1287    /**
1288     * The last computed memory level, for holding when we are in a state that
1289     * processes are going away for other reasons.
1290     */
1291    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1292
1293    /**
1294     * The last total number of process we have, to determine if changes actually look
1295     * like a shrinking number of process due to lower RAM.
1296     */
1297    int mLastNumProcesses;
1298
1299    /**
1300     * The uptime of the last time we performed idle maintenance.
1301     */
1302    long mLastIdleTime = SystemClock.uptimeMillis();
1303
1304    /**
1305     * Total time spent with RAM that has been added in the past since the last idle time.
1306     */
1307    long mLowRamTimeSinceLastIdle = 0;
1308
1309    /**
1310     * If RAM is currently low, when that horrible situation started.
1311     */
1312    long mLowRamStartTime = 0;
1313
1314    /**
1315     * For reporting to battery stats the current top application.
1316     */
1317    private String mCurResumedPackage = null;
1318    private int mCurResumedUid = -1;
1319
1320    /**
1321     * For reporting to battery stats the apps currently running foreground
1322     * service.  The ProcessMap is package/uid tuples; each of these contain
1323     * an array of the currently foreground processes.
1324     */
1325    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1326            = new ProcessMap<ArrayList<ProcessRecord>>();
1327
1328    /**
1329     * This is set if we had to do a delayed dexopt of an app before launching
1330     * it, to increase the ANR timeouts in that case.
1331     */
1332    boolean mDidDexOpt;
1333
1334    /**
1335     * Set if the systemServer made a call to enterSafeMode.
1336     */
1337    boolean mSafeMode;
1338
1339    /**
1340     * If true, we are running under a test environment so will sample PSS from processes
1341     * much more rapidly to try to collect better data when the tests are rapidly
1342     * running through apps.
1343     */
1344    boolean mTestPssMode = false;
1345
1346    String mDebugApp = null;
1347    boolean mWaitForDebugger = false;
1348    boolean mDebugTransient = false;
1349    String mOrigDebugApp = null;
1350    boolean mOrigWaitForDebugger = false;
1351    boolean mAlwaysFinishActivities = false;
1352    boolean mLenientBackgroundCheck = false;
1353    boolean mForceResizableActivities;
1354    boolean mSupportsMultiWindow;
1355    boolean mSupportsFreeformWindowManagement;
1356    boolean mSupportsPictureInPicture;
1357    boolean mSupportsLeanbackOnly;
1358    Rect mDefaultPinnedStackBounds;
1359    IActivityController mController = null;
1360    boolean mControllerIsAMonkey = false;
1361    String mProfileApp = null;
1362    ProcessRecord mProfileProc = null;
1363    String mProfileFile;
1364    ParcelFileDescriptor mProfileFd;
1365    int mSamplingInterval = 0;
1366    boolean mAutoStopProfiler = false;
1367    int mProfileType = 0;
1368    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1369    String mMemWatchDumpProcName;
1370    String mMemWatchDumpFile;
1371    int mMemWatchDumpPid;
1372    int mMemWatchDumpUid;
1373    String mTrackAllocationApp = null;
1374    String mNativeDebuggingApp = null;
1375
1376    final long[] mTmpLong = new long[2];
1377
1378    static final class ProcessChangeItem {
1379        static final int CHANGE_ACTIVITIES = 1<<0;
1380        static final int CHANGE_PROCESS_STATE = 1<<1;
1381        int changes;
1382        int uid;
1383        int pid;
1384        int processState;
1385        boolean foregroundActivities;
1386    }
1387
1388    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1389    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1390
1391    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1392    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1393
1394    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1395    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1396
1397    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1398    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1399
1400    /**
1401     * Runtime CPU use collection thread.  This object's lock is used to
1402     * perform synchronization with the thread (notifying it to run).
1403     */
1404    final Thread mProcessCpuThread;
1405
1406    /**
1407     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1408     * Must acquire this object's lock when accessing it.
1409     * NOTE: this lock will be held while doing long operations (trawling
1410     * through all processes in /proc), so it should never be acquired by
1411     * any critical paths such as when holding the main activity manager lock.
1412     */
1413    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1414            MONITOR_THREAD_CPU_USAGE);
1415    final AtomicLong mLastCpuTime = new AtomicLong(0);
1416    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1417
1418    long mLastWriteTime = 0;
1419
1420    /**
1421     * Used to retain an update lock when the foreground activity is in
1422     * immersive mode.
1423     */
1424    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1425
1426    /**
1427     * Set to true after the system has finished booting.
1428     */
1429    boolean mBooted = false;
1430
1431    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1432    int mProcessLimitOverride = -1;
1433
1434    WindowManagerService mWindowManager;
1435    final ActivityThread mSystemThread;
1436
1437    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1438        final ProcessRecord mApp;
1439        final int mPid;
1440        final IApplicationThread mAppThread;
1441
1442        AppDeathRecipient(ProcessRecord app, int pid,
1443                IApplicationThread thread) {
1444            if (DEBUG_ALL) Slog.v(
1445                TAG, "New death recipient " + this
1446                + " for thread " + thread.asBinder());
1447            mApp = app;
1448            mPid = pid;
1449            mAppThread = thread;
1450        }
1451
1452        @Override
1453        public void binderDied() {
1454            if (DEBUG_ALL) Slog.v(
1455                TAG, "Death received in " + this
1456                + " for thread " + mAppThread.asBinder());
1457            synchronized(ActivityManagerService.this) {
1458                appDiedLocked(mApp, mPid, mAppThread, true);
1459            }
1460        }
1461    }
1462
1463    static final int SHOW_ERROR_UI_MSG = 1;
1464    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1465    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1466    static final int UPDATE_CONFIGURATION_MSG = 4;
1467    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1468    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1469    static final int SERVICE_TIMEOUT_MSG = 12;
1470    static final int UPDATE_TIME_ZONE = 13;
1471    static final int SHOW_UID_ERROR_UI_MSG = 14;
1472    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1473    static final int PROC_START_TIMEOUT_MSG = 20;
1474    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1475    static final int KILL_APPLICATION_MSG = 22;
1476    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1477    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1478    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1479    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1480    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1481    static final int CLEAR_DNS_CACHE_MSG = 28;
1482    static final int UPDATE_HTTP_PROXY_MSG = 29;
1483    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1484    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1485    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1486    static final int REPORT_MEM_USAGE_MSG = 33;
1487    static final int REPORT_USER_SWITCH_MSG = 34;
1488    static final int CONTINUE_USER_SWITCH_MSG = 35;
1489    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1490    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1491    static final int PERSIST_URI_GRANTS_MSG = 38;
1492    static final int REQUEST_ALL_PSS_MSG = 39;
1493    static final int START_PROFILES_MSG = 40;
1494    static final int UPDATE_TIME = 41;
1495    static final int SYSTEM_USER_START_MSG = 42;
1496    static final int SYSTEM_USER_CURRENT_MSG = 43;
1497    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1498    static final int FINISH_BOOTING_MSG = 45;
1499    static final int START_USER_SWITCH_UI_MSG = 46;
1500    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1501    static final int DISMISS_DIALOG_UI_MSG = 48;
1502    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1503    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1504    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1505    static final int DELETE_DUMPHEAP_MSG = 52;
1506    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1507    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1508    static final int REPORT_TIME_TRACKER_MSG = 55;
1509    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1510    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1511    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1512    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1513    static final int IDLE_UIDS_MSG = 60;
1514    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1515    static final int LOG_STACK_STATE = 62;
1516    static final int VR_MODE_CHANGE_MSG = 63;
1517    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1518    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1519    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1520    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1521    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1522    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1523    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1524
1525    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1526    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1527    static final int FIRST_COMPAT_MODE_MSG = 300;
1528    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1529
1530    static ServiceThread sKillThread = null;
1531    static KillHandler sKillHandler = null;
1532
1533    CompatModeDialog mCompatModeDialog;
1534    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1535    long mLastMemUsageReportTime = 0;
1536
1537    /**
1538     * Flag whether the current user is a "monkey", i.e. whether
1539     * the UI is driven by a UI automation tool.
1540     */
1541    private boolean mUserIsMonkey;
1542
1543    /** Flag whether the device has a Recents UI */
1544    boolean mHasRecents;
1545
1546    /** The dimensions of the thumbnails in the Recents UI. */
1547    int mThumbnailWidth;
1548    int mThumbnailHeight;
1549    float mFullscreenThumbnailScale;
1550
1551    final ServiceThread mHandlerThread;
1552    final MainHandler mHandler;
1553    final UiHandler mUiHandler;
1554
1555    PackageManagerInternal mPackageManagerInt;
1556
1557    // VoiceInteraction session ID that changes for each new request except when
1558    // being called for multiwindow assist in a single session.
1559    private int mViSessionId = 1000;
1560
1561    final class KillHandler extends Handler {
1562        static final int KILL_PROCESS_GROUP_MSG = 4000;
1563
1564        public KillHandler(Looper looper) {
1565            super(looper, null, true);
1566        }
1567
1568        @Override
1569        public void handleMessage(Message msg) {
1570            switch (msg.what) {
1571                case KILL_PROCESS_GROUP_MSG:
1572                {
1573                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1574                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1575                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1576                }
1577                break;
1578
1579                default:
1580                    super.handleMessage(msg);
1581            }
1582        }
1583    }
1584
1585    final class UiHandler extends Handler {
1586        public UiHandler() {
1587            super(com.android.server.UiThread.get().getLooper(), null, true);
1588        }
1589
1590        @Override
1591        public void handleMessage(Message msg) {
1592            switch (msg.what) {
1593            case SHOW_ERROR_UI_MSG: {
1594                mAppErrors.handleShowAppErrorUi(msg);
1595                ensureBootCompleted();
1596            } break;
1597            case SHOW_NOT_RESPONDING_UI_MSG: {
1598                mAppErrors.handleShowAnrUi(msg);
1599                ensureBootCompleted();
1600            } break;
1601            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1602                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1603                synchronized (ActivityManagerService.this) {
1604                    ProcessRecord proc = (ProcessRecord) data.get("app");
1605                    if (proc == null) {
1606                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1607                        break;
1608                    }
1609                    if (proc.crashDialog != null) {
1610                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1611                        return;
1612                    }
1613                    AppErrorResult res = (AppErrorResult) data.get("result");
1614                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1615                        Dialog d = new StrictModeViolationDialog(mContext,
1616                                ActivityManagerService.this, res, proc);
1617                        d.show();
1618                        proc.crashDialog = d;
1619                    } else {
1620                        // The device is asleep, so just pretend that the user
1621                        // saw a crash dialog and hit "force quit".
1622                        res.set(0);
1623                    }
1624                }
1625                ensureBootCompleted();
1626            } break;
1627            case SHOW_FACTORY_ERROR_UI_MSG: {
1628                Dialog d = new FactoryErrorDialog(
1629                    mContext, msg.getData().getCharSequence("msg"));
1630                d.show();
1631                ensureBootCompleted();
1632            } break;
1633            case WAIT_FOR_DEBUGGER_UI_MSG: {
1634                synchronized (ActivityManagerService.this) {
1635                    ProcessRecord app = (ProcessRecord)msg.obj;
1636                    if (msg.arg1 != 0) {
1637                        if (!app.waitedForDebugger) {
1638                            Dialog d = new AppWaitingForDebuggerDialog(
1639                                    ActivityManagerService.this,
1640                                    mContext, app);
1641                            app.waitDialog = d;
1642                            app.waitedForDebugger = true;
1643                            d.show();
1644                        }
1645                    } else {
1646                        if (app.waitDialog != null) {
1647                            app.waitDialog.dismiss();
1648                            app.waitDialog = null;
1649                        }
1650                    }
1651                }
1652            } break;
1653            case SHOW_UID_ERROR_UI_MSG: {
1654                if (mShowDialogs) {
1655                    AlertDialog d = new BaseErrorDialog(mContext);
1656                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1657                    d.setCancelable(false);
1658                    d.setTitle(mContext.getText(R.string.android_system_label));
1659                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1660                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1661                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1662                    d.show();
1663                }
1664            } break;
1665            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1666                if (mShowDialogs) {
1667                    AlertDialog d = new BaseErrorDialog(mContext);
1668                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1669                    d.setCancelable(false);
1670                    d.setTitle(mContext.getText(R.string.android_system_label));
1671                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1672                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1673                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1674                    d.show();
1675                }
1676            } break;
1677            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1678                synchronized (ActivityManagerService.this) {
1679                    ActivityRecord ar = (ActivityRecord) msg.obj;
1680                    if (mCompatModeDialog != null) {
1681                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1682                                ar.info.applicationInfo.packageName)) {
1683                            return;
1684                        }
1685                        mCompatModeDialog.dismiss();
1686                        mCompatModeDialog = null;
1687                    }
1688                    if (ar != null && false) {
1689                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1690                                ar.packageName)) {
1691                            int mode = mCompatModePackages.computeCompatModeLocked(
1692                                    ar.info.applicationInfo);
1693                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1694                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1695                                mCompatModeDialog = new CompatModeDialog(
1696                                        ActivityManagerService.this, mContext,
1697                                        ar.info.applicationInfo);
1698                                mCompatModeDialog.show();
1699                            }
1700                        }
1701                    }
1702                }
1703                break;
1704            }
1705            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1706                synchronized (ActivityManagerService.this) {
1707                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1708                    if (mUnsupportedDisplaySizeDialog != null) {
1709                        mUnsupportedDisplaySizeDialog.dismiss();
1710                        mUnsupportedDisplaySizeDialog = null;
1711                    }
1712                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1713                            ar.packageName)) {
1714                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1715                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1716                        mUnsupportedDisplaySizeDialog.show();
1717                    }
1718                }
1719                break;
1720            }
1721            case START_USER_SWITCH_UI_MSG: {
1722                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1723                break;
1724            }
1725            case DISMISS_DIALOG_UI_MSG: {
1726                final Dialog d = (Dialog) msg.obj;
1727                d.dismiss();
1728                break;
1729            }
1730            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1731                dispatchProcessesChanged();
1732                break;
1733            }
1734            case DISPATCH_PROCESS_DIED_UI_MSG: {
1735                final int pid = msg.arg1;
1736                final int uid = msg.arg2;
1737                dispatchProcessDied(pid, uid);
1738                break;
1739            }
1740            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1741                dispatchUidsChanged();
1742            } break;
1743            }
1744        }
1745    }
1746
1747    final class MainHandler extends Handler {
1748        public MainHandler(Looper looper) {
1749            super(looper, null, true);
1750        }
1751
1752        @Override
1753        public void handleMessage(Message msg) {
1754            switch (msg.what) {
1755            case UPDATE_CONFIGURATION_MSG: {
1756                final ContentResolver resolver = mContext.getContentResolver();
1757                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1758                        msg.arg1);
1759            } break;
1760            case GC_BACKGROUND_PROCESSES_MSG: {
1761                synchronized (ActivityManagerService.this) {
1762                    performAppGcsIfAppropriateLocked();
1763                }
1764            } break;
1765            case SERVICE_TIMEOUT_MSG: {
1766                if (mDidDexOpt) {
1767                    mDidDexOpt = false;
1768                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1769                    nmsg.obj = msg.obj;
1770                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1771                    return;
1772                }
1773                mServices.serviceTimeout((ProcessRecord)msg.obj);
1774            } break;
1775            case UPDATE_TIME_ZONE: {
1776                synchronized (ActivityManagerService.this) {
1777                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1778                        ProcessRecord r = mLruProcesses.get(i);
1779                        if (r.thread != null) {
1780                            try {
1781                                r.thread.updateTimeZone();
1782                            } catch (RemoteException ex) {
1783                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1784                            }
1785                        }
1786                    }
1787                }
1788            } break;
1789            case CLEAR_DNS_CACHE_MSG: {
1790                synchronized (ActivityManagerService.this) {
1791                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1792                        ProcessRecord r = mLruProcesses.get(i);
1793                        if (r.thread != null) {
1794                            try {
1795                                r.thread.clearDnsCache();
1796                            } catch (RemoteException ex) {
1797                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1798                            }
1799                        }
1800                    }
1801                }
1802            } break;
1803            case UPDATE_HTTP_PROXY_MSG: {
1804                ProxyInfo proxy = (ProxyInfo)msg.obj;
1805                String host = "";
1806                String port = "";
1807                String exclList = "";
1808                Uri pacFileUrl = Uri.EMPTY;
1809                if (proxy != null) {
1810                    host = proxy.getHost();
1811                    port = Integer.toString(proxy.getPort());
1812                    exclList = proxy.getExclusionListAsString();
1813                    pacFileUrl = proxy.getPacFileUrl();
1814                }
1815                synchronized (ActivityManagerService.this) {
1816                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1817                        ProcessRecord r = mLruProcesses.get(i);
1818                        if (r.thread != null) {
1819                            try {
1820                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1821                            } catch (RemoteException ex) {
1822                                Slog.w(TAG, "Failed to update http proxy for: " +
1823                                        r.info.processName);
1824                            }
1825                        }
1826                    }
1827                }
1828            } break;
1829            case PROC_START_TIMEOUT_MSG: {
1830                if (mDidDexOpt) {
1831                    mDidDexOpt = false;
1832                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1833                    nmsg.obj = msg.obj;
1834                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1835                    return;
1836                }
1837                ProcessRecord app = (ProcessRecord)msg.obj;
1838                synchronized (ActivityManagerService.this) {
1839                    processStartTimedOutLocked(app);
1840                }
1841            } break;
1842            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1843                ProcessRecord app = (ProcessRecord)msg.obj;
1844                synchronized (ActivityManagerService.this) {
1845                    processContentProviderPublishTimedOutLocked(app);
1846                }
1847            } break;
1848            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1849                synchronized (ActivityManagerService.this) {
1850                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1851                }
1852            } break;
1853            case KILL_APPLICATION_MSG: {
1854                synchronized (ActivityManagerService.this) {
1855                    final int appId = msg.arg1;
1856                    final int userId = msg.arg2;
1857                    Bundle bundle = (Bundle)msg.obj;
1858                    String pkg = bundle.getString("pkg");
1859                    String reason = bundle.getString("reason");
1860                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1861                            false, userId, reason);
1862                }
1863            } break;
1864            case FINALIZE_PENDING_INTENT_MSG: {
1865                ((PendingIntentRecord)msg.obj).completeFinalize();
1866            } break;
1867            case POST_HEAVY_NOTIFICATION_MSG: {
1868                INotificationManager inm = NotificationManager.getService();
1869                if (inm == null) {
1870                    return;
1871                }
1872
1873                ActivityRecord root = (ActivityRecord)msg.obj;
1874                ProcessRecord process = root.app;
1875                if (process == null) {
1876                    return;
1877                }
1878
1879                try {
1880                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1881                    String text = mContext.getString(R.string.heavy_weight_notification,
1882                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1883                    Notification notification = new Notification.Builder(context)
1884                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1885                            .setWhen(0)
1886                            .setOngoing(true)
1887                            .setTicker(text)
1888                            .setColor(mContext.getColor(
1889                                    com.android.internal.R.color.system_notification_accent_color))
1890                            .setContentTitle(text)
1891                            .setContentText(
1892                                    mContext.getText(R.string.heavy_weight_notification_detail))
1893                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1894                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1895                                    new UserHandle(root.userId)))
1896                            .build();
1897                    try {
1898                        int[] outId = new int[1];
1899                        inm.enqueueNotificationWithTag("android", "android", null,
1900                                R.string.heavy_weight_notification,
1901                                notification, outId, root.userId);
1902                    } catch (RuntimeException e) {
1903                        Slog.w(ActivityManagerService.TAG,
1904                                "Error showing notification for heavy-weight app", e);
1905                    } catch (RemoteException e) {
1906                    }
1907                } catch (NameNotFoundException e) {
1908                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1909                }
1910            } break;
1911            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1912                INotificationManager inm = NotificationManager.getService();
1913                if (inm == null) {
1914                    return;
1915                }
1916                try {
1917                    inm.cancelNotificationWithTag("android", null,
1918                            R.string.heavy_weight_notification,  msg.arg1);
1919                } catch (RuntimeException e) {
1920                    Slog.w(ActivityManagerService.TAG,
1921                            "Error canceling notification for service", e);
1922                } catch (RemoteException e) {
1923                }
1924            } break;
1925            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1926                synchronized (ActivityManagerService.this) {
1927                    checkExcessivePowerUsageLocked(true);
1928                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1929                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1930                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1931                }
1932            } break;
1933            case REPORT_MEM_USAGE_MSG: {
1934                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1935                Thread thread = new Thread() {
1936                    @Override public void run() {
1937                        reportMemUsage(memInfos);
1938                    }
1939                };
1940                thread.start();
1941                break;
1942            }
1943            case REPORT_USER_SWITCH_MSG: {
1944                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1945                break;
1946            }
1947            case CONTINUE_USER_SWITCH_MSG: {
1948                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1949                break;
1950            }
1951            case USER_SWITCH_TIMEOUT_MSG: {
1952                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1953                break;
1954            }
1955            case IMMERSIVE_MODE_LOCK_MSG: {
1956                final boolean nextState = (msg.arg1 != 0);
1957                if (mUpdateLock.isHeld() != nextState) {
1958                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1959                            "Applying new update lock state '" + nextState
1960                            + "' for " + (ActivityRecord)msg.obj);
1961                    if (nextState) {
1962                        mUpdateLock.acquire();
1963                    } else {
1964                        mUpdateLock.release();
1965                    }
1966                }
1967                break;
1968            }
1969            case PERSIST_URI_GRANTS_MSG: {
1970                writeGrantedUriPermissions();
1971                break;
1972            }
1973            case REQUEST_ALL_PSS_MSG: {
1974                synchronized (ActivityManagerService.this) {
1975                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1976                }
1977                break;
1978            }
1979            case START_PROFILES_MSG: {
1980                synchronized (ActivityManagerService.this) {
1981                    mUserController.startProfilesLocked();
1982                }
1983                break;
1984            }
1985            case UPDATE_TIME: {
1986                synchronized (ActivityManagerService.this) {
1987                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1988                        ProcessRecord r = mLruProcesses.get(i);
1989                        if (r.thread != null) {
1990                            try {
1991                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1992                            } catch (RemoteException ex) {
1993                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1994                            }
1995                        }
1996                    }
1997                }
1998                break;
1999            }
2000            case SYSTEM_USER_START_MSG: {
2001                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2002                        Integer.toString(msg.arg1), msg.arg1);
2003                mSystemServiceManager.startUser(msg.arg1);
2004                break;
2005            }
2006            case SYSTEM_USER_UNLOCK_MSG: {
2007                final int userId = msg.arg1;
2008                mSystemServiceManager.unlockUser(userId);
2009                synchronized (ActivityManagerService.this) {
2010                    mRecentTasks.loadUserRecentsLocked(userId);
2011                }
2012                if (userId == UserHandle.USER_SYSTEM) {
2013                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2014                }
2015                installEncryptionUnawareProviders(userId);
2016                mUserController.finishUserUnlocked((UserState) msg.obj);
2017                break;
2018            }
2019            case SYSTEM_USER_CURRENT_MSG: {
2020                mBatteryStatsService.noteEvent(
2021                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2022                        Integer.toString(msg.arg2), msg.arg2);
2023                mBatteryStatsService.noteEvent(
2024                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2025                        Integer.toString(msg.arg1), msg.arg1);
2026                mSystemServiceManager.switchUser(msg.arg1);
2027                break;
2028            }
2029            case ENTER_ANIMATION_COMPLETE_MSG: {
2030                synchronized (ActivityManagerService.this) {
2031                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2032                    if (r != null && r.app != null && r.app.thread != null) {
2033                        try {
2034                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2035                        } catch (RemoteException e) {
2036                        }
2037                    }
2038                }
2039                break;
2040            }
2041            case FINISH_BOOTING_MSG: {
2042                if (msg.arg1 != 0) {
2043                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2044                    finishBooting();
2045                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2046                }
2047                if (msg.arg2 != 0) {
2048                    enableScreenAfterBoot();
2049                }
2050                break;
2051            }
2052            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2053                try {
2054                    Locale l = (Locale) msg.obj;
2055                    IBinder service = ServiceManager.getService("mount");
2056                    IMountService mountService = IMountService.Stub.asInterface(service);
2057                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2058                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2059                } catch (RemoteException e) {
2060                    Log.e(TAG, "Error storing locale for decryption UI", e);
2061                }
2062                break;
2063            }
2064            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2065                synchronized (ActivityManagerService.this) {
2066                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2067                        try {
2068                            // Make a one-way callback to the listener
2069                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2070                        } catch (RemoteException e){
2071                            // Handled by the RemoteCallbackList
2072                        }
2073                    }
2074                    mTaskStackListeners.finishBroadcast();
2075                }
2076                break;
2077            }
2078            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2079                synchronized (ActivityManagerService.this) {
2080                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2081                        try {
2082                            // Make a one-way callback to the listener
2083                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2084                        } catch (RemoteException e){
2085                            // Handled by the RemoteCallbackList
2086                        }
2087                    }
2088                    mTaskStackListeners.finishBroadcast();
2089                }
2090                break;
2091            }
2092            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2093                synchronized (ActivityManagerService.this) {
2094                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2095                        try {
2096                            // Make a one-way callback to the listener
2097                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2098                        } catch (RemoteException e){
2099                            // Handled by the RemoteCallbackList
2100                        }
2101                    }
2102                    mTaskStackListeners.finishBroadcast();
2103                }
2104                break;
2105            }
2106            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2107                synchronized (ActivityManagerService.this) {
2108                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2109                        try {
2110                            // Make a one-way callback to the listener
2111                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2112                        } catch (RemoteException e){
2113                            // Handled by the RemoteCallbackList
2114                        }
2115                    }
2116                    mTaskStackListeners.finishBroadcast();
2117                }
2118                break;
2119            }
2120            case NOTIFY_FORCED_RESIZABLE_MSG: {
2121                synchronized (ActivityManagerService.this) {
2122                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2123                        try {
2124                            // Make a one-way callback to the listener
2125                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2126                                    (String) msg.obj, msg.arg1);
2127                        } catch (RemoteException e){
2128                            // Handled by the RemoteCallbackList
2129                        }
2130                    }
2131                    mTaskStackListeners.finishBroadcast();
2132                }
2133                break;
2134            }
2135                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2136                    synchronized (ActivityManagerService.this) {
2137                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2138                            try {
2139                                // Make a one-way callback to the listener
2140                                mTaskStackListeners.getBroadcastItem(i)
2141                                        .onActivityDismissingDockedStack();
2142                            } catch (RemoteException e){
2143                                // Handled by the RemoteCallbackList
2144                            }
2145                        }
2146                        mTaskStackListeners.finishBroadcast();
2147                    }
2148                    break;
2149                }
2150            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2151                final int uid = msg.arg1;
2152                final byte[] firstPacket = (byte[]) msg.obj;
2153
2154                synchronized (mPidsSelfLocked) {
2155                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2156                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2157                        if (p.uid == uid) {
2158                            try {
2159                                p.thread.notifyCleartextNetwork(firstPacket);
2160                            } catch (RemoteException ignored) {
2161                            }
2162                        }
2163                    }
2164                }
2165                break;
2166            }
2167            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2168                final String procName;
2169                final int uid;
2170                final long memLimit;
2171                final String reportPackage;
2172                synchronized (ActivityManagerService.this) {
2173                    procName = mMemWatchDumpProcName;
2174                    uid = mMemWatchDumpUid;
2175                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2176                    if (val == null) {
2177                        val = mMemWatchProcesses.get(procName, 0);
2178                    }
2179                    if (val != null) {
2180                        memLimit = val.first;
2181                        reportPackage = val.second;
2182                    } else {
2183                        memLimit = 0;
2184                        reportPackage = null;
2185                    }
2186                }
2187                if (procName == null) {
2188                    return;
2189                }
2190
2191                if (DEBUG_PSS) Slog.d(TAG_PSS,
2192                        "Showing dump heap notification from " + procName + "/" + uid);
2193
2194                INotificationManager inm = NotificationManager.getService();
2195                if (inm == null) {
2196                    return;
2197                }
2198
2199                String text = mContext.getString(R.string.dump_heap_notification, procName);
2200
2201
2202                Intent deleteIntent = new Intent();
2203                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2204                Intent intent = new Intent();
2205                intent.setClassName("android", DumpHeapActivity.class.getName());
2206                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2207                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2208                if (reportPackage != null) {
2209                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2210                }
2211                int userId = UserHandle.getUserId(uid);
2212                Notification notification = new Notification.Builder(mContext)
2213                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2214                        .setWhen(0)
2215                        .setOngoing(true)
2216                        .setAutoCancel(true)
2217                        .setTicker(text)
2218                        .setColor(mContext.getColor(
2219                                com.android.internal.R.color.system_notification_accent_color))
2220                        .setContentTitle(text)
2221                        .setContentText(
2222                                mContext.getText(R.string.dump_heap_notification_detail))
2223                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2224                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2225                                new UserHandle(userId)))
2226                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2227                                deleteIntent, 0, UserHandle.SYSTEM))
2228                        .build();
2229
2230                try {
2231                    int[] outId = new int[1];
2232                    inm.enqueueNotificationWithTag("android", "android", null,
2233                            R.string.dump_heap_notification,
2234                            notification, outId, userId);
2235                } catch (RuntimeException e) {
2236                    Slog.w(ActivityManagerService.TAG,
2237                            "Error showing notification for dump heap", e);
2238                } catch (RemoteException e) {
2239                }
2240            } break;
2241            case DELETE_DUMPHEAP_MSG: {
2242                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2243                        DumpHeapActivity.JAVA_URI,
2244                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2245                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2246                        UserHandle.myUserId());
2247                synchronized (ActivityManagerService.this) {
2248                    mMemWatchDumpFile = null;
2249                    mMemWatchDumpProcName = null;
2250                    mMemWatchDumpPid = -1;
2251                    mMemWatchDumpUid = -1;
2252                }
2253            } break;
2254            case FOREGROUND_PROFILE_CHANGED_MSG: {
2255                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2256            } break;
2257            case REPORT_TIME_TRACKER_MSG: {
2258                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2259                tracker.deliverResult(mContext);
2260            } break;
2261            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2262                mUserController.dispatchUserSwitchComplete(msg.arg1);
2263            } break;
2264            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2265                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2266                try {
2267                    connection.shutdown();
2268                } catch (RemoteException e) {
2269                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2270                }
2271                // Only a UiAutomation can set this flag and now that
2272                // it is finished we make sure it is reset to its default.
2273                mUserIsMonkey = false;
2274            } break;
2275            case APP_BOOST_DEACTIVATE_MSG: {
2276                synchronized(ActivityManagerService.this) {
2277                    if (mIsBoosted) {
2278                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2279                            nativeMigrateFromBoost();
2280                            mIsBoosted = false;
2281                            mBoostStartTime = 0;
2282                        } else {
2283                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2284                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2285                        }
2286                    }
2287                }
2288            } break;
2289            case IDLE_UIDS_MSG: {
2290                idleUids();
2291            } break;
2292            case LOG_STACK_STATE: {
2293                synchronized (ActivityManagerService.this) {
2294                    mStackSupervisor.logStackState();
2295                }
2296            } break;
2297            case VR_MODE_CHANGE_MSG: {
2298                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2299                final ActivityRecord r = (ActivityRecord) msg.obj;
2300                boolean vrMode;
2301                ComponentName requestedPackage;
2302                ComponentName callingPackage;
2303                int userId;
2304                synchronized (ActivityManagerService.this) {
2305                    vrMode = r.requestedVrComponent != null;
2306                    requestedPackage = r.requestedVrComponent;
2307                    userId = r.userId;
2308                    callingPackage = r.info.getComponentName();
2309                    if (mInVrMode != vrMode) {
2310                        mInVrMode = vrMode;
2311                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2312                    }
2313                }
2314                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2315            } break;
2316            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2317                final ActivityRecord r = (ActivityRecord) msg.obj;
2318                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2319                if (needsVrMode) {
2320                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2321                            r.info.getComponentName(), false);
2322                }
2323            } break;
2324            }
2325        }
2326    };
2327
2328    static final int COLLECT_PSS_BG_MSG = 1;
2329
2330    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2331        @Override
2332        public void handleMessage(Message msg) {
2333            switch (msg.what) {
2334            case COLLECT_PSS_BG_MSG: {
2335                long start = SystemClock.uptimeMillis();
2336                MemInfoReader memInfo = null;
2337                synchronized (ActivityManagerService.this) {
2338                    if (mFullPssPending) {
2339                        mFullPssPending = false;
2340                        memInfo = new MemInfoReader();
2341                    }
2342                }
2343                if (memInfo != null) {
2344                    updateCpuStatsNow();
2345                    long nativeTotalPss = 0;
2346                    synchronized (mProcessCpuTracker) {
2347                        final int N = mProcessCpuTracker.countStats();
2348                        for (int j=0; j<N; j++) {
2349                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2350                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2351                                // This is definitely an application process; skip it.
2352                                continue;
2353                            }
2354                            synchronized (mPidsSelfLocked) {
2355                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2356                                    // This is one of our own processes; skip it.
2357                                    continue;
2358                                }
2359                            }
2360                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2361                        }
2362                    }
2363                    memInfo.readMemInfo();
2364                    synchronized (ActivityManagerService.this) {
2365                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2366                                + (SystemClock.uptimeMillis()-start) + "ms");
2367                        final long cachedKb = memInfo.getCachedSizeKb();
2368                        final long freeKb = memInfo.getFreeSizeKb();
2369                        final long zramKb = memInfo.getZramTotalSizeKb();
2370                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2371                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2372                                kernelKb*1024, nativeTotalPss*1024);
2373                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2374                                nativeTotalPss);
2375                    }
2376                }
2377
2378                int num = 0;
2379                long[] tmp = new long[2];
2380                do {
2381                    ProcessRecord proc;
2382                    int procState;
2383                    int pid;
2384                    long lastPssTime;
2385                    synchronized (ActivityManagerService.this) {
2386                        if (mPendingPssProcesses.size() <= 0) {
2387                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2388                                    "Collected PSS of " + num + " processes in "
2389                                    + (SystemClock.uptimeMillis() - start) + "ms");
2390                            mPendingPssProcesses.clear();
2391                            return;
2392                        }
2393                        proc = mPendingPssProcesses.remove(0);
2394                        procState = proc.pssProcState;
2395                        lastPssTime = proc.lastPssTime;
2396                        if (proc.thread != null && procState == proc.setProcState
2397                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2398                                        < SystemClock.uptimeMillis()) {
2399                            pid = proc.pid;
2400                        } else {
2401                            proc = null;
2402                            pid = 0;
2403                        }
2404                    }
2405                    if (proc != null) {
2406                        long pss = Debug.getPss(pid, tmp, null);
2407                        synchronized (ActivityManagerService.this) {
2408                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2409                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2410                                num++;
2411                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2412                                        SystemClock.uptimeMillis());
2413                            }
2414                        }
2415                    }
2416                } while (true);
2417            }
2418            }
2419        }
2420    };
2421
2422    public void setSystemProcess() {
2423        try {
2424            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2425            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2426            ServiceManager.addService("meminfo", new MemBinder(this));
2427            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2428            ServiceManager.addService("dbinfo", new DbBinder(this));
2429            if (MONITOR_CPU_USAGE) {
2430                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2431            }
2432            ServiceManager.addService("permission", new PermissionController(this));
2433            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2434
2435            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2436                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2437            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2438
2439            synchronized (this) {
2440                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2441                app.persistent = true;
2442                app.pid = MY_PID;
2443                app.maxAdj = ProcessList.SYSTEM_ADJ;
2444                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2445                synchronized (mPidsSelfLocked) {
2446                    mPidsSelfLocked.put(app.pid, app);
2447                }
2448                updateLruProcessLocked(app, false, null);
2449                updateOomAdjLocked();
2450            }
2451        } catch (PackageManager.NameNotFoundException e) {
2452            throw new RuntimeException(
2453                    "Unable to find android system package", e);
2454        }
2455    }
2456
2457    public void setWindowManager(WindowManagerService wm) {
2458        mWindowManager = wm;
2459        mStackSupervisor.setWindowManager(wm);
2460        mActivityStarter.setWindowManager(wm);
2461    }
2462
2463    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2464        mUsageStatsService = usageStatsManager;
2465    }
2466
2467    public void startObservingNativeCrashes() {
2468        final NativeCrashListener ncl = new NativeCrashListener(this);
2469        ncl.start();
2470    }
2471
2472    public IAppOpsService getAppOpsService() {
2473        return mAppOpsService;
2474    }
2475
2476    static class MemBinder extends Binder {
2477        ActivityManagerService mActivityManagerService;
2478        MemBinder(ActivityManagerService activityManagerService) {
2479            mActivityManagerService = activityManagerService;
2480        }
2481
2482        @Override
2483        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2484            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2485                    != PackageManager.PERMISSION_GRANTED) {
2486                pw.println("Permission Denial: can't dump meminfo from from pid="
2487                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2488                        + " without permission " + android.Manifest.permission.DUMP);
2489                return;
2490            }
2491
2492            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2493        }
2494    }
2495
2496    static class GraphicsBinder extends Binder {
2497        ActivityManagerService mActivityManagerService;
2498        GraphicsBinder(ActivityManagerService activityManagerService) {
2499            mActivityManagerService = activityManagerService;
2500        }
2501
2502        @Override
2503        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2504            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2505                    != PackageManager.PERMISSION_GRANTED) {
2506                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2507                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2508                        + " without permission " + android.Manifest.permission.DUMP);
2509                return;
2510            }
2511
2512            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2513        }
2514    }
2515
2516    static class DbBinder extends Binder {
2517        ActivityManagerService mActivityManagerService;
2518        DbBinder(ActivityManagerService activityManagerService) {
2519            mActivityManagerService = activityManagerService;
2520        }
2521
2522        @Override
2523        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2524            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2525                    != PackageManager.PERMISSION_GRANTED) {
2526                pw.println("Permission Denial: can't dump dbinfo from from pid="
2527                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2528                        + " without permission " + android.Manifest.permission.DUMP);
2529                return;
2530            }
2531
2532            mActivityManagerService.dumpDbInfo(fd, pw, args);
2533        }
2534    }
2535
2536    static class CpuBinder extends Binder {
2537        ActivityManagerService mActivityManagerService;
2538        CpuBinder(ActivityManagerService activityManagerService) {
2539            mActivityManagerService = activityManagerService;
2540        }
2541
2542        @Override
2543        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2544            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2545                    != PackageManager.PERMISSION_GRANTED) {
2546                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2547                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2548                        + " without permission " + android.Manifest.permission.DUMP);
2549                return;
2550            }
2551
2552            synchronized (mActivityManagerService.mProcessCpuTracker) {
2553                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2554                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2555                        SystemClock.uptimeMillis()));
2556            }
2557        }
2558    }
2559
2560    public static final class Lifecycle extends SystemService {
2561        private final ActivityManagerService mService;
2562
2563        public Lifecycle(Context context) {
2564            super(context);
2565            mService = new ActivityManagerService(context);
2566        }
2567
2568        @Override
2569        public void onStart() {
2570            mService.start();
2571        }
2572
2573        public ActivityManagerService getService() {
2574            return mService;
2575        }
2576    }
2577
2578    // Note: This method is invoked on the main thread but may need to attach various
2579    // handlers to other threads.  So take care to be explicit about the looper.
2580    public ActivityManagerService(Context systemContext) {
2581        mContext = systemContext;
2582        mFactoryTest = FactoryTest.getMode();
2583        mSystemThread = ActivityThread.currentActivityThread();
2584
2585        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2586
2587        mHandlerThread = new ServiceThread(TAG,
2588                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2589        mHandlerThread.start();
2590        mHandler = new MainHandler(mHandlerThread.getLooper());
2591        mUiHandler = new UiHandler();
2592
2593        /* static; one-time init here */
2594        if (sKillHandler == null) {
2595            sKillThread = new ServiceThread(TAG + ":kill",
2596                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2597            sKillThread.start();
2598            sKillHandler = new KillHandler(sKillThread.getLooper());
2599        }
2600
2601        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2602                "foreground", BROADCAST_FG_TIMEOUT, false);
2603        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2604                "background", BROADCAST_BG_TIMEOUT, true);
2605        mBroadcastQueues[0] = mFgBroadcastQueue;
2606        mBroadcastQueues[1] = mBgBroadcastQueue;
2607
2608        mServices = new ActiveServices(this);
2609        mProviderMap = new ProviderMap(this);
2610        mAppErrors = new AppErrors(mContext, this);
2611
2612        // TODO: Move creation of battery stats service outside of activity manager service.
2613        File dataDir = Environment.getDataDirectory();
2614        File systemDir = new File(dataDir, "system");
2615        systemDir.mkdirs();
2616        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2617        mBatteryStatsService.getActiveStatistics().readLocked();
2618        mBatteryStatsService.scheduleWriteToDisk();
2619        mOnBattery = DEBUG_POWER ? true
2620                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2621        mBatteryStatsService.getActiveStatistics().setCallback(this);
2622
2623        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2624
2625        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2626        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2627                new IAppOpsCallback.Stub() {
2628                    @Override public void opChanged(int op, int uid, String packageName) {
2629                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2630                            if (mAppOpsService.checkOperation(op, uid, packageName)
2631                                    != AppOpsManager.MODE_ALLOWED) {
2632                                runInBackgroundDisabled(uid);
2633                            }
2634                        }
2635                    }
2636                });
2637
2638        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2639
2640        mUserController = new UserController(this);
2641
2642        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2643            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2644
2645        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2646
2647        mConfiguration.setToDefaults();
2648        mConfiguration.setLocales(LocaleList.getDefault());
2649
2650        mConfigurationSeq = mConfiguration.seq = 1;
2651        mProcessCpuTracker.init();
2652
2653        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2654        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2655        mStackSupervisor = new ActivityStackSupervisor(this);
2656        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2657        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2658
2659        mProcessCpuThread = new Thread("CpuTracker") {
2660            @Override
2661            public void run() {
2662                while (true) {
2663                    try {
2664                        try {
2665                            synchronized(this) {
2666                                final long now = SystemClock.uptimeMillis();
2667                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2668                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2669                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2670                                //        + ", write delay=" + nextWriteDelay);
2671                                if (nextWriteDelay < nextCpuDelay) {
2672                                    nextCpuDelay = nextWriteDelay;
2673                                }
2674                                if (nextCpuDelay > 0) {
2675                                    mProcessCpuMutexFree.set(true);
2676                                    this.wait(nextCpuDelay);
2677                                }
2678                            }
2679                        } catch (InterruptedException e) {
2680                        }
2681                        updateCpuStatsNow();
2682                    } catch (Exception e) {
2683                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2684                    }
2685                }
2686            }
2687        };
2688
2689        Watchdog.getInstance().addMonitor(this);
2690        Watchdog.getInstance().addThread(mHandler);
2691    }
2692
2693    public void setSystemServiceManager(SystemServiceManager mgr) {
2694        mSystemServiceManager = mgr;
2695    }
2696
2697    public void setInstaller(Installer installer) {
2698        mInstaller = installer;
2699    }
2700
2701    private void start() {
2702        Process.removeAllProcessGroups();
2703        mProcessCpuThread.start();
2704
2705        mBatteryStatsService.publish(mContext);
2706        mAppOpsService.publish(mContext);
2707        Slog.d("AppOps", "AppOpsService published");
2708        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2709    }
2710
2711    void onUserStoppedLocked(int userId) {
2712        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2713    }
2714
2715    public void initPowerManagement() {
2716        mStackSupervisor.initPowerManagement();
2717        mBatteryStatsService.initPowerManagement();
2718        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2719        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2720        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2721        mVoiceWakeLock.setReferenceCounted(false);
2722    }
2723
2724    @Override
2725    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2726            throws RemoteException {
2727        if (code == SYSPROPS_TRANSACTION) {
2728            // We need to tell all apps about the system property change.
2729            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2730            synchronized(this) {
2731                final int NP = mProcessNames.getMap().size();
2732                for (int ip=0; ip<NP; ip++) {
2733                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2734                    final int NA = apps.size();
2735                    for (int ia=0; ia<NA; ia++) {
2736                        ProcessRecord app = apps.valueAt(ia);
2737                        if (app.thread != null) {
2738                            procs.add(app.thread.asBinder());
2739                        }
2740                    }
2741                }
2742            }
2743
2744            int N = procs.size();
2745            for (int i=0; i<N; i++) {
2746                Parcel data2 = Parcel.obtain();
2747                try {
2748                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2749                } catch (RemoteException e) {
2750                }
2751                data2.recycle();
2752            }
2753        }
2754        try {
2755            return super.onTransact(code, data, reply, flags);
2756        } catch (RuntimeException e) {
2757            // The activity manager only throws security exceptions, so let's
2758            // log all others.
2759            if (!(e instanceof SecurityException)) {
2760                Slog.wtf(TAG, "Activity Manager Crash", e);
2761            }
2762            throw e;
2763        }
2764    }
2765
2766    void updateCpuStats() {
2767        final long now = SystemClock.uptimeMillis();
2768        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2769            return;
2770        }
2771        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2772            synchronized (mProcessCpuThread) {
2773                mProcessCpuThread.notify();
2774            }
2775        }
2776    }
2777
2778    void updateCpuStatsNow() {
2779        synchronized (mProcessCpuTracker) {
2780            mProcessCpuMutexFree.set(false);
2781            final long now = SystemClock.uptimeMillis();
2782            boolean haveNewCpuStats = false;
2783
2784            if (MONITOR_CPU_USAGE &&
2785                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2786                mLastCpuTime.set(now);
2787                mProcessCpuTracker.update();
2788                if (mProcessCpuTracker.hasGoodLastStats()) {
2789                    haveNewCpuStats = true;
2790                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2791                    //Slog.i(TAG, "Total CPU usage: "
2792                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2793
2794                    // Slog the cpu usage if the property is set.
2795                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2796                        int user = mProcessCpuTracker.getLastUserTime();
2797                        int system = mProcessCpuTracker.getLastSystemTime();
2798                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2799                        int irq = mProcessCpuTracker.getLastIrqTime();
2800                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2801                        int idle = mProcessCpuTracker.getLastIdleTime();
2802
2803                        int total = user + system + iowait + irq + softIrq + idle;
2804                        if (total == 0) total = 1;
2805
2806                        EventLog.writeEvent(EventLogTags.CPU,
2807                                ((user+system+iowait+irq+softIrq) * 100) / total,
2808                                (user * 100) / total,
2809                                (system * 100) / total,
2810                                (iowait * 100) / total,
2811                                (irq * 100) / total,
2812                                (softIrq * 100) / total);
2813                    }
2814                }
2815            }
2816
2817            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2818            synchronized(bstats) {
2819                synchronized(mPidsSelfLocked) {
2820                    if (haveNewCpuStats) {
2821                        if (bstats.startAddingCpuLocked()) {
2822                            int totalUTime = 0;
2823                            int totalSTime = 0;
2824                            final int N = mProcessCpuTracker.countStats();
2825                            for (int i=0; i<N; i++) {
2826                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2827                                if (!st.working) {
2828                                    continue;
2829                                }
2830                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2831                                totalUTime += st.rel_utime;
2832                                totalSTime += st.rel_stime;
2833                                if (pr != null) {
2834                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2835                                    if (ps == null || !ps.isActive()) {
2836                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2837                                                pr.info.uid, pr.processName);
2838                                    }
2839                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2840                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2841                                } else {
2842                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2843                                    if (ps == null || !ps.isActive()) {
2844                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2845                                                bstats.mapUid(st.uid), st.name);
2846                                    }
2847                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2848                                }
2849                            }
2850                            final int userTime = mProcessCpuTracker.getLastUserTime();
2851                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2852                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2853                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2854                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2855                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2856                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2857                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2858                        }
2859                    }
2860                }
2861
2862                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2863                    mLastWriteTime = now;
2864                    mBatteryStatsService.scheduleWriteToDisk();
2865                }
2866            }
2867        }
2868    }
2869
2870    @Override
2871    public void batteryNeedsCpuUpdate() {
2872        updateCpuStatsNow();
2873    }
2874
2875    @Override
2876    public void batteryPowerChanged(boolean onBattery) {
2877        // When plugging in, update the CPU stats first before changing
2878        // the plug state.
2879        updateCpuStatsNow();
2880        synchronized (this) {
2881            synchronized(mPidsSelfLocked) {
2882                mOnBattery = DEBUG_POWER ? true : onBattery;
2883            }
2884        }
2885    }
2886
2887    @Override
2888    public void batterySendBroadcast(Intent intent) {
2889        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2890                AppOpsManager.OP_NONE, null, false, false,
2891                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2892    }
2893
2894    /**
2895     * Initialize the application bind args. These are passed to each
2896     * process when the bindApplication() IPC is sent to the process. They're
2897     * lazily setup to make sure the services are running when they're asked for.
2898     */
2899    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2900        if (mAppBindArgs == null) {
2901            mAppBindArgs = new HashMap<>();
2902
2903            // Isolated processes won't get this optimization, so that we don't
2904            // violate the rules about which services they have access to.
2905            if (!isolated) {
2906                // Setup the application init args
2907                mAppBindArgs.put("package", ServiceManager.getService("package"));
2908                mAppBindArgs.put("window", ServiceManager.getService("window"));
2909                mAppBindArgs.put(Context.ALARM_SERVICE,
2910                        ServiceManager.getService(Context.ALARM_SERVICE));
2911            }
2912        }
2913        return mAppBindArgs;
2914    }
2915
2916    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2917        if (r == null || mFocusedActivity == r) {
2918            return false;
2919        }
2920
2921        if (!r.isFocusable()) {
2922            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2923            return false;
2924        }
2925
2926        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2927
2928        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2929        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2930                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2931        mDoingSetFocusedActivity = true;
2932
2933        final ActivityRecord last = mFocusedActivity;
2934        mFocusedActivity = r;
2935        if (r.task.isApplicationTask()) {
2936            if (mCurAppTimeTracker != r.appTimeTracker) {
2937                // We are switching app tracking.  Complete the current one.
2938                if (mCurAppTimeTracker != null) {
2939                    mCurAppTimeTracker.stop();
2940                    mHandler.obtainMessage(
2941                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2942                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2943                    mCurAppTimeTracker = null;
2944                }
2945                if (r.appTimeTracker != null) {
2946                    mCurAppTimeTracker = r.appTimeTracker;
2947                    startTimeTrackingFocusedActivityLocked();
2948                }
2949            } else {
2950                startTimeTrackingFocusedActivityLocked();
2951            }
2952        } else {
2953            r.appTimeTracker = null;
2954        }
2955        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2956        // TODO: Probably not, because we don't want to resume voice on switching
2957        // back to this activity
2958        if (r.task.voiceInteractor != null) {
2959            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2960        } else {
2961            finishRunningVoiceLocked();
2962            IVoiceInteractionSession session;
2963            if (last != null && ((session = last.task.voiceSession) != null
2964                    || (session = last.voiceSession) != null)) {
2965                // We had been in a voice interaction session, but now focused has
2966                // move to something different.  Just finish the session, we can't
2967                // return to it and retain the proper state and synchronization with
2968                // the voice interaction service.
2969                finishVoiceTask(session);
2970            }
2971        }
2972        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2973            mWindowManager.setFocusedApp(r.appToken, true);
2974        }
2975        applyUpdateLockStateLocked(r);
2976        applyUpdateVrModeLocked(r);
2977        if (mFocusedActivity.userId != mLastFocusedUserId) {
2978            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2979            mHandler.obtainMessage(
2980                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2981            mLastFocusedUserId = mFocusedActivity.userId;
2982        }
2983
2984        // Log a warning if the focused app is changed during the process. This could
2985        // indicate a problem of the focus setting logic!
2986        if (mFocusedActivity != r) Slog.w(TAG,
2987                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2988        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2989
2990        EventLogTags.writeAmFocusedActivity(
2991                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2992                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2993                reason);
2994        return true;
2995    }
2996
2997    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2998        if (mFocusedActivity != goingAway) {
2999            return;
3000        }
3001
3002        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3003        if (focusedStack != null) {
3004            final ActivityRecord top = focusedStack.topActivity();
3005            if (top != null && top.userId != mLastFocusedUserId) {
3006                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3007                mHandler.sendMessage(
3008                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3009                mLastFocusedUserId = top.userId;
3010            }
3011        }
3012
3013        // Try to move focus to another activity if possible.
3014        if (setFocusedActivityLocked(
3015                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3016            return;
3017        }
3018
3019        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3020                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3021        mFocusedActivity = null;
3022        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3023    }
3024
3025    @Override
3026    public void setFocusedStack(int stackId) {
3027        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3028        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3029        final long callingId = Binder.clearCallingIdentity();
3030        try {
3031            synchronized (this) {
3032                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3033                if (stack == null) {
3034                    return;
3035                }
3036                final ActivityRecord r = stack.topRunningActivityLocked();
3037                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3038                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3039                }
3040            }
3041        } finally {
3042            Binder.restoreCallingIdentity(callingId);
3043        }
3044    }
3045
3046    @Override
3047    public void setFocusedTask(int taskId) {
3048        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3049        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3050        final long callingId = Binder.clearCallingIdentity();
3051        try {
3052            synchronized (this) {
3053                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3054                if (task == null) {
3055                    return;
3056                }
3057                final ActivityRecord r = task.topRunningActivityLocked();
3058                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3059                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3060                }
3061            }
3062        } finally {
3063            Binder.restoreCallingIdentity(callingId);
3064        }
3065    }
3066
3067    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3068    @Override
3069    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3070        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3071        synchronized (this) {
3072            if (listener != null) {
3073                mTaskStackListeners.register(listener);
3074            }
3075        }
3076    }
3077
3078    @Override
3079    public void notifyActivityDrawn(IBinder token) {
3080        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3081        synchronized (this) {
3082            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3083            if (r != null) {
3084                r.task.stack.notifyActivityDrawnLocked(r);
3085            }
3086        }
3087    }
3088
3089    final void applyUpdateLockStateLocked(ActivityRecord r) {
3090        // Modifications to the UpdateLock state are done on our handler, outside
3091        // the activity manager's locks.  The new state is determined based on the
3092        // state *now* of the relevant activity record.  The object is passed to
3093        // the handler solely for logging detail, not to be consulted/modified.
3094        final boolean nextState = r != null && r.immersive;
3095        mHandler.sendMessage(
3096                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3097    }
3098
3099    final void applyUpdateVrModeLocked(ActivityRecord r) {
3100        mHandler.sendMessage(
3101                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3102    }
3103
3104    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3105        mHandler.sendMessage(
3106                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3107    }
3108
3109    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3110            ComponentName callingPackage, boolean immediate) {
3111        VrManagerInternal vrService =
3112                LocalServices.getService(VrManagerInternal.class);
3113        if (immediate) {
3114            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3115        } else {
3116            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3117        }
3118    }
3119
3120    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3121        Message msg = Message.obtain();
3122        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3123        msg.obj = r.task.askedCompatMode ? null : r;
3124        mUiHandler.sendMessage(msg);
3125    }
3126
3127    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3128        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3129                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3130            final Message msg = Message.obtain();
3131            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3132            msg.obj = r;
3133            mUiHandler.sendMessage(msg);
3134        }
3135    }
3136
3137    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3138            String what, Object obj, ProcessRecord srcApp) {
3139        app.lastActivityTime = now;
3140
3141        if (app.activities.size() > 0) {
3142            // Don't want to touch dependent processes that are hosting activities.
3143            return index;
3144        }
3145
3146        int lrui = mLruProcesses.lastIndexOf(app);
3147        if (lrui < 0) {
3148            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3149                    + what + " " + obj + " from " + srcApp);
3150            return index;
3151        }
3152
3153        if (lrui >= index) {
3154            // Don't want to cause this to move dependent processes *back* in the
3155            // list as if they were less frequently used.
3156            return index;
3157        }
3158
3159        if (lrui >= mLruProcessActivityStart) {
3160            // Don't want to touch dependent processes that are hosting activities.
3161            return index;
3162        }
3163
3164        mLruProcesses.remove(lrui);
3165        if (index > 0) {
3166            index--;
3167        }
3168        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3169                + " in LRU list: " + app);
3170        mLruProcesses.add(index, app);
3171        return index;
3172    }
3173
3174    static void killProcessGroup(int uid, int pid) {
3175        if (sKillHandler != null) {
3176            sKillHandler.sendMessage(
3177                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3178        } else {
3179            Slog.w(TAG, "Asked to kill process group before system bringup!");
3180            Process.killProcessGroup(uid, pid);
3181        }
3182    }
3183
3184    final void removeLruProcessLocked(ProcessRecord app) {
3185        int lrui = mLruProcesses.lastIndexOf(app);
3186        if (lrui >= 0) {
3187            if (!app.killed) {
3188                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3189                Process.killProcessQuiet(app.pid);
3190                killProcessGroup(app.uid, app.pid);
3191            }
3192            if (lrui <= mLruProcessActivityStart) {
3193                mLruProcessActivityStart--;
3194            }
3195            if (lrui <= mLruProcessServiceStart) {
3196                mLruProcessServiceStart--;
3197            }
3198            mLruProcesses.remove(lrui);
3199        }
3200    }
3201
3202    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3203            ProcessRecord client) {
3204        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3205                || app.treatLikeActivity;
3206        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3207        if (!activityChange && hasActivity) {
3208            // The process has activities, so we are only allowing activity-based adjustments
3209            // to move it.  It should be kept in the front of the list with other
3210            // processes that have activities, and we don't want those to change their
3211            // order except due to activity operations.
3212            return;
3213        }
3214
3215        mLruSeq++;
3216        final long now = SystemClock.uptimeMillis();
3217        app.lastActivityTime = now;
3218
3219        // First a quick reject: if the app is already at the position we will
3220        // put it, then there is nothing to do.
3221        if (hasActivity) {
3222            final int N = mLruProcesses.size();
3223            if (N > 0 && mLruProcesses.get(N-1) == app) {
3224                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3225                return;
3226            }
3227        } else {
3228            if (mLruProcessServiceStart > 0
3229                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3230                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3231                return;
3232            }
3233        }
3234
3235        int lrui = mLruProcesses.lastIndexOf(app);
3236
3237        if (app.persistent && lrui >= 0) {
3238            // We don't care about the position of persistent processes, as long as
3239            // they are in the list.
3240            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3241            return;
3242        }
3243
3244        /* In progress: compute new position first, so we can avoid doing work
3245           if the process is not actually going to move.  Not yet working.
3246        int addIndex;
3247        int nextIndex;
3248        boolean inActivity = false, inService = false;
3249        if (hasActivity) {
3250            // Process has activities, put it at the very tipsy-top.
3251            addIndex = mLruProcesses.size();
3252            nextIndex = mLruProcessServiceStart;
3253            inActivity = true;
3254        } else if (hasService) {
3255            // Process has services, put it at the top of the service list.
3256            addIndex = mLruProcessActivityStart;
3257            nextIndex = mLruProcessServiceStart;
3258            inActivity = true;
3259            inService = true;
3260        } else  {
3261            // Process not otherwise of interest, it goes to the top of the non-service area.
3262            addIndex = mLruProcessServiceStart;
3263            if (client != null) {
3264                int clientIndex = mLruProcesses.lastIndexOf(client);
3265                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3266                        + app);
3267                if (clientIndex >= 0 && addIndex > clientIndex) {
3268                    addIndex = clientIndex;
3269                }
3270            }
3271            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3272        }
3273
3274        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3275                + mLruProcessActivityStart + "): " + app);
3276        */
3277
3278        if (lrui >= 0) {
3279            if (lrui < mLruProcessActivityStart) {
3280                mLruProcessActivityStart--;
3281            }
3282            if (lrui < mLruProcessServiceStart) {
3283                mLruProcessServiceStart--;
3284            }
3285            /*
3286            if (addIndex > lrui) {
3287                addIndex--;
3288            }
3289            if (nextIndex > lrui) {
3290                nextIndex--;
3291            }
3292            */
3293            mLruProcesses.remove(lrui);
3294        }
3295
3296        /*
3297        mLruProcesses.add(addIndex, app);
3298        if (inActivity) {
3299            mLruProcessActivityStart++;
3300        }
3301        if (inService) {
3302            mLruProcessActivityStart++;
3303        }
3304        */
3305
3306        int nextIndex;
3307        if (hasActivity) {
3308            final int N = mLruProcesses.size();
3309            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3310                // Process doesn't have activities, but has clients with
3311                // activities...  move it up, but one below the top (the top
3312                // should always have a real activity).
3313                if (DEBUG_LRU) Slog.d(TAG_LRU,
3314                        "Adding to second-top of LRU activity list: " + app);
3315                mLruProcesses.add(N - 1, app);
3316                // To keep it from spamming the LRU list (by making a bunch of clients),
3317                // we will push down any other entries owned by the app.
3318                final int uid = app.info.uid;
3319                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3320                    ProcessRecord subProc = mLruProcesses.get(i);
3321                    if (subProc.info.uid == uid) {
3322                        // We want to push this one down the list.  If the process after
3323                        // it is for the same uid, however, don't do so, because we don't
3324                        // want them internally to be re-ordered.
3325                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3326                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3327                                    "Pushing uid " + uid + " swapping at " + i + ": "
3328                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3329                            ProcessRecord tmp = mLruProcesses.get(i);
3330                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3331                            mLruProcesses.set(i - 1, tmp);
3332                            i--;
3333                        }
3334                    } else {
3335                        // A gap, we can stop here.
3336                        break;
3337                    }
3338                }
3339            } else {
3340                // Process has activities, put it at the very tipsy-top.
3341                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3342                mLruProcesses.add(app);
3343            }
3344            nextIndex = mLruProcessServiceStart;
3345        } else if (hasService) {
3346            // Process has services, put it at the top of the service list.
3347            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3348            mLruProcesses.add(mLruProcessActivityStart, app);
3349            nextIndex = mLruProcessServiceStart;
3350            mLruProcessActivityStart++;
3351        } else  {
3352            // Process not otherwise of interest, it goes to the top of the non-service area.
3353            int index = mLruProcessServiceStart;
3354            if (client != null) {
3355                // If there is a client, don't allow the process to be moved up higher
3356                // in the list than that client.
3357                int clientIndex = mLruProcesses.lastIndexOf(client);
3358                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3359                        + " when updating " + app);
3360                if (clientIndex <= lrui) {
3361                    // Don't allow the client index restriction to push it down farther in the
3362                    // list than it already is.
3363                    clientIndex = lrui;
3364                }
3365                if (clientIndex >= 0 && index > clientIndex) {
3366                    index = clientIndex;
3367                }
3368            }
3369            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3370            mLruProcesses.add(index, app);
3371            nextIndex = index-1;
3372            mLruProcessActivityStart++;
3373            mLruProcessServiceStart++;
3374        }
3375
3376        // If the app is currently using a content provider or service,
3377        // bump those processes as well.
3378        for (int j=app.connections.size()-1; j>=0; j--) {
3379            ConnectionRecord cr = app.connections.valueAt(j);
3380            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3381                    && cr.binding.service.app != null
3382                    && cr.binding.service.app.lruSeq != mLruSeq
3383                    && !cr.binding.service.app.persistent) {
3384                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3385                        "service connection", cr, app);
3386            }
3387        }
3388        for (int j=app.conProviders.size()-1; j>=0; j--) {
3389            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3390            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3391                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3392                        "provider reference", cpr, app);
3393            }
3394        }
3395    }
3396
3397    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3398        if (uid == Process.SYSTEM_UID) {
3399            // The system gets to run in any process.  If there are multiple
3400            // processes with the same uid, just pick the first (this
3401            // should never happen).
3402            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3403            if (procs == null) return null;
3404            final int procCount = procs.size();
3405            for (int i = 0; i < procCount; i++) {
3406                final int procUid = procs.keyAt(i);
3407                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3408                    // Don't use an app process or different user process for system component.
3409                    continue;
3410                }
3411                return procs.valueAt(i);
3412            }
3413        }
3414        ProcessRecord proc = mProcessNames.get(processName, uid);
3415        if (false && proc != null && !keepIfLarge
3416                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3417                && proc.lastCachedPss >= 4000) {
3418            // Turn this condition on to cause killing to happen regularly, for testing.
3419            if (proc.baseProcessTracker != null) {
3420                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3421            }
3422            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3423        } else if (proc != null && !keepIfLarge
3424                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3425                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3426            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3427            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3428                if (proc.baseProcessTracker != null) {
3429                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3430                }
3431                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3432            }
3433        }
3434        return proc;
3435    }
3436
3437    void notifyPackageUse(String packageName, int reason) {
3438        IPackageManager pm = AppGlobals.getPackageManager();
3439        try {
3440            pm.notifyPackageUse(packageName, reason);
3441        } catch (RemoteException e) {
3442        }
3443    }
3444
3445    boolean isNextTransitionForward() {
3446        int transit = mWindowManager.getPendingAppTransition();
3447        return transit == TRANSIT_ACTIVITY_OPEN
3448                || transit == TRANSIT_TASK_OPEN
3449                || transit == TRANSIT_TASK_TO_FRONT;
3450    }
3451
3452    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3453            String processName, String abiOverride, int uid, Runnable crashHandler) {
3454        synchronized(this) {
3455            ApplicationInfo info = new ApplicationInfo();
3456            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3457            // For isolated processes, the former contains the parent's uid and the latter the
3458            // actual uid of the isolated process.
3459            // In the special case introduced by this method (which is, starting an isolated
3460            // process directly from the SystemServer without an actual parent app process) the
3461            // closest thing to a parent's uid is SYSTEM_UID.
3462            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3463            // the |isolated| logic in the ProcessRecord constructor.
3464            info.uid = Process.SYSTEM_UID;
3465            info.processName = processName;
3466            info.className = entryPoint;
3467            info.packageName = "android";
3468            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3469                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3470                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3471                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3472                    crashHandler);
3473            return proc != null ? proc.pid : 0;
3474        }
3475    }
3476
3477    final ProcessRecord startProcessLocked(String processName,
3478            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3479            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3480            boolean isolated, boolean keepIfLarge) {
3481        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3482                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3483                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3484                null /* crashHandler */);
3485    }
3486
3487    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3488            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3489            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3490            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3491        long startTime = SystemClock.elapsedRealtime();
3492        ProcessRecord app;
3493        if (!isolated) {
3494            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3495            checkTime(startTime, "startProcess: after getProcessRecord");
3496
3497            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3498                // If we are in the background, then check to see if this process
3499                // is bad.  If so, we will just silently fail.
3500                if (mAppErrors.isBadProcessLocked(info)) {
3501                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3502                            + "/" + info.processName);
3503                    return null;
3504                }
3505            } else {
3506                // When the user is explicitly starting a process, then clear its
3507                // crash count so that we won't make it bad until they see at
3508                // least one crash dialog again, and make the process good again
3509                // if it had been bad.
3510                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3511                        + "/" + info.processName);
3512                mAppErrors.resetProcessCrashTimeLocked(info);
3513                if (mAppErrors.isBadProcessLocked(info)) {
3514                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3515                            UserHandle.getUserId(info.uid), info.uid,
3516                            info.processName);
3517                    mAppErrors.clearBadProcessLocked(info);
3518                    if (app != null) {
3519                        app.bad = false;
3520                    }
3521                }
3522            }
3523        } else {
3524            // If this is an isolated process, it can't re-use an existing process.
3525            app = null;
3526        }
3527
3528        // app launch boost for big.little configurations
3529        // use cpusets to migrate freshly launched tasks to big cores
3530        nativeMigrateToBoost();
3531        mIsBoosted = true;
3532        mBoostStartTime = SystemClock.uptimeMillis();
3533        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3534        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3535
3536        // We don't have to do anything more if:
3537        // (1) There is an existing application record; and
3538        // (2) The caller doesn't think it is dead, OR there is no thread
3539        //     object attached to it so we know it couldn't have crashed; and
3540        // (3) There is a pid assigned to it, so it is either starting or
3541        //     already running.
3542        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3543                + " app=" + app + " knownToBeDead=" + knownToBeDead
3544                + " thread=" + (app != null ? app.thread : null)
3545                + " pid=" + (app != null ? app.pid : -1));
3546        if (app != null && app.pid > 0) {
3547            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3548                // We already have the app running, or are waiting for it to
3549                // come up (we have a pid but not yet its thread), so keep it.
3550                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3551                // If this is a new package in the process, add the package to the list
3552                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3553                checkTime(startTime, "startProcess: done, added package to proc");
3554                return app;
3555            }
3556
3557            // An application record is attached to a previous process,
3558            // clean it up now.
3559            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3560            checkTime(startTime, "startProcess: bad proc running, killing");
3561            killProcessGroup(app.uid, app.pid);
3562            handleAppDiedLocked(app, true, true);
3563            checkTime(startTime, "startProcess: done killing old proc");
3564        }
3565
3566        String hostingNameStr = hostingName != null
3567                ? hostingName.flattenToShortString() : null;
3568
3569        if (app == null) {
3570            checkTime(startTime, "startProcess: creating new process record");
3571            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3572            if (app == null) {
3573                Slog.w(TAG, "Failed making new process record for "
3574                        + processName + "/" + info.uid + " isolated=" + isolated);
3575                return null;
3576            }
3577            app.crashHandler = crashHandler;
3578            checkTime(startTime, "startProcess: done creating new process record");
3579        } else {
3580            // If this is a new package in the process, add the package to the list
3581            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3582            checkTime(startTime, "startProcess: added package to existing proc");
3583        }
3584
3585        // If the system is not ready yet, then hold off on starting this
3586        // process until it is.
3587        if (!mProcessesReady
3588                && !isAllowedWhileBooting(info)
3589                && !allowWhileBooting) {
3590            if (!mProcessesOnHold.contains(app)) {
3591                mProcessesOnHold.add(app);
3592            }
3593            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3594                    "System not ready, putting on hold: " + app);
3595            checkTime(startTime, "startProcess: returning with proc on hold");
3596            return app;
3597        }
3598
3599        checkTime(startTime, "startProcess: stepping in to startProcess");
3600        startProcessLocked(
3601                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3602        checkTime(startTime, "startProcess: done starting proc!");
3603        return (app.pid != 0) ? app : null;
3604    }
3605
3606    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3607        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3608    }
3609
3610    private final void startProcessLocked(ProcessRecord app,
3611            String hostingType, String hostingNameStr) {
3612        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3613                null /* entryPoint */, null /* entryPointArgs */);
3614    }
3615
3616    private final void startProcessLocked(ProcessRecord app, String hostingType,
3617            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3618        long startTime = SystemClock.elapsedRealtime();
3619        if (app.pid > 0 && app.pid != MY_PID) {
3620            checkTime(startTime, "startProcess: removing from pids map");
3621            synchronized (mPidsSelfLocked) {
3622                mPidsSelfLocked.remove(app.pid);
3623                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3624            }
3625            checkTime(startTime, "startProcess: done removing from pids map");
3626            app.setPid(0);
3627        }
3628
3629        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3630                "startProcessLocked removing on hold: " + app);
3631        mProcessesOnHold.remove(app);
3632
3633        checkTime(startTime, "startProcess: starting to update cpu stats");
3634        updateCpuStats();
3635        checkTime(startTime, "startProcess: done updating cpu stats");
3636
3637        try {
3638            try {
3639                final int userId = UserHandle.getUserId(app.uid);
3640                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3641            } catch (RemoteException e) {
3642                throw e.rethrowAsRuntimeException();
3643            }
3644
3645            int uid = app.uid;
3646            int[] gids = null;
3647            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3648            if (!app.isolated) {
3649                int[] permGids = null;
3650                try {
3651                    checkTime(startTime, "startProcess: getting gids from package manager");
3652                    final IPackageManager pm = AppGlobals.getPackageManager();
3653                    permGids = pm.getPackageGids(app.info.packageName,
3654                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3655                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3656                            MountServiceInternal.class);
3657                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3658                            app.info.packageName);
3659                } catch (RemoteException e) {
3660                    throw e.rethrowAsRuntimeException();
3661                }
3662
3663                /*
3664                 * Add shared application and profile GIDs so applications can share some
3665                 * resources like shared libraries and access user-wide resources
3666                 */
3667                if (ArrayUtils.isEmpty(permGids)) {
3668                    gids = new int[2];
3669                } else {
3670                    gids = new int[permGids.length + 2];
3671                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3672                }
3673                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3674                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3675            }
3676            checkTime(startTime, "startProcess: building args");
3677            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3678                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3679                        && mTopComponent != null
3680                        && app.processName.equals(mTopComponent.getPackageName())) {
3681                    uid = 0;
3682                }
3683                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3684                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3685                    uid = 0;
3686                }
3687            }
3688            int debugFlags = 0;
3689            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3690                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3691                // Also turn on CheckJNI for debuggable apps. It's quite
3692                // awkward to turn on otherwise.
3693                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3694            }
3695            // Run the app in safe mode if its manifest requests so or the
3696            // system is booted in safe mode.
3697            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3698                mSafeMode == true) {
3699                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3700            }
3701            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3702                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3703            }
3704            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3705            if ("true".equals(genDebugInfoProperty)) {
3706                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3707            }
3708            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3709                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3710            }
3711            if ("1".equals(SystemProperties.get("debug.assert"))) {
3712                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3713            }
3714            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3715                // Enable all debug flags required by the native debugger.
3716                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3717                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3718                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3719                mNativeDebuggingApp = null;
3720            }
3721
3722            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3723            if (requiredAbi == null) {
3724                requiredAbi = Build.SUPPORTED_ABIS[0];
3725            }
3726
3727            String instructionSet = null;
3728            if (app.info.primaryCpuAbi != null) {
3729                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3730            }
3731
3732            app.gids = gids;
3733            app.requiredAbi = requiredAbi;
3734            app.instructionSet = instructionSet;
3735
3736            // Start the process.  It will either succeed and return a result containing
3737            // the PID of the new process, or else throw a RuntimeException.
3738            boolean isActivityProcess = (entryPoint == null);
3739            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3740            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3741                    app.processName);
3742            checkTime(startTime, "startProcess: asking zygote to start proc");
3743            Process.ProcessStartResult startResult = Process.start(entryPoint,
3744                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3745                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3746                    app.info.dataDir, entryPointArgs);
3747            checkTime(startTime, "startProcess: returned from zygote!");
3748            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3749
3750            if (app.isolated) {
3751                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3752            }
3753            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3754            checkTime(startTime, "startProcess: done updating battery stats");
3755
3756            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3757                    UserHandle.getUserId(uid), startResult.pid, uid,
3758                    app.processName, hostingType,
3759                    hostingNameStr != null ? hostingNameStr : "");
3760
3761            try {
3762                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3763                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3764            } catch (RemoteException ex) {
3765                // Ignore
3766            }
3767
3768            if (app.persistent) {
3769                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3770            }
3771
3772            checkTime(startTime, "startProcess: building log message");
3773            StringBuilder buf = mStringBuilder;
3774            buf.setLength(0);
3775            buf.append("Start proc ");
3776            buf.append(startResult.pid);
3777            buf.append(':');
3778            buf.append(app.processName);
3779            buf.append('/');
3780            UserHandle.formatUid(buf, uid);
3781            if (!isActivityProcess) {
3782                buf.append(" [");
3783                buf.append(entryPoint);
3784                buf.append("]");
3785            }
3786            buf.append(" for ");
3787            buf.append(hostingType);
3788            if (hostingNameStr != null) {
3789                buf.append(" ");
3790                buf.append(hostingNameStr);
3791            }
3792            Slog.i(TAG, buf.toString());
3793            app.setPid(startResult.pid);
3794            app.usingWrapper = startResult.usingWrapper;
3795            app.removed = false;
3796            app.killed = false;
3797            app.killedByAm = false;
3798            checkTime(startTime, "startProcess: starting to update pids map");
3799            synchronized (mPidsSelfLocked) {
3800                this.mPidsSelfLocked.put(startResult.pid, app);
3801                if (isActivityProcess) {
3802                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3803                    msg.obj = app;
3804                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3805                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3806                }
3807            }
3808            checkTime(startTime, "startProcess: done updating pids map");
3809        } catch (RuntimeException e) {
3810            Slog.e(TAG, "Failure starting process " + app.processName, e);
3811
3812            // Something went very wrong while trying to start this process; one
3813            // common case is when the package is frozen due to an active
3814            // upgrade. To recover, clean up any active bookkeeping related to
3815            // starting this process. (We already invoked this method once when
3816            // the package was initially frozen through KILL_APPLICATION_MSG, so
3817            // it doesn't hurt to use it again.)
3818            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3819                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3820        }
3821    }
3822
3823    void updateUsageStats(ActivityRecord component, boolean resumed) {
3824        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3825                "updateUsageStats: comp=" + component + "res=" + resumed);
3826        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3827        if (resumed) {
3828            if (mUsageStatsService != null) {
3829                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3830                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3831            }
3832            synchronized (stats) {
3833                stats.noteActivityResumedLocked(component.app.uid);
3834            }
3835        } else {
3836            if (mUsageStatsService != null) {
3837                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3838                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3839            }
3840            synchronized (stats) {
3841                stats.noteActivityPausedLocked(component.app.uid);
3842            }
3843        }
3844    }
3845
3846    Intent getHomeIntent() {
3847        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3848        intent.setComponent(mTopComponent);
3849        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3850        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3851            intent.addCategory(Intent.CATEGORY_HOME);
3852        }
3853        return intent;
3854    }
3855
3856    boolean startHomeActivityLocked(int userId, String reason) {
3857        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3858                && mTopAction == null) {
3859            // We are running in factory test mode, but unable to find
3860            // the factory test app, so just sit around displaying the
3861            // error message and don't try to start anything.
3862            return false;
3863        }
3864        Intent intent = getHomeIntent();
3865        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3866        if (aInfo != null) {
3867            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3868            // Don't do this if the home app is currently being
3869            // instrumented.
3870            aInfo = new ActivityInfo(aInfo);
3871            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3872            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3873                    aInfo.applicationInfo.uid, true);
3874            if (app == null || app.instrumentationClass == null) {
3875                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3876                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3877            }
3878        } else {
3879            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3880        }
3881
3882        return true;
3883    }
3884
3885    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3886        ActivityInfo ai = null;
3887        ComponentName comp = intent.getComponent();
3888        try {
3889            if (comp != null) {
3890                // Factory test.
3891                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3892            } else {
3893                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3894                        intent,
3895                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3896                        flags, userId);
3897
3898                if (info != null) {
3899                    ai = info.activityInfo;
3900                }
3901            }
3902        } catch (RemoteException e) {
3903            // ignore
3904        }
3905
3906        return ai;
3907    }
3908
3909    /**
3910     * Starts the "new version setup screen" if appropriate.
3911     */
3912    void startSetupActivityLocked() {
3913        // Only do this once per boot.
3914        if (mCheckedForSetup) {
3915            return;
3916        }
3917
3918        // We will show this screen if the current one is a different
3919        // version than the last one shown, and we are not running in
3920        // low-level factory test mode.
3921        final ContentResolver resolver = mContext.getContentResolver();
3922        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3923                Settings.Global.getInt(resolver,
3924                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3925            mCheckedForSetup = true;
3926
3927            // See if we should be showing the platform update setup UI.
3928            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3929            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3930                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3931            if (!ris.isEmpty()) {
3932                final ResolveInfo ri = ris.get(0);
3933                String vers = ri.activityInfo.metaData != null
3934                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3935                        : null;
3936                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3937                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3938                            Intent.METADATA_SETUP_VERSION);
3939                }
3940                String lastVers = Settings.Secure.getString(
3941                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3942                if (vers != null && !vers.equals(lastVers)) {
3943                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3944                    intent.setComponent(new ComponentName(
3945                            ri.activityInfo.packageName, ri.activityInfo.name));
3946                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3947                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3948                            null, 0, 0, 0, null, false, false, null, null, null);
3949                }
3950            }
3951        }
3952    }
3953
3954    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3955        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3956    }
3957
3958    void enforceNotIsolatedCaller(String caller) {
3959        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3960            throw new SecurityException("Isolated process not allowed to call " + caller);
3961        }
3962    }
3963
3964    void enforceShellRestriction(String restriction, int userHandle) {
3965        if (Binder.getCallingUid() == Process.SHELL_UID) {
3966            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3967                throw new SecurityException("Shell does not have permission to access user "
3968                        + userHandle);
3969            }
3970        }
3971    }
3972
3973    @Override
3974    public int getFrontActivityScreenCompatMode() {
3975        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3976        synchronized (this) {
3977            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3978        }
3979    }
3980
3981    @Override
3982    public void setFrontActivityScreenCompatMode(int mode) {
3983        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3984                "setFrontActivityScreenCompatMode");
3985        synchronized (this) {
3986            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3987        }
3988    }
3989
3990    @Override
3991    public int getPackageScreenCompatMode(String packageName) {
3992        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3993        synchronized (this) {
3994            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3995        }
3996    }
3997
3998    @Override
3999    public void setPackageScreenCompatMode(String packageName, int mode) {
4000        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4001                "setPackageScreenCompatMode");
4002        synchronized (this) {
4003            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4004        }
4005    }
4006
4007    @Override
4008    public boolean getPackageAskScreenCompat(String packageName) {
4009        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4010        synchronized (this) {
4011            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4012        }
4013    }
4014
4015    @Override
4016    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4017        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4018                "setPackageAskScreenCompat");
4019        synchronized (this) {
4020            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4021        }
4022    }
4023
4024    private boolean hasUsageStatsPermission(String callingPackage) {
4025        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4026                Binder.getCallingUid(), callingPackage);
4027        if (mode == AppOpsManager.MODE_DEFAULT) {
4028            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4029                    == PackageManager.PERMISSION_GRANTED;
4030        }
4031        return mode == AppOpsManager.MODE_ALLOWED;
4032    }
4033
4034    @Override
4035    public int getPackageProcessState(String packageName, String callingPackage) {
4036        if (!hasUsageStatsPermission(callingPackage)) {
4037            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4038                    "getPackageProcessState");
4039        }
4040
4041        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4042        synchronized (this) {
4043            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4044                final ProcessRecord proc = mLruProcesses.get(i);
4045                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4046                        || procState > proc.setProcState) {
4047                    boolean found = false;
4048                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4049                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4050                            procState = proc.setProcState;
4051                            found = true;
4052                        }
4053                    }
4054                    if (proc.pkgDeps != null && !found) {
4055                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4056                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4057                                procState = proc.setProcState;
4058                                break;
4059                            }
4060                        }
4061                    }
4062                }
4063            }
4064        }
4065        return procState;
4066    }
4067
4068    @Override
4069    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4070        synchronized (this) {
4071            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4072            if (app == null) {
4073                return false;
4074            }
4075            if (app.trimMemoryLevel < level && app.thread != null &&
4076                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4077                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4078                try {
4079                    app.thread.scheduleTrimMemory(level);
4080                    app.trimMemoryLevel = level;
4081                    return true;
4082                } catch (RemoteException e) {
4083                    // Fallthrough to failure case.
4084                }
4085            }
4086        }
4087        return false;
4088    }
4089
4090    private void dispatchProcessesChanged() {
4091        int N;
4092        synchronized (this) {
4093            N = mPendingProcessChanges.size();
4094            if (mActiveProcessChanges.length < N) {
4095                mActiveProcessChanges = new ProcessChangeItem[N];
4096            }
4097            mPendingProcessChanges.toArray(mActiveProcessChanges);
4098            mPendingProcessChanges.clear();
4099            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4100                    "*** Delivering " + N + " process changes");
4101        }
4102
4103        int i = mProcessObservers.beginBroadcast();
4104        while (i > 0) {
4105            i--;
4106            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4107            if (observer != null) {
4108                try {
4109                    for (int j=0; j<N; j++) {
4110                        ProcessChangeItem item = mActiveProcessChanges[j];
4111                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4112                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4113                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4114                                    + item.uid + ": " + item.foregroundActivities);
4115                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4116                                    item.foregroundActivities);
4117                        }
4118                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4119                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4120                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4121                                    + ": " + item.processState);
4122                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4123                        }
4124                    }
4125                } catch (RemoteException e) {
4126                }
4127            }
4128        }
4129        mProcessObservers.finishBroadcast();
4130
4131        synchronized (this) {
4132            for (int j=0; j<N; j++) {
4133                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4134            }
4135        }
4136    }
4137
4138    private void dispatchProcessDied(int pid, int uid) {
4139        int i = mProcessObservers.beginBroadcast();
4140        while (i > 0) {
4141            i--;
4142            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4143            if (observer != null) {
4144                try {
4145                    observer.onProcessDied(pid, uid);
4146                } catch (RemoteException e) {
4147                }
4148            }
4149        }
4150        mProcessObservers.finishBroadcast();
4151    }
4152
4153    private void dispatchUidsChanged() {
4154        int N;
4155        synchronized (this) {
4156            N = mPendingUidChanges.size();
4157            if (mActiveUidChanges.length < N) {
4158                mActiveUidChanges = new UidRecord.ChangeItem[N];
4159            }
4160            for (int i=0; i<N; i++) {
4161                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4162                mActiveUidChanges[i] = change;
4163                if (change.uidRecord != null) {
4164                    change.uidRecord.pendingChange = null;
4165                    change.uidRecord = null;
4166                }
4167            }
4168            mPendingUidChanges.clear();
4169            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4170                    "*** Delivering " + N + " uid changes");
4171        }
4172
4173        if (mLocalPowerManager != null) {
4174            for (int j=0; j<N; j++) {
4175                UidRecord.ChangeItem item = mActiveUidChanges[j];
4176                if (item.change == UidRecord.CHANGE_GONE
4177                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4178                    mLocalPowerManager.uidGone(item.uid);
4179                } else {
4180                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4181                }
4182            }
4183        }
4184
4185        int i = mUidObservers.beginBroadcast();
4186        while (i > 0) {
4187            i--;
4188            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4189            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4190            if (observer != null) {
4191                try {
4192                    for (int j=0; j<N; j++) {
4193                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4194                        final int change = item.change;
4195                        UidRecord validateUid = null;
4196                        if (VALIDATE_UID_STATES && i == 0) {
4197                            validateUid = mValidateUids.get(item.uid);
4198                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4199                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4200                                validateUid = new UidRecord(item.uid);
4201                                mValidateUids.put(item.uid, validateUid);
4202                            }
4203                        }
4204                        if (change == UidRecord.CHANGE_IDLE
4205                                || change == UidRecord.CHANGE_GONE_IDLE) {
4206                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4207                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4208                                        "UID idle uid=" + item.uid);
4209                                observer.onUidIdle(item.uid);
4210                            }
4211                            if (VALIDATE_UID_STATES && i == 0) {
4212                                if (validateUid != null) {
4213                                    validateUid.idle = true;
4214                                }
4215                            }
4216                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4217                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4218                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4219                                        "UID active uid=" + item.uid);
4220                                observer.onUidActive(item.uid);
4221                            }
4222                            if (VALIDATE_UID_STATES && i == 0) {
4223                                validateUid.idle = false;
4224                            }
4225                        }
4226                        if (change == UidRecord.CHANGE_GONE
4227                                || change == UidRecord.CHANGE_GONE_IDLE) {
4228                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4229                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4230                                        "UID gone uid=" + item.uid);
4231                                observer.onUidGone(item.uid);
4232                            }
4233                            if (VALIDATE_UID_STATES && i == 0) {
4234                                if (validateUid != null) {
4235                                    mValidateUids.remove(item.uid);
4236                                }
4237                            }
4238                        } else {
4239                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4240                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4241                                        "UID CHANGED uid=" + item.uid
4242                                                + ": " + item.processState);
4243                                observer.onUidStateChanged(item.uid, item.processState);
4244                            }
4245                            if (VALIDATE_UID_STATES && i == 0) {
4246                                validateUid.curProcState = validateUid.setProcState
4247                                        = item.processState;
4248                            }
4249                        }
4250                    }
4251                } catch (RemoteException e) {
4252                }
4253            }
4254        }
4255        mUidObservers.finishBroadcast();
4256
4257        synchronized (this) {
4258            for (int j=0; j<N; j++) {
4259                mAvailUidChanges.add(mActiveUidChanges[j]);
4260            }
4261        }
4262    }
4263
4264    @Override
4265    public final int startActivity(IApplicationThread caller, String callingPackage,
4266            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4267            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4268        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4269                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4270                UserHandle.getCallingUserId());
4271    }
4272
4273    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4274        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4275        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4276                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4277                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4278
4279        // TODO: Switch to user app stacks here.
4280        String mimeType = intent.getType();
4281        final Uri data = intent.getData();
4282        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4283            mimeType = getProviderMimeType(data, userId);
4284        }
4285        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4286
4287        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4288        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4289                null, 0, 0, null, null, null, null, false, userId, container, null);
4290    }
4291
4292    @Override
4293    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4294            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4295            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4296        enforceNotIsolatedCaller("startActivity");
4297        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4298                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4299        // TODO: Switch to user app stacks here.
4300        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4301                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4302                profilerInfo, null, null, bOptions, false, userId, null, null);
4303    }
4304
4305    @Override
4306    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4307            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4308            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4309            int userId) {
4310
4311        // This is very dangerous -- it allows you to perform a start activity (including
4312        // permission grants) as any app that may launch one of your own activities.  So
4313        // we will only allow this to be done from activities that are part of the core framework,
4314        // and then only when they are running as the system.
4315        final ActivityRecord sourceRecord;
4316        final int targetUid;
4317        final String targetPackage;
4318        synchronized (this) {
4319            if (resultTo == null) {
4320                throw new SecurityException("Must be called from an activity");
4321            }
4322            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4323            if (sourceRecord == null) {
4324                throw new SecurityException("Called with bad activity token: " + resultTo);
4325            }
4326            if (!sourceRecord.info.packageName.equals("android")) {
4327                throw new SecurityException(
4328                        "Must be called from an activity that is declared in the android package");
4329            }
4330            if (sourceRecord.app == null) {
4331                throw new SecurityException("Called without a process attached to activity");
4332            }
4333            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4334                // This is still okay, as long as this activity is running under the
4335                // uid of the original calling activity.
4336                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4337                    throw new SecurityException(
4338                            "Calling activity in uid " + sourceRecord.app.uid
4339                                    + " must be system uid or original calling uid "
4340                                    + sourceRecord.launchedFromUid);
4341                }
4342            }
4343            if (ignoreTargetSecurity) {
4344                if (intent.getComponent() == null) {
4345                    throw new SecurityException(
4346                            "Component must be specified with ignoreTargetSecurity");
4347                }
4348                if (intent.getSelector() != null) {
4349                    throw new SecurityException(
4350                            "Selector not allowed with ignoreTargetSecurity");
4351                }
4352            }
4353            targetUid = sourceRecord.launchedFromUid;
4354            targetPackage = sourceRecord.launchedFromPackage;
4355        }
4356
4357        if (userId == UserHandle.USER_NULL) {
4358            userId = UserHandle.getUserId(sourceRecord.app.uid);
4359        }
4360
4361        // TODO: Switch to user app stacks here.
4362        try {
4363            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4364                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4365                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4366            return ret;
4367        } catch (SecurityException e) {
4368            // XXX need to figure out how to propagate to original app.
4369            // A SecurityException here is generally actually a fault of the original
4370            // calling activity (such as a fairly granting permissions), so propagate it
4371            // back to them.
4372            /*
4373            StringBuilder msg = new StringBuilder();
4374            msg.append("While launching");
4375            msg.append(intent.toString());
4376            msg.append(": ");
4377            msg.append(e.getMessage());
4378            */
4379            throw e;
4380        }
4381    }
4382
4383    @Override
4384    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4385            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4386            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4387        enforceNotIsolatedCaller("startActivityAndWait");
4388        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4389                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4390        WaitResult res = new WaitResult();
4391        // TODO: Switch to user app stacks here.
4392        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4393                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4394                bOptions, false, userId, null, null);
4395        return res;
4396    }
4397
4398    @Override
4399    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4400            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4401            int startFlags, Configuration config, Bundle bOptions, int userId) {
4402        enforceNotIsolatedCaller("startActivityWithConfig");
4403        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4404                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4405        // TODO: Switch to user app stacks here.
4406        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4407                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4408                null, null, config, bOptions, false, userId, null, null);
4409        return ret;
4410    }
4411
4412    @Override
4413    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4414            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4415            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4416            throws TransactionTooLargeException {
4417        enforceNotIsolatedCaller("startActivityIntentSender");
4418        // Refuse possible leaked file descriptors
4419        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4420            throw new IllegalArgumentException("File descriptors passed in Intent");
4421        }
4422
4423        IIntentSender sender = intent.getTarget();
4424        if (!(sender instanceof PendingIntentRecord)) {
4425            throw new IllegalArgumentException("Bad PendingIntent object");
4426        }
4427
4428        PendingIntentRecord pir = (PendingIntentRecord)sender;
4429
4430        synchronized (this) {
4431            // If this is coming from the currently resumed activity, it is
4432            // effectively saying that app switches are allowed at this point.
4433            final ActivityStack stack = getFocusedStack();
4434            if (stack.mResumedActivity != null &&
4435                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4436                mAppSwitchesAllowedTime = 0;
4437            }
4438        }
4439        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4440                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4441        return ret;
4442    }
4443
4444    @Override
4445    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4446            Intent intent, String resolvedType, IVoiceInteractionSession session,
4447            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4448            Bundle bOptions, int userId) {
4449        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4450                != PackageManager.PERMISSION_GRANTED) {
4451            String msg = "Permission Denial: startVoiceActivity() from pid="
4452                    + Binder.getCallingPid()
4453                    + ", uid=" + Binder.getCallingUid()
4454                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4455            Slog.w(TAG, msg);
4456            throw new SecurityException(msg);
4457        }
4458        if (session == null || interactor == null) {
4459            throw new NullPointerException("null session or interactor");
4460        }
4461        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4462                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4463        // TODO: Switch to user app stacks here.
4464        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4465                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4466                null, bOptions, false, userId, null, null);
4467    }
4468
4469    @Override
4470    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4471            throws RemoteException {
4472        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4473        synchronized (this) {
4474            ActivityRecord activity = getFocusedStack().topActivity();
4475            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4476                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4477            }
4478            if (mRunningVoice != null || activity.task.voiceSession != null
4479                    || activity.voiceSession != null) {
4480                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4481                return;
4482            }
4483            if (activity.pendingVoiceInteractionStart) {
4484                Slog.w(TAG, "Pending start of voice interaction already.");
4485                return;
4486            }
4487            activity.pendingVoiceInteractionStart = true;
4488        }
4489        LocalServices.getService(VoiceInteractionManagerInternal.class)
4490                .startLocalVoiceInteraction(callingActivity, options);
4491    }
4492
4493    @Override
4494    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4495        LocalServices.getService(VoiceInteractionManagerInternal.class)
4496                .stopLocalVoiceInteraction(callingActivity);
4497    }
4498
4499    @Override
4500    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4501        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4502                .supportsLocalVoiceInteraction();
4503    }
4504
4505    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4506            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4507        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4508        if (activityToCallback == null) return;
4509        activityToCallback.setVoiceSessionLocked(voiceSession);
4510
4511        // Inform the activity
4512        try {
4513            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4514                    voiceInteractor);
4515            long token = Binder.clearCallingIdentity();
4516            try {
4517                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4518            } finally {
4519                Binder.restoreCallingIdentity(token);
4520            }
4521            // TODO: VI Should we cache the activity so that it's easier to find later
4522            // rather than scan through all the stacks and activities?
4523        } catch (RemoteException re) {
4524            activityToCallback.clearVoiceSessionLocked();
4525            // TODO: VI Should this terminate the voice session?
4526        }
4527    }
4528
4529    @Override
4530    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4531        synchronized (this) {
4532            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4533                if (keepAwake) {
4534                    mVoiceWakeLock.acquire();
4535                } else {
4536                    mVoiceWakeLock.release();
4537                }
4538            }
4539        }
4540    }
4541
4542    @Override
4543    public boolean startNextMatchingActivity(IBinder callingActivity,
4544            Intent intent, Bundle bOptions) {
4545        // Refuse possible leaked file descriptors
4546        if (intent != null && intent.hasFileDescriptors() == true) {
4547            throw new IllegalArgumentException("File descriptors passed in Intent");
4548        }
4549        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4550
4551        synchronized (this) {
4552            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4553            if (r == null) {
4554                ActivityOptions.abort(options);
4555                return false;
4556            }
4557            if (r.app == null || r.app.thread == null) {
4558                // The caller is not running...  d'oh!
4559                ActivityOptions.abort(options);
4560                return false;
4561            }
4562            intent = new Intent(intent);
4563            // The caller is not allowed to change the data.
4564            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4565            // And we are resetting to find the next component...
4566            intent.setComponent(null);
4567
4568            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4569
4570            ActivityInfo aInfo = null;
4571            try {
4572                List<ResolveInfo> resolves =
4573                    AppGlobals.getPackageManager().queryIntentActivities(
4574                            intent, r.resolvedType,
4575                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4576                            UserHandle.getCallingUserId()).getList();
4577
4578                // Look for the original activity in the list...
4579                final int N = resolves != null ? resolves.size() : 0;
4580                for (int i=0; i<N; i++) {
4581                    ResolveInfo rInfo = resolves.get(i);
4582                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4583                            && rInfo.activityInfo.name.equals(r.info.name)) {
4584                        // We found the current one...  the next matching is
4585                        // after it.
4586                        i++;
4587                        if (i<N) {
4588                            aInfo = resolves.get(i).activityInfo;
4589                        }
4590                        if (debug) {
4591                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4592                                    + "/" + r.info.name);
4593                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4594                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4595                        }
4596                        break;
4597                    }
4598                }
4599            } catch (RemoteException e) {
4600            }
4601
4602            if (aInfo == null) {
4603                // Nobody who is next!
4604                ActivityOptions.abort(options);
4605                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4606                return false;
4607            }
4608
4609            intent.setComponent(new ComponentName(
4610                    aInfo.applicationInfo.packageName, aInfo.name));
4611            intent.setFlags(intent.getFlags()&~(
4612                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4613                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4614                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4615                    Intent.FLAG_ACTIVITY_NEW_TASK));
4616
4617            // Okay now we need to start the new activity, replacing the
4618            // currently running activity.  This is a little tricky because
4619            // we want to start the new one as if the current one is finished,
4620            // but not finish the current one first so that there is no flicker.
4621            // And thus...
4622            final boolean wasFinishing = r.finishing;
4623            r.finishing = true;
4624
4625            // Propagate reply information over to the new activity.
4626            final ActivityRecord resultTo = r.resultTo;
4627            final String resultWho = r.resultWho;
4628            final int requestCode = r.requestCode;
4629            r.resultTo = null;
4630            if (resultTo != null) {
4631                resultTo.removeResultsLocked(r, resultWho, requestCode);
4632            }
4633
4634            final long origId = Binder.clearCallingIdentity();
4635            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4636                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4637                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4638                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4639                    false, false, null, null, null);
4640            Binder.restoreCallingIdentity(origId);
4641
4642            r.finishing = wasFinishing;
4643            if (res != ActivityManager.START_SUCCESS) {
4644                return false;
4645            }
4646            return true;
4647        }
4648    }
4649
4650    @Override
4651    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4652        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4653            String msg = "Permission Denial: startActivityFromRecents called without " +
4654                    START_TASKS_FROM_RECENTS;
4655            Slog.w(TAG, msg);
4656            throw new SecurityException(msg);
4657        }
4658        final long origId = Binder.clearCallingIdentity();
4659        try {
4660            synchronized (this) {
4661                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4662            }
4663        } finally {
4664            Binder.restoreCallingIdentity(origId);
4665        }
4666    }
4667
4668    final int startActivityInPackage(int uid, String callingPackage,
4669            Intent intent, String resolvedType, IBinder resultTo,
4670            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4671            IActivityContainer container, TaskRecord inTask) {
4672
4673        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4674                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4675
4676        // TODO: Switch to user app stacks here.
4677        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4678                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4679                null, null, null, bOptions, false, userId, container, inTask);
4680        return ret;
4681    }
4682
4683    @Override
4684    public final int startActivities(IApplicationThread caller, String callingPackage,
4685            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4686            int userId) {
4687        enforceNotIsolatedCaller("startActivities");
4688        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4689                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4690        // TODO: Switch to user app stacks here.
4691        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4692                resolvedTypes, resultTo, bOptions, userId);
4693        return ret;
4694    }
4695
4696    final int startActivitiesInPackage(int uid, String callingPackage,
4697            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4698            Bundle bOptions, int userId) {
4699
4700        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4701                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4702        // TODO: Switch to user app stacks here.
4703        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4704                resultTo, bOptions, userId);
4705        return ret;
4706    }
4707
4708    @Override
4709    public void reportActivityFullyDrawn(IBinder token) {
4710        synchronized (this) {
4711            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4712            if (r == null) {
4713                return;
4714            }
4715            r.reportFullyDrawnLocked();
4716        }
4717    }
4718
4719    @Override
4720    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4721        synchronized (this) {
4722            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4723            if (r == null) {
4724                return;
4725            }
4726            TaskRecord task = r.task;
4727            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4728                // Fixed screen orientation isn't supported when activities aren't in full screen
4729                // mode.
4730                return;
4731            }
4732            final long origId = Binder.clearCallingIdentity();
4733            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4734            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4735                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4736            if (config != null) {
4737                r.frozenBeforeDestroy = true;
4738                if (!updateConfigurationLocked(config, r, false)) {
4739                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4740                }
4741            }
4742            Binder.restoreCallingIdentity(origId);
4743        }
4744    }
4745
4746    @Override
4747    public int getRequestedOrientation(IBinder token) {
4748        synchronized (this) {
4749            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4750            if (r == null) {
4751                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4752            }
4753            return mWindowManager.getAppOrientation(r.appToken);
4754        }
4755    }
4756
4757    /**
4758     * This is the internal entry point for handling Activity.finish().
4759     *
4760     * @param token The Binder token referencing the Activity we want to finish.
4761     * @param resultCode Result code, if any, from this Activity.
4762     * @param resultData Result data (Intent), if any, from this Activity.
4763     * @param finishTask Whether to finish the task associated with this Activity.
4764     *
4765     * @return Returns true if the activity successfully finished, or false if it is still running.
4766     */
4767    @Override
4768    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4769            int finishTask) {
4770        // Refuse possible leaked file descriptors
4771        if (resultData != null && resultData.hasFileDescriptors() == true) {
4772            throw new IllegalArgumentException("File descriptors passed in Intent");
4773        }
4774
4775        synchronized(this) {
4776            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4777            if (r == null) {
4778                return true;
4779            }
4780            // Keep track of the root activity of the task before we finish it
4781            TaskRecord tr = r.task;
4782            ActivityRecord rootR = tr.getRootActivity();
4783            if (rootR == null) {
4784                Slog.w(TAG, "Finishing task with all activities already finished");
4785            }
4786            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4787            // finish.
4788            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4789                    mStackSupervisor.isLastLockedTask(tr)) {
4790                Slog.i(TAG, "Not finishing task in lock task mode");
4791                mStackSupervisor.showLockTaskToast();
4792                return false;
4793            }
4794            if (mController != null) {
4795                // Find the first activity that is not finishing.
4796                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4797                if (next != null) {
4798                    // ask watcher if this is allowed
4799                    boolean resumeOK = true;
4800                    try {
4801                        resumeOK = mController.activityResuming(next.packageName);
4802                    } catch (RemoteException e) {
4803                        mController = null;
4804                        Watchdog.getInstance().setActivityController(null);
4805                    }
4806
4807                    if (!resumeOK) {
4808                        Slog.i(TAG, "Not finishing activity because controller resumed");
4809                        return false;
4810                    }
4811                }
4812            }
4813            final long origId = Binder.clearCallingIdentity();
4814            try {
4815                boolean res;
4816                final boolean finishWithRootActivity =
4817                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4818                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4819                        || (finishWithRootActivity && r == rootR)) {
4820                    // If requested, remove the task that is associated to this activity only if it
4821                    // was the root activity in the task. The result code and data is ignored
4822                    // because we don't support returning them across task boundaries. Also, to
4823                    // keep backwards compatibility we remove the task from recents when finishing
4824                    // task with root activity.
4825                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4826                    if (!res) {
4827                        Slog.i(TAG, "Removing task failed to finish activity");
4828                    }
4829                } else {
4830                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4831                            resultData, "app-request", true);
4832                    if (!res) {
4833                        Slog.i(TAG, "Failed to finish by app-request");
4834                    }
4835                }
4836                return res;
4837            } finally {
4838                Binder.restoreCallingIdentity(origId);
4839            }
4840        }
4841    }
4842
4843    @Override
4844    public final void finishHeavyWeightApp() {
4845        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4846                != PackageManager.PERMISSION_GRANTED) {
4847            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4848                    + Binder.getCallingPid()
4849                    + ", uid=" + Binder.getCallingUid()
4850                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4851            Slog.w(TAG, msg);
4852            throw new SecurityException(msg);
4853        }
4854
4855        synchronized(this) {
4856            if (mHeavyWeightProcess == null) {
4857                return;
4858            }
4859
4860            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4861            for (int i = 0; i < activities.size(); i++) {
4862                ActivityRecord r = activities.get(i);
4863                if (!r.finishing && r.isInStackLocked()) {
4864                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4865                            null, "finish-heavy", true);
4866                }
4867            }
4868
4869            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4870                    mHeavyWeightProcess.userId, 0));
4871            mHeavyWeightProcess = null;
4872        }
4873    }
4874
4875    @Override
4876    public void crashApplication(int uid, int initialPid, String packageName,
4877            String message) {
4878        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4879                != PackageManager.PERMISSION_GRANTED) {
4880            String msg = "Permission Denial: crashApplication() from pid="
4881                    + Binder.getCallingPid()
4882                    + ", uid=" + Binder.getCallingUid()
4883                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4884            Slog.w(TAG, msg);
4885            throw new SecurityException(msg);
4886        }
4887
4888        synchronized(this) {
4889            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4890        }
4891    }
4892
4893    @Override
4894    public final void finishSubActivity(IBinder token, String resultWho,
4895            int requestCode) {
4896        synchronized(this) {
4897            final long origId = Binder.clearCallingIdentity();
4898            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4899            if (r != null) {
4900                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4901            }
4902            Binder.restoreCallingIdentity(origId);
4903        }
4904    }
4905
4906    @Override
4907    public boolean finishActivityAffinity(IBinder token) {
4908        synchronized(this) {
4909            final long origId = Binder.clearCallingIdentity();
4910            try {
4911                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4912                if (r == null) {
4913                    return false;
4914                }
4915
4916                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4917                // can finish.
4918                final TaskRecord task = r.task;
4919                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4920                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4921                    mStackSupervisor.showLockTaskToast();
4922                    return false;
4923                }
4924                return task.stack.finishActivityAffinityLocked(r);
4925            } finally {
4926                Binder.restoreCallingIdentity(origId);
4927            }
4928        }
4929    }
4930
4931    @Override
4932    public void finishVoiceTask(IVoiceInteractionSession session) {
4933        synchronized (this) {
4934            final long origId = Binder.clearCallingIdentity();
4935            try {
4936                // TODO: VI Consider treating local voice interactions and voice tasks
4937                // differently here
4938                mStackSupervisor.finishVoiceTask(session);
4939            } finally {
4940                Binder.restoreCallingIdentity(origId);
4941            }
4942        }
4943
4944    }
4945
4946    @Override
4947    public boolean releaseActivityInstance(IBinder token) {
4948        synchronized(this) {
4949            final long origId = Binder.clearCallingIdentity();
4950            try {
4951                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4952                if (r == null) {
4953                    return false;
4954                }
4955                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4956            } finally {
4957                Binder.restoreCallingIdentity(origId);
4958            }
4959        }
4960    }
4961
4962    @Override
4963    public void releaseSomeActivities(IApplicationThread appInt) {
4964        synchronized(this) {
4965            final long origId = Binder.clearCallingIdentity();
4966            try {
4967                ProcessRecord app = getRecordForAppLocked(appInt);
4968                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4969            } finally {
4970                Binder.restoreCallingIdentity(origId);
4971            }
4972        }
4973    }
4974
4975    @Override
4976    public boolean willActivityBeVisible(IBinder token) {
4977        synchronized(this) {
4978            ActivityStack stack = ActivityRecord.getStackLocked(token);
4979            if (stack != null) {
4980                return stack.willActivityBeVisibleLocked(token);
4981            }
4982            return false;
4983        }
4984    }
4985
4986    @Override
4987    public void overridePendingTransition(IBinder token, String packageName,
4988            int enterAnim, int exitAnim) {
4989        synchronized(this) {
4990            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4991            if (self == null) {
4992                return;
4993            }
4994
4995            final long origId = Binder.clearCallingIdentity();
4996
4997            if (self.state == ActivityState.RESUMED
4998                    || self.state == ActivityState.PAUSING) {
4999                mWindowManager.overridePendingAppTransition(packageName,
5000                        enterAnim, exitAnim, null);
5001            }
5002
5003            Binder.restoreCallingIdentity(origId);
5004        }
5005    }
5006
5007    /**
5008     * Main function for removing an existing process from the activity manager
5009     * as a result of that process going away.  Clears out all connections
5010     * to the process.
5011     */
5012    private final void handleAppDiedLocked(ProcessRecord app,
5013            boolean restarting, boolean allowRestart) {
5014        int pid = app.pid;
5015        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5016        if (!kept && !restarting) {
5017            removeLruProcessLocked(app);
5018            if (pid > 0) {
5019                ProcessList.remove(pid);
5020            }
5021        }
5022
5023        if (mProfileProc == app) {
5024            clearProfilerLocked();
5025        }
5026
5027        // Remove this application's activities from active lists.
5028        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5029
5030        app.activities.clear();
5031
5032        if (app.instrumentationClass != null) {
5033            Slog.w(TAG, "Crash of app " + app.processName
5034                  + " running instrumentation " + app.instrumentationClass);
5035            Bundle info = new Bundle();
5036            info.putString("shortMsg", "Process crashed.");
5037            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5038        }
5039
5040        if (!restarting && hasVisibleActivities
5041                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5042            // If there was nothing to resume, and we are not already restarting this process, but
5043            // there is a visible activity that is hosted by the process...  then make sure all
5044            // visible activities are running, taking care of restarting this process.
5045            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5046        }
5047    }
5048
5049    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5050        IBinder threadBinder = thread.asBinder();
5051        // Find the application record.
5052        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5053            ProcessRecord rec = mLruProcesses.get(i);
5054            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5055                return i;
5056            }
5057        }
5058        return -1;
5059    }
5060
5061    final ProcessRecord getRecordForAppLocked(
5062            IApplicationThread thread) {
5063        if (thread == null) {
5064            return null;
5065        }
5066
5067        int appIndex = getLRURecordIndexForAppLocked(thread);
5068        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5069    }
5070
5071    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5072        // If there are no longer any background processes running,
5073        // and the app that died was not running instrumentation,
5074        // then tell everyone we are now low on memory.
5075        boolean haveBg = false;
5076        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5077            ProcessRecord rec = mLruProcesses.get(i);
5078            if (rec.thread != null
5079                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5080                haveBg = true;
5081                break;
5082            }
5083        }
5084
5085        if (!haveBg) {
5086            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5087            if (doReport) {
5088                long now = SystemClock.uptimeMillis();
5089                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5090                    doReport = false;
5091                } else {
5092                    mLastMemUsageReportTime = now;
5093                }
5094            }
5095            final ArrayList<ProcessMemInfo> memInfos
5096                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5097            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5098            long now = SystemClock.uptimeMillis();
5099            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5100                ProcessRecord rec = mLruProcesses.get(i);
5101                if (rec == dyingProc || rec.thread == null) {
5102                    continue;
5103                }
5104                if (doReport) {
5105                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5106                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5107                }
5108                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5109                    // The low memory report is overriding any current
5110                    // state for a GC request.  Make sure to do
5111                    // heavy/important/visible/foreground processes first.
5112                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5113                        rec.lastRequestedGc = 0;
5114                    } else {
5115                        rec.lastRequestedGc = rec.lastLowMemory;
5116                    }
5117                    rec.reportLowMemory = true;
5118                    rec.lastLowMemory = now;
5119                    mProcessesToGc.remove(rec);
5120                    addProcessToGcListLocked(rec);
5121                }
5122            }
5123            if (doReport) {
5124                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5125                mHandler.sendMessage(msg);
5126            }
5127            scheduleAppGcsLocked();
5128        }
5129    }
5130
5131    final void appDiedLocked(ProcessRecord app) {
5132       appDiedLocked(app, app.pid, app.thread, false);
5133    }
5134
5135    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5136            boolean fromBinderDied) {
5137        // First check if this ProcessRecord is actually active for the pid.
5138        synchronized (mPidsSelfLocked) {
5139            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5140            if (curProc != app) {
5141                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5142                return;
5143            }
5144        }
5145
5146        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5147        synchronized (stats) {
5148            stats.noteProcessDiedLocked(app.info.uid, pid);
5149        }
5150
5151        if (!app.killed) {
5152            if (!fromBinderDied) {
5153                Process.killProcessQuiet(pid);
5154            }
5155            killProcessGroup(app.uid, pid);
5156            app.killed = true;
5157        }
5158
5159        // Clean up already done if the process has been re-started.
5160        if (app.pid == pid && app.thread != null &&
5161                app.thread.asBinder() == thread.asBinder()) {
5162            boolean doLowMem = app.instrumentationClass == null;
5163            boolean doOomAdj = doLowMem;
5164            if (!app.killedByAm) {
5165                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5166                        + ") has died");
5167                mAllowLowerMemLevel = true;
5168            } else {
5169                // Note that we always want to do oom adj to update our state with the
5170                // new number of procs.
5171                mAllowLowerMemLevel = false;
5172                doLowMem = false;
5173            }
5174            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5175            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5176                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5177            handleAppDiedLocked(app, false, true);
5178
5179            if (doOomAdj) {
5180                updateOomAdjLocked();
5181            }
5182            if (doLowMem) {
5183                doLowMemReportIfNeededLocked(app);
5184            }
5185        } else if (app.pid != pid) {
5186            // A new process has already been started.
5187            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5188                    + ") has died and restarted (pid " + app.pid + ").");
5189            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5190        } else if (DEBUG_PROCESSES) {
5191            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5192                    + thread.asBinder());
5193        }
5194    }
5195
5196    /**
5197     * If a stack trace dump file is configured, dump process stack traces.
5198     * @param clearTraces causes the dump file to be erased prior to the new
5199     *    traces being written, if true; when false, the new traces will be
5200     *    appended to any existing file content.
5201     * @param firstPids of dalvik VM processes to dump stack traces for first
5202     * @param lastPids of dalvik VM processes to dump stack traces for last
5203     * @param nativeProcs optional list of native process names to dump stack crawls
5204     * @return file containing stack traces, or null if no dump file is configured
5205     */
5206    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5207            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5208        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5209        if (tracesPath == null || tracesPath.length() == 0) {
5210            return null;
5211        }
5212
5213        File tracesFile = new File(tracesPath);
5214        try {
5215            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5216            tracesFile.createNewFile();
5217            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5218        } catch (IOException e) {
5219            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5220            return null;
5221        }
5222
5223        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5224        return tracesFile;
5225    }
5226
5227    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5228            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5229        // Use a FileObserver to detect when traces finish writing.
5230        // The order of traces is considered important to maintain for legibility.
5231        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5232            @Override
5233            public synchronized void onEvent(int event, String path) { notify(); }
5234        };
5235
5236        try {
5237            observer.startWatching();
5238
5239            // First collect all of the stacks of the most important pids.
5240            if (firstPids != null) {
5241                try {
5242                    int num = firstPids.size();
5243                    for (int i = 0; i < num; i++) {
5244                        synchronized (observer) {
5245                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5246                                    + firstPids.get(i));
5247                            final long sime = SystemClock.elapsedRealtime();
5248                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5249                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5250                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5251                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5252                        }
5253                    }
5254                } catch (InterruptedException e) {
5255                    Slog.wtf(TAG, e);
5256                }
5257            }
5258
5259            // Next collect the stacks of the native pids
5260            if (nativeProcs != null) {
5261                int[] pids = Process.getPidsForCommands(nativeProcs);
5262                if (pids != null) {
5263                    for (int pid : pids) {
5264                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5265                        final long sime = SystemClock.elapsedRealtime();
5266                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5267                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5268                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5269                    }
5270                }
5271            }
5272
5273            // Lastly, measure CPU usage.
5274            if (processCpuTracker != null) {
5275                processCpuTracker.init();
5276                System.gc();
5277                processCpuTracker.update();
5278                try {
5279                    synchronized (processCpuTracker) {
5280                        processCpuTracker.wait(500); // measure over 1/2 second.
5281                    }
5282                } catch (InterruptedException e) {
5283                }
5284                processCpuTracker.update();
5285
5286                // We'll take the stack crawls of just the top apps using CPU.
5287                final int N = processCpuTracker.countWorkingStats();
5288                int numProcs = 0;
5289                for (int i=0; i<N && numProcs<5; i++) {
5290                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5291                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5292                        numProcs++;
5293                        try {
5294                            synchronized (observer) {
5295                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5296                                        + stats.pid);
5297                                final long stime = SystemClock.elapsedRealtime();
5298                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5299                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5300                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5301                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5302                            }
5303                        } catch (InterruptedException e) {
5304                            Slog.wtf(TAG, e);
5305                        }
5306                    } else if (DEBUG_ANR) {
5307                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5308                                + stats.pid);
5309                    }
5310                }
5311            }
5312        } finally {
5313            observer.stopWatching();
5314        }
5315    }
5316
5317    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5318        if (true || IS_USER_BUILD) {
5319            return;
5320        }
5321        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5322        if (tracesPath == null || tracesPath.length() == 0) {
5323            return;
5324        }
5325
5326        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5327        StrictMode.allowThreadDiskWrites();
5328        try {
5329            final File tracesFile = new File(tracesPath);
5330            final File tracesDir = tracesFile.getParentFile();
5331            final File tracesTmp = new File(tracesDir, "__tmp__");
5332            try {
5333                if (tracesFile.exists()) {
5334                    tracesTmp.delete();
5335                    tracesFile.renameTo(tracesTmp);
5336                }
5337                StringBuilder sb = new StringBuilder();
5338                Time tobj = new Time();
5339                tobj.set(System.currentTimeMillis());
5340                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5341                sb.append(": ");
5342                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5343                sb.append(" since ");
5344                sb.append(msg);
5345                FileOutputStream fos = new FileOutputStream(tracesFile);
5346                fos.write(sb.toString().getBytes());
5347                if (app == null) {
5348                    fos.write("\n*** No application process!".getBytes());
5349                }
5350                fos.close();
5351                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5352            } catch (IOException e) {
5353                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5354                return;
5355            }
5356
5357            if (app != null) {
5358                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5359                firstPids.add(app.pid);
5360                dumpStackTraces(tracesPath, firstPids, null, null, null);
5361            }
5362
5363            File lastTracesFile = null;
5364            File curTracesFile = null;
5365            for (int i=9; i>=0; i--) {
5366                String name = String.format(Locale.US, "slow%02d.txt", i);
5367                curTracesFile = new File(tracesDir, name);
5368                if (curTracesFile.exists()) {
5369                    if (lastTracesFile != null) {
5370                        curTracesFile.renameTo(lastTracesFile);
5371                    } else {
5372                        curTracesFile.delete();
5373                    }
5374                }
5375                lastTracesFile = curTracesFile;
5376            }
5377            tracesFile.renameTo(curTracesFile);
5378            if (tracesTmp.exists()) {
5379                tracesTmp.renameTo(tracesFile);
5380            }
5381        } finally {
5382            StrictMode.setThreadPolicy(oldPolicy);
5383        }
5384    }
5385
5386    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5387        if (!mLaunchWarningShown) {
5388            mLaunchWarningShown = true;
5389            mUiHandler.post(new Runnable() {
5390                @Override
5391                public void run() {
5392                    synchronized (ActivityManagerService.this) {
5393                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5394                        d.show();
5395                        mUiHandler.postDelayed(new Runnable() {
5396                            @Override
5397                            public void run() {
5398                                synchronized (ActivityManagerService.this) {
5399                                    d.dismiss();
5400                                    mLaunchWarningShown = false;
5401                                }
5402                            }
5403                        }, 4000);
5404                    }
5405                }
5406            });
5407        }
5408    }
5409
5410    @Override
5411    public boolean clearApplicationUserData(final String packageName,
5412            final IPackageDataObserver observer, int userId) {
5413        enforceNotIsolatedCaller("clearApplicationUserData");
5414        int uid = Binder.getCallingUid();
5415        int pid = Binder.getCallingPid();
5416        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5417                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5418
5419
5420        long callingId = Binder.clearCallingIdentity();
5421        try {
5422            IPackageManager pm = AppGlobals.getPackageManager();
5423            int pkgUid = -1;
5424            synchronized(this) {
5425                if (getPackageManagerInternalLocked().canPackageBeWiped(
5426                        userId, packageName)) {
5427                    throw new SecurityException(
5428                            "Cannot clear data for a device owner or a profile owner");
5429                }
5430
5431                try {
5432                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5433                } catch (RemoteException e) {
5434                }
5435                if (pkgUid == -1) {
5436                    Slog.w(TAG, "Invalid packageName: " + packageName);
5437                    if (observer != null) {
5438                        try {
5439                            observer.onRemoveCompleted(packageName, false);
5440                        } catch (RemoteException e) {
5441                            Slog.i(TAG, "Observer no longer exists.");
5442                        }
5443                    }
5444                    return false;
5445                }
5446                if (uid == pkgUid || checkComponentPermission(
5447                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5448                        pid, uid, -1, true)
5449                        == PackageManager.PERMISSION_GRANTED) {
5450                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5451                } else {
5452                    throw new SecurityException("PID " + pid + " does not have permission "
5453                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5454                                    + " of package " + packageName);
5455                }
5456
5457                // Remove all tasks match the cleared application package and user
5458                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5459                    final TaskRecord tr = mRecentTasks.get(i);
5460                    final String taskPackageName =
5461                            tr.getBaseIntent().getComponent().getPackageName();
5462                    if (tr.userId != userId) continue;
5463                    if (!taskPackageName.equals(packageName)) continue;
5464                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5465                }
5466            }
5467
5468            final int pkgUidF = pkgUid;
5469            final int userIdF = userId;
5470            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5471                @Override
5472                public void onRemoveCompleted(String packageName, boolean succeeded)
5473                        throws RemoteException {
5474                    synchronized (ActivityManagerService.this) {
5475                        finishForceStopPackageLocked(packageName, pkgUidF);
5476                    }
5477
5478                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5479                            Uri.fromParts("package", packageName, null));
5480                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5481                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5482                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5483                            null, null, 0, null, null, null, null, false, false, userIdF);
5484
5485                    if (observer != null) {
5486                        observer.onRemoveCompleted(packageName, succeeded);
5487                    }
5488                }
5489            };
5490
5491            try {
5492                // Clear application user data
5493                pm.clearApplicationUserData(packageName, localObserver, userId);
5494
5495                synchronized(this) {
5496                    // Remove all permissions granted from/to this package
5497                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5498                }
5499
5500                // Remove all zen rules created by this package; revoke it's zen access.
5501                INotificationManager inm = NotificationManager.getService();
5502                inm.removeAutomaticZenRules(packageName);
5503                inm.setNotificationPolicyAccessGranted(packageName, false);
5504
5505            } catch (RemoteException e) {
5506            }
5507        } finally {
5508            Binder.restoreCallingIdentity(callingId);
5509        }
5510        return true;
5511    }
5512
5513    @Override
5514    public void killBackgroundProcesses(final String packageName, int userId) {
5515        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5516                != PackageManager.PERMISSION_GRANTED &&
5517                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5518                        != PackageManager.PERMISSION_GRANTED) {
5519            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5520                    + Binder.getCallingPid()
5521                    + ", uid=" + Binder.getCallingUid()
5522                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5523            Slog.w(TAG, msg);
5524            throw new SecurityException(msg);
5525        }
5526
5527        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5528                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5529        long callingId = Binder.clearCallingIdentity();
5530        try {
5531            IPackageManager pm = AppGlobals.getPackageManager();
5532            synchronized(this) {
5533                int appId = -1;
5534                try {
5535                    appId = UserHandle.getAppId(
5536                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5537                } catch (RemoteException e) {
5538                }
5539                if (appId == -1) {
5540                    Slog.w(TAG, "Invalid packageName: " + packageName);
5541                    return;
5542                }
5543                killPackageProcessesLocked(packageName, appId, userId,
5544                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5545            }
5546        } finally {
5547            Binder.restoreCallingIdentity(callingId);
5548        }
5549    }
5550
5551    @Override
5552    public void killAllBackgroundProcesses() {
5553        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5554                != PackageManager.PERMISSION_GRANTED) {
5555            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5556                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5557                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5558            Slog.w(TAG, msg);
5559            throw new SecurityException(msg);
5560        }
5561
5562        final long callingId = Binder.clearCallingIdentity();
5563        try {
5564            synchronized (this) {
5565                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5566                final int NP = mProcessNames.getMap().size();
5567                for (int ip = 0; ip < NP; ip++) {
5568                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5569                    final int NA = apps.size();
5570                    for (int ia = 0; ia < NA; ia++) {
5571                        final ProcessRecord app = apps.valueAt(ia);
5572                        if (app.persistent) {
5573                            // We don't kill persistent processes.
5574                            continue;
5575                        }
5576                        if (app.removed) {
5577                            procs.add(app);
5578                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5579                            app.removed = true;
5580                            procs.add(app);
5581                        }
5582                    }
5583                }
5584
5585                final int N = procs.size();
5586                for (int i = 0; i < N; i++) {
5587                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5588                }
5589
5590                mAllowLowerMemLevel = true;
5591
5592                updateOomAdjLocked();
5593                doLowMemReportIfNeededLocked(null);
5594            }
5595        } finally {
5596            Binder.restoreCallingIdentity(callingId);
5597        }
5598    }
5599
5600    /**
5601     * Kills all background processes, except those matching any of the
5602     * specified properties.
5603     *
5604     * @param minTargetSdk the target SDK version at or above which to preserve
5605     *                     processes, or {@code -1} to ignore the target SDK
5606     * @param maxProcState the process state at or below which to preserve
5607     *                     processes, or {@code -1} to ignore the process state
5608     */
5609    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5610        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5611                != PackageManager.PERMISSION_GRANTED) {
5612            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5613                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5614                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5615            Slog.w(TAG, msg);
5616            throw new SecurityException(msg);
5617        }
5618
5619        final long callingId = Binder.clearCallingIdentity();
5620        try {
5621            synchronized (this) {
5622                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5623                final int NP = mProcessNames.getMap().size();
5624                for (int ip = 0; ip < NP; ip++) {
5625                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5626                    final int NA = apps.size();
5627                    for (int ia = 0; ia < NA; ia++) {
5628                        final ProcessRecord app = apps.valueAt(ia);
5629                        if (app.removed) {
5630                            procs.add(app);
5631                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5632                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5633                            app.removed = true;
5634                            procs.add(app);
5635                        }
5636                    }
5637                }
5638
5639                final int N = procs.size();
5640                for (int i = 0; i < N; i++) {
5641                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5642                }
5643            }
5644        } finally {
5645            Binder.restoreCallingIdentity(callingId);
5646        }
5647    }
5648
5649    @Override
5650    public void forceStopPackage(final String packageName, int userId) {
5651        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5652                != PackageManager.PERMISSION_GRANTED) {
5653            String msg = "Permission Denial: forceStopPackage() from pid="
5654                    + Binder.getCallingPid()
5655                    + ", uid=" + Binder.getCallingUid()
5656                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5657            Slog.w(TAG, msg);
5658            throw new SecurityException(msg);
5659        }
5660        final int callingPid = Binder.getCallingPid();
5661        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5662                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5663        long callingId = Binder.clearCallingIdentity();
5664        try {
5665            IPackageManager pm = AppGlobals.getPackageManager();
5666            synchronized(this) {
5667                int[] users = userId == UserHandle.USER_ALL
5668                        ? mUserController.getUsers() : new int[] { userId };
5669                for (int user : users) {
5670                    int pkgUid = -1;
5671                    try {
5672                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5673                                user);
5674                    } catch (RemoteException e) {
5675                    }
5676                    if (pkgUid == -1) {
5677                        Slog.w(TAG, "Invalid packageName: " + packageName);
5678                        continue;
5679                    }
5680                    try {
5681                        pm.setPackageStoppedState(packageName, true, user);
5682                    } catch (RemoteException e) {
5683                    } catch (IllegalArgumentException e) {
5684                        Slog.w(TAG, "Failed trying to unstop package "
5685                                + packageName + ": " + e);
5686                    }
5687                    if (mUserController.isUserRunningLocked(user, 0)) {
5688                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5689                        finishForceStopPackageLocked(packageName, pkgUid);
5690                    }
5691                }
5692            }
5693        } finally {
5694            Binder.restoreCallingIdentity(callingId);
5695        }
5696    }
5697
5698    @Override
5699    public void addPackageDependency(String packageName) {
5700        synchronized (this) {
5701            int callingPid = Binder.getCallingPid();
5702            if (callingPid == Process.myPid()) {
5703                //  Yeah, um, no.
5704                return;
5705            }
5706            ProcessRecord proc;
5707            synchronized (mPidsSelfLocked) {
5708                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5709            }
5710            if (proc != null) {
5711                if (proc.pkgDeps == null) {
5712                    proc.pkgDeps = new ArraySet<String>(1);
5713                }
5714                proc.pkgDeps.add(packageName);
5715            }
5716        }
5717    }
5718
5719    /*
5720     * The pkg name and app id have to be specified.
5721     */
5722    @Override
5723    public void killApplication(String pkg, int appId, int userId, String reason) {
5724        if (pkg == null) {
5725            return;
5726        }
5727        // Make sure the uid is valid.
5728        if (appId < 0) {
5729            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5730            return;
5731        }
5732        int callerUid = Binder.getCallingUid();
5733        // Only the system server can kill an application
5734        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5735            // Post an aysnc message to kill the application
5736            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5737            msg.arg1 = appId;
5738            msg.arg2 = userId;
5739            Bundle bundle = new Bundle();
5740            bundle.putString("pkg", pkg);
5741            bundle.putString("reason", reason);
5742            msg.obj = bundle;
5743            mHandler.sendMessage(msg);
5744        } else {
5745            throw new SecurityException(callerUid + " cannot kill pkg: " +
5746                    pkg);
5747        }
5748    }
5749
5750    @Override
5751    public void closeSystemDialogs(String reason) {
5752        enforceNotIsolatedCaller("closeSystemDialogs");
5753
5754        final int pid = Binder.getCallingPid();
5755        final int uid = Binder.getCallingUid();
5756        final long origId = Binder.clearCallingIdentity();
5757        try {
5758            synchronized (this) {
5759                // Only allow this from foreground processes, so that background
5760                // applications can't abuse it to prevent system UI from being shown.
5761                if (uid >= Process.FIRST_APPLICATION_UID) {
5762                    ProcessRecord proc;
5763                    synchronized (mPidsSelfLocked) {
5764                        proc = mPidsSelfLocked.get(pid);
5765                    }
5766                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5767                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5768                                + " from background process " + proc);
5769                        return;
5770                    }
5771                }
5772                closeSystemDialogsLocked(reason);
5773            }
5774        } finally {
5775            Binder.restoreCallingIdentity(origId);
5776        }
5777    }
5778
5779    void closeSystemDialogsLocked(String reason) {
5780        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5781        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5782                | Intent.FLAG_RECEIVER_FOREGROUND);
5783        if (reason != null) {
5784            intent.putExtra("reason", reason);
5785        }
5786        mWindowManager.closeSystemDialogs(reason);
5787
5788        mStackSupervisor.closeSystemDialogsLocked();
5789
5790        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5791                AppOpsManager.OP_NONE, null, false, false,
5792                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5793    }
5794
5795    @Override
5796    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5797        enforceNotIsolatedCaller("getProcessMemoryInfo");
5798        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5799        for (int i=pids.length-1; i>=0; i--) {
5800            ProcessRecord proc;
5801            int oomAdj;
5802            synchronized (this) {
5803                synchronized (mPidsSelfLocked) {
5804                    proc = mPidsSelfLocked.get(pids[i]);
5805                    oomAdj = proc != null ? proc.setAdj : 0;
5806                }
5807            }
5808            infos[i] = new Debug.MemoryInfo();
5809            Debug.getMemoryInfo(pids[i], infos[i]);
5810            if (proc != null) {
5811                synchronized (this) {
5812                    if (proc.thread != null && proc.setAdj == oomAdj) {
5813                        // Record this for posterity if the process has been stable.
5814                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5815                                infos[i].getTotalUss(), false, proc.pkgList);
5816                    }
5817                }
5818            }
5819        }
5820        return infos;
5821    }
5822
5823    @Override
5824    public long[] getProcessPss(int[] pids) {
5825        enforceNotIsolatedCaller("getProcessPss");
5826        long[] pss = new long[pids.length];
5827        for (int i=pids.length-1; i>=0; i--) {
5828            ProcessRecord proc;
5829            int oomAdj;
5830            synchronized (this) {
5831                synchronized (mPidsSelfLocked) {
5832                    proc = mPidsSelfLocked.get(pids[i]);
5833                    oomAdj = proc != null ? proc.setAdj : 0;
5834                }
5835            }
5836            long[] tmpUss = new long[1];
5837            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5838            if (proc != null) {
5839                synchronized (this) {
5840                    if (proc.thread != null && proc.setAdj == oomAdj) {
5841                        // Record this for posterity if the process has been stable.
5842                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5843                    }
5844                }
5845            }
5846        }
5847        return pss;
5848    }
5849
5850    @Override
5851    public void killApplicationProcess(String processName, int uid) {
5852        if (processName == null) {
5853            return;
5854        }
5855
5856        int callerUid = Binder.getCallingUid();
5857        // Only the system server can kill an application
5858        if (callerUid == Process.SYSTEM_UID) {
5859            synchronized (this) {
5860                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5861                if (app != null && app.thread != null) {
5862                    try {
5863                        app.thread.scheduleSuicide();
5864                    } catch (RemoteException e) {
5865                        // If the other end already died, then our work here is done.
5866                    }
5867                } else {
5868                    Slog.w(TAG, "Process/uid not found attempting kill of "
5869                            + processName + " / " + uid);
5870                }
5871            }
5872        } else {
5873            throw new SecurityException(callerUid + " cannot kill app process: " +
5874                    processName);
5875        }
5876    }
5877
5878    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5879        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5880                false, true, false, false, UserHandle.getUserId(uid), reason);
5881    }
5882
5883    private void finishForceStopPackageLocked(final String packageName, int uid) {
5884        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5885                Uri.fromParts("package", packageName, null));
5886        if (!mProcessesReady) {
5887            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5888                    | Intent.FLAG_RECEIVER_FOREGROUND);
5889        }
5890        intent.putExtra(Intent.EXTRA_UID, uid);
5891        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5892        broadcastIntentLocked(null, null, intent,
5893                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5894                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5895    }
5896
5897
5898    private final boolean killPackageProcessesLocked(String packageName, int appId,
5899            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5900            boolean doit, boolean evenPersistent, String reason) {
5901        ArrayList<ProcessRecord> procs = new ArrayList<>();
5902
5903        // Remove all processes this package may have touched: all with the
5904        // same UID (except for the system or root user), and all whose name
5905        // matches the package name.
5906        final int NP = mProcessNames.getMap().size();
5907        for (int ip=0; ip<NP; ip++) {
5908            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5909            final int NA = apps.size();
5910            for (int ia=0; ia<NA; ia++) {
5911                ProcessRecord app = apps.valueAt(ia);
5912                if (app.persistent && !evenPersistent) {
5913                    // we don't kill persistent processes
5914                    continue;
5915                }
5916                if (app.removed) {
5917                    if (doit) {
5918                        procs.add(app);
5919                    }
5920                    continue;
5921                }
5922
5923                // Skip process if it doesn't meet our oom adj requirement.
5924                if (app.setAdj < minOomAdj) {
5925                    continue;
5926                }
5927
5928                // If no package is specified, we call all processes under the
5929                // give user id.
5930                if (packageName == null) {
5931                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5932                        continue;
5933                    }
5934                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5935                        continue;
5936                    }
5937                // Package has been specified, we want to hit all processes
5938                // that match it.  We need to qualify this by the processes
5939                // that are running under the specified app and user ID.
5940                } else {
5941                    final boolean isDep = app.pkgDeps != null
5942                            && app.pkgDeps.contains(packageName);
5943                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5944                        continue;
5945                    }
5946                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5947                        continue;
5948                    }
5949                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5950                        continue;
5951                    }
5952                }
5953
5954                // Process has passed all conditions, kill it!
5955                if (!doit) {
5956                    return true;
5957                }
5958                app.removed = true;
5959                procs.add(app);
5960            }
5961        }
5962
5963        int N = procs.size();
5964        for (int i=0; i<N; i++) {
5965            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5966        }
5967        updateOomAdjLocked();
5968        return N > 0;
5969    }
5970
5971    private void cleanupDisabledPackageComponentsLocked(
5972            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5973
5974        Set<String> disabledClasses = null;
5975        boolean packageDisabled = false;
5976        IPackageManager pm = AppGlobals.getPackageManager();
5977
5978        if (changedClasses == null) {
5979            // Nothing changed...
5980            return;
5981        }
5982
5983        // Determine enable/disable state of the package and its components.
5984        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5985        for (int i = changedClasses.length - 1; i >= 0; i--) {
5986            final String changedClass = changedClasses[i];
5987
5988            if (changedClass.equals(packageName)) {
5989                try {
5990                    // Entire package setting changed
5991                    enabled = pm.getApplicationEnabledSetting(packageName,
5992                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5993                } catch (Exception e) {
5994                    // No such package/component; probably racing with uninstall.  In any
5995                    // event it means we have nothing further to do here.
5996                    return;
5997                }
5998                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5999                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6000                if (packageDisabled) {
6001                    // Entire package is disabled.
6002                    // No need to continue to check component states.
6003                    disabledClasses = null;
6004                    break;
6005                }
6006            } else {
6007                try {
6008                    enabled = pm.getComponentEnabledSetting(
6009                            new ComponentName(packageName, changedClass),
6010                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6011                } catch (Exception e) {
6012                    // As above, probably racing with uninstall.
6013                    return;
6014                }
6015                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6016                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6017                    if (disabledClasses == null) {
6018                        disabledClasses = new ArraySet<>(changedClasses.length);
6019                    }
6020                    disabledClasses.add(changedClass);
6021                }
6022            }
6023        }
6024
6025        if (!packageDisabled && disabledClasses == null) {
6026            // Nothing to do here...
6027            return;
6028        }
6029
6030        // Clean-up disabled activities.
6031        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6032                packageName, disabledClasses, true, false, userId) && mBooted) {
6033            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6034            mStackSupervisor.scheduleIdleLocked();
6035        }
6036
6037        // Clean-up disabled tasks
6038        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6039
6040        // Clean-up disabled services.
6041        mServices.bringDownDisabledPackageServicesLocked(
6042                packageName, disabledClasses, userId, false, killProcess, true);
6043
6044        // Clean-up disabled providers.
6045        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6046        mProviderMap.collectPackageProvidersLocked(
6047                packageName, disabledClasses, true, false, userId, providers);
6048        for (int i = providers.size() - 1; i >= 0; i--) {
6049            removeDyingProviderLocked(null, providers.get(i), true);
6050        }
6051
6052        // Clean-up disabled broadcast receivers.
6053        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6054            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6055                    packageName, disabledClasses, userId, true);
6056        }
6057
6058    }
6059
6060    final boolean clearBroadcastQueueForUserLocked(int userId) {
6061        boolean didSomething = false;
6062        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6063            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6064                    null, null, userId, true);
6065        }
6066        return didSomething;
6067    }
6068
6069    final boolean forceStopPackageLocked(String packageName, int appId,
6070            boolean callerWillRestart, boolean purgeCache, boolean doit,
6071            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6072        int i;
6073
6074        if (userId == UserHandle.USER_ALL && packageName == null) {
6075            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6076        }
6077
6078        if (appId < 0 && packageName != null) {
6079            try {
6080                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6081                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6082            } catch (RemoteException e) {
6083            }
6084        }
6085
6086        if (doit) {
6087            if (packageName != null) {
6088                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6089                        + " user=" + userId + ": " + reason);
6090            } else {
6091                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6092            }
6093
6094            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6095        }
6096
6097        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6098                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6099                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6100
6101        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6102                packageName, null, doit, evenPersistent, userId)) {
6103            if (!doit) {
6104                return true;
6105            }
6106            didSomething = true;
6107        }
6108
6109        if (mServices.bringDownDisabledPackageServicesLocked(
6110                packageName, null, userId, evenPersistent, true, doit)) {
6111            if (!doit) {
6112                return true;
6113            }
6114            didSomething = true;
6115        }
6116
6117        if (packageName == null) {
6118            // Remove all sticky broadcasts from this user.
6119            mStickyBroadcasts.remove(userId);
6120        }
6121
6122        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6123        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6124                userId, providers)) {
6125            if (!doit) {
6126                return true;
6127            }
6128            didSomething = true;
6129        }
6130        for (i = providers.size() - 1; i >= 0; i--) {
6131            removeDyingProviderLocked(null, providers.get(i), true);
6132        }
6133
6134        // Remove transient permissions granted from/to this package/user
6135        removeUriPermissionsForPackageLocked(packageName, userId, false);
6136
6137        if (doit) {
6138            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6139                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6140                        packageName, null, userId, doit);
6141            }
6142        }
6143
6144        if (packageName == null || uninstalling) {
6145            // Remove pending intents.  For now we only do this when force
6146            // stopping users, because we have some problems when doing this
6147            // for packages -- app widgets are not currently cleaned up for
6148            // such packages, so they can be left with bad pending intents.
6149            if (mIntentSenderRecords.size() > 0) {
6150                Iterator<WeakReference<PendingIntentRecord>> it
6151                        = mIntentSenderRecords.values().iterator();
6152                while (it.hasNext()) {
6153                    WeakReference<PendingIntentRecord> wpir = it.next();
6154                    if (wpir == null) {
6155                        it.remove();
6156                        continue;
6157                    }
6158                    PendingIntentRecord pir = wpir.get();
6159                    if (pir == null) {
6160                        it.remove();
6161                        continue;
6162                    }
6163                    if (packageName == null) {
6164                        // Stopping user, remove all objects for the user.
6165                        if (pir.key.userId != userId) {
6166                            // Not the same user, skip it.
6167                            continue;
6168                        }
6169                    } else {
6170                        if (UserHandle.getAppId(pir.uid) != appId) {
6171                            // Different app id, skip it.
6172                            continue;
6173                        }
6174                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6175                            // Different user, skip it.
6176                            continue;
6177                        }
6178                        if (!pir.key.packageName.equals(packageName)) {
6179                            // Different package, skip it.
6180                            continue;
6181                        }
6182                    }
6183                    if (!doit) {
6184                        return true;
6185                    }
6186                    didSomething = true;
6187                    it.remove();
6188                    pir.canceled = true;
6189                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6190                        pir.key.activity.pendingResults.remove(pir.ref);
6191                    }
6192                }
6193            }
6194        }
6195
6196        if (doit) {
6197            if (purgeCache && packageName != null) {
6198                AttributeCache ac = AttributeCache.instance();
6199                if (ac != null) {
6200                    ac.removePackage(packageName);
6201                }
6202            }
6203            if (mBooted) {
6204                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6205                mStackSupervisor.scheduleIdleLocked();
6206            }
6207        }
6208
6209        return didSomething;
6210    }
6211
6212    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6213        ProcessRecord old = mProcessNames.remove(name, uid);
6214        if (old != null) {
6215            old.uidRecord.numProcs--;
6216            if (old.uidRecord.numProcs == 0) {
6217                // No more processes using this uid, tell clients it is gone.
6218                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6219                        "No more processes in " + old.uidRecord);
6220                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6221                mActiveUids.remove(uid);
6222                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6223            }
6224            old.uidRecord = null;
6225        }
6226        mIsolatedProcesses.remove(uid);
6227        return old;
6228    }
6229
6230    private final void addProcessNameLocked(ProcessRecord proc) {
6231        // We shouldn't already have a process under this name, but just in case we
6232        // need to clean up whatever may be there now.
6233        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6234        if (old == proc && proc.persistent) {
6235            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6236            Slog.w(TAG, "Re-adding persistent process " + proc);
6237        } else if (old != null) {
6238            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6239        }
6240        UidRecord uidRec = mActiveUids.get(proc.uid);
6241        if (uidRec == null) {
6242            uidRec = new UidRecord(proc.uid);
6243            // This is the first appearance of the uid, report it now!
6244            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6245                    "Creating new process uid: " + uidRec);
6246            mActiveUids.put(proc.uid, uidRec);
6247            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6248            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6249        }
6250        proc.uidRecord = uidRec;
6251        uidRec.numProcs++;
6252        mProcessNames.put(proc.processName, proc.uid, proc);
6253        if (proc.isolated) {
6254            mIsolatedProcesses.put(proc.uid, proc);
6255        }
6256    }
6257
6258    boolean removeProcessLocked(ProcessRecord app,
6259            boolean callerWillRestart, boolean allowRestart, String reason) {
6260        final String name = app.processName;
6261        final int uid = app.uid;
6262        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6263            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6264
6265        ProcessRecord old = mProcessNames.get(name, uid);
6266        if (old != app) {
6267            // This process is no longer active, so nothing to do.
6268            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6269            return false;
6270        }
6271        removeProcessNameLocked(name, uid);
6272        if (mHeavyWeightProcess == app) {
6273            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6274                    mHeavyWeightProcess.userId, 0));
6275            mHeavyWeightProcess = null;
6276        }
6277        boolean needRestart = false;
6278        if (app.pid > 0 && app.pid != MY_PID) {
6279            int pid = app.pid;
6280            synchronized (mPidsSelfLocked) {
6281                mPidsSelfLocked.remove(pid);
6282                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6283            }
6284            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6285            if (app.isolated) {
6286                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6287            }
6288            boolean willRestart = false;
6289            if (app.persistent && !app.isolated) {
6290                if (!callerWillRestart) {
6291                    willRestart = true;
6292                } else {
6293                    needRestart = true;
6294                }
6295            }
6296            app.kill(reason, true);
6297            handleAppDiedLocked(app, willRestart, allowRestart);
6298            if (willRestart) {
6299                removeLruProcessLocked(app);
6300                addAppLocked(app.info, false, null /* ABI override */);
6301            }
6302        } else {
6303            mRemovedProcesses.add(app);
6304        }
6305
6306        return needRestart;
6307    }
6308
6309    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6310        cleanupAppInLaunchingProvidersLocked(app, true);
6311        removeProcessLocked(app, false, true, "timeout publishing content providers");
6312    }
6313
6314    private final void processStartTimedOutLocked(ProcessRecord app) {
6315        final int pid = app.pid;
6316        boolean gone = false;
6317        synchronized (mPidsSelfLocked) {
6318            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6319            if (knownApp != null && knownApp.thread == null) {
6320                mPidsSelfLocked.remove(pid);
6321                gone = true;
6322            }
6323        }
6324
6325        if (gone) {
6326            Slog.w(TAG, "Process " + app + " failed to attach");
6327            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6328                    pid, app.uid, app.processName);
6329            removeProcessNameLocked(app.processName, app.uid);
6330            if (mHeavyWeightProcess == app) {
6331                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6332                        mHeavyWeightProcess.userId, 0));
6333                mHeavyWeightProcess = null;
6334            }
6335            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6336            if (app.isolated) {
6337                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6338            }
6339            // Take care of any launching providers waiting for this process.
6340            cleanupAppInLaunchingProvidersLocked(app, true);
6341            // Take care of any services that are waiting for the process.
6342            mServices.processStartTimedOutLocked(app);
6343            app.kill("start timeout", true);
6344            removeLruProcessLocked(app);
6345            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6346                Slog.w(TAG, "Unattached app died before backup, skipping");
6347                try {
6348                    IBackupManager bm = IBackupManager.Stub.asInterface(
6349                            ServiceManager.getService(Context.BACKUP_SERVICE));
6350                    bm.agentDisconnected(app.info.packageName);
6351                } catch (RemoteException e) {
6352                    // Can't happen; the backup manager is local
6353                }
6354            }
6355            if (isPendingBroadcastProcessLocked(pid)) {
6356                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6357                skipPendingBroadcastLocked(pid);
6358            }
6359        } else {
6360            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6361        }
6362    }
6363
6364    private final boolean attachApplicationLocked(IApplicationThread thread,
6365            int pid) {
6366
6367        // Find the application record that is being attached...  either via
6368        // the pid if we are running in multiple processes, or just pull the
6369        // next app record if we are emulating process with anonymous threads.
6370        ProcessRecord app;
6371        if (pid != MY_PID && pid >= 0) {
6372            synchronized (mPidsSelfLocked) {
6373                app = mPidsSelfLocked.get(pid);
6374            }
6375        } else {
6376            app = null;
6377        }
6378
6379        if (app == null) {
6380            Slog.w(TAG, "No pending application record for pid " + pid
6381                    + " (IApplicationThread " + thread + "); dropping process");
6382            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6383            if (pid > 0 && pid != MY_PID) {
6384                Process.killProcessQuiet(pid);
6385                //TODO: killProcessGroup(app.info.uid, pid);
6386            } else {
6387                try {
6388                    thread.scheduleExit();
6389                } catch (Exception e) {
6390                    // Ignore exceptions.
6391                }
6392            }
6393            return false;
6394        }
6395
6396        // If this application record is still attached to a previous
6397        // process, clean it up now.
6398        if (app.thread != null) {
6399            handleAppDiedLocked(app, true, true);
6400        }
6401
6402        // Tell the process all about itself.
6403
6404        if (DEBUG_ALL) Slog.v(
6405                TAG, "Binding process pid " + pid + " to record " + app);
6406
6407        final String processName = app.processName;
6408        try {
6409            AppDeathRecipient adr = new AppDeathRecipient(
6410                    app, pid, thread);
6411            thread.asBinder().linkToDeath(adr, 0);
6412            app.deathRecipient = adr;
6413        } catch (RemoteException e) {
6414            app.resetPackageList(mProcessStats);
6415            startProcessLocked(app, "link fail", processName);
6416            return false;
6417        }
6418
6419        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6420
6421        app.makeActive(thread, mProcessStats);
6422        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6423        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6424        app.forcingToForeground = null;
6425        updateProcessForegroundLocked(app, false, false);
6426        app.hasShownUi = false;
6427        app.debugging = false;
6428        app.cached = false;
6429        app.killedByAm = false;
6430
6431        // We carefully use the same state that PackageManager uses for
6432        // filtering, since we use this flag to decide if we need to install
6433        // providers when user is unlocked later
6434        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6435
6436        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6437
6438        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6439        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6440
6441        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6442            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6443            msg.obj = app;
6444            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6445        }
6446
6447        if (!normalMode) {
6448            Slog.i(TAG, "Launching preboot mode app: " + app);
6449        }
6450
6451        if (DEBUG_ALL) Slog.v(
6452            TAG, "New app record " + app
6453            + " thread=" + thread.asBinder() + " pid=" + pid);
6454        try {
6455            int testMode = IApplicationThread.DEBUG_OFF;
6456            if (mDebugApp != null && mDebugApp.equals(processName)) {
6457                testMode = mWaitForDebugger
6458                    ? IApplicationThread.DEBUG_WAIT
6459                    : IApplicationThread.DEBUG_ON;
6460                app.debugging = true;
6461                if (mDebugTransient) {
6462                    mDebugApp = mOrigDebugApp;
6463                    mWaitForDebugger = mOrigWaitForDebugger;
6464                }
6465            }
6466            String profileFile = app.instrumentationProfileFile;
6467            ParcelFileDescriptor profileFd = null;
6468            int samplingInterval = 0;
6469            boolean profileAutoStop = false;
6470            if (mProfileApp != null && mProfileApp.equals(processName)) {
6471                mProfileProc = app;
6472                profileFile = mProfileFile;
6473                profileFd = mProfileFd;
6474                samplingInterval = mSamplingInterval;
6475                profileAutoStop = mAutoStopProfiler;
6476            }
6477            boolean enableTrackAllocation = false;
6478            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6479                enableTrackAllocation = true;
6480                mTrackAllocationApp = null;
6481            }
6482
6483            // If the app is being launched for restore or full backup, set it up specially
6484            boolean isRestrictedBackupMode = false;
6485            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6486                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6487                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6488                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6489                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6490            }
6491
6492            if (app.instrumentationClass != null) {
6493                notifyPackageUse(app.instrumentationClass.getPackageName(),
6494                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6495            }
6496            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6497                    + processName + " with config " + mConfiguration);
6498            ApplicationInfo appInfo = app.instrumentationInfo != null
6499                    ? app.instrumentationInfo : app.info;
6500            app.compat = compatibilityInfoForPackageLocked(appInfo);
6501            if (profileFd != null) {
6502                profileFd = profileFd.dup();
6503            }
6504            ProfilerInfo profilerInfo = profileFile == null ? null
6505                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6506            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6507                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6508                    app.instrumentationUiAutomationConnection, testMode,
6509                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6510                    isRestrictedBackupMode || !normalMode, app.persistent,
6511                    new Configuration(mConfiguration), app.compat,
6512                    getCommonServicesLocked(app.isolated),
6513                    mCoreSettingsObserver.getCoreSettingsLocked());
6514            updateLruProcessLocked(app, false, null);
6515            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6516        } catch (Exception e) {
6517            // todo: Yikes!  What should we do?  For now we will try to
6518            // start another process, but that could easily get us in
6519            // an infinite loop of restarting processes...
6520            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6521
6522            app.resetPackageList(mProcessStats);
6523            app.unlinkDeathRecipient();
6524            startProcessLocked(app, "bind fail", processName);
6525            return false;
6526        }
6527
6528        // Remove this record from the list of starting applications.
6529        mPersistentStartingProcesses.remove(app);
6530        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6531                "Attach application locked removing on hold: " + app);
6532        mProcessesOnHold.remove(app);
6533
6534        boolean badApp = false;
6535        boolean didSomething = false;
6536
6537        // See if the top visible activity is waiting to run in this process...
6538        if (normalMode) {
6539            try {
6540                if (mStackSupervisor.attachApplicationLocked(app)) {
6541                    didSomething = true;
6542                }
6543            } catch (Exception e) {
6544                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6545                badApp = true;
6546            }
6547        }
6548
6549        // Find any services that should be running in this process...
6550        if (!badApp) {
6551            try {
6552                didSomething |= mServices.attachApplicationLocked(app, processName);
6553            } catch (Exception e) {
6554                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6555                badApp = true;
6556            }
6557        }
6558
6559        // Check if a next-broadcast receiver is in this process...
6560        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6561            try {
6562                didSomething |= sendPendingBroadcastsLocked(app);
6563            } catch (Exception e) {
6564                // If the app died trying to launch the receiver we declare it 'bad'
6565                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6566                badApp = true;
6567            }
6568        }
6569
6570        // Check whether the next backup agent is in this process...
6571        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6572            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6573                    "New app is backup target, launching agent for " + app);
6574            notifyPackageUse(mBackupTarget.appInfo.packageName,
6575                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6576            try {
6577                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6578                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6579                        mBackupTarget.backupMode);
6580            } catch (Exception e) {
6581                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6582                badApp = true;
6583            }
6584        }
6585
6586        if (badApp) {
6587            app.kill("error during init", true);
6588            handleAppDiedLocked(app, false, true);
6589            return false;
6590        }
6591
6592        if (!didSomething) {
6593            updateOomAdjLocked();
6594        }
6595
6596        return true;
6597    }
6598
6599    @Override
6600    public final void attachApplication(IApplicationThread thread) {
6601        synchronized (this) {
6602            int callingPid = Binder.getCallingPid();
6603            final long origId = Binder.clearCallingIdentity();
6604            attachApplicationLocked(thread, callingPid);
6605            Binder.restoreCallingIdentity(origId);
6606        }
6607    }
6608
6609    @Override
6610    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6611        final long origId = Binder.clearCallingIdentity();
6612        synchronized (this) {
6613            ActivityStack stack = ActivityRecord.getStackLocked(token);
6614            if (stack != null) {
6615                ActivityRecord r =
6616                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6617                if (stopProfiling) {
6618                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6619                        try {
6620                            mProfileFd.close();
6621                        } catch (IOException e) {
6622                        }
6623                        clearProfilerLocked();
6624                    }
6625                }
6626            }
6627        }
6628        Binder.restoreCallingIdentity(origId);
6629    }
6630
6631    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6632        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6633                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6634    }
6635
6636    void enableScreenAfterBoot() {
6637        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6638                SystemClock.uptimeMillis());
6639        mWindowManager.enableScreenAfterBoot();
6640
6641        synchronized (this) {
6642            updateEventDispatchingLocked();
6643        }
6644    }
6645
6646    @Override
6647    public void showBootMessage(final CharSequence msg, final boolean always) {
6648        if (Binder.getCallingUid() != Process.myUid()) {
6649            // These days only the core system can call this, so apps can't get in
6650            // the way of what we show about running them.
6651        }
6652        mWindowManager.showBootMessage(msg, always);
6653    }
6654
6655    @Override
6656    public void keyguardWaitingForActivityDrawn() {
6657        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6658        final long token = Binder.clearCallingIdentity();
6659        try {
6660            synchronized (this) {
6661                if (DEBUG_LOCKSCREEN) logLockScreen("");
6662                mWindowManager.keyguardWaitingForActivityDrawn();
6663                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6664                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6665                    updateSleepIfNeededLocked();
6666                }
6667            }
6668        } finally {
6669            Binder.restoreCallingIdentity(token);
6670        }
6671    }
6672
6673    @Override
6674    public void keyguardGoingAway(int flags) {
6675        enforceNotIsolatedCaller("keyguardGoingAway");
6676        final long token = Binder.clearCallingIdentity();
6677        try {
6678            synchronized (this) {
6679                if (DEBUG_LOCKSCREEN) logLockScreen("");
6680                mWindowManager.keyguardGoingAway(flags);
6681                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6682                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6683                    updateSleepIfNeededLocked();
6684
6685                    // Some stack visibility might change (e.g. docked stack)
6686                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6687                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6688                }
6689            }
6690        } finally {
6691            Binder.restoreCallingIdentity(token);
6692        }
6693    }
6694
6695    final void finishBooting() {
6696        synchronized (this) {
6697            if (!mBootAnimationComplete) {
6698                mCallFinishBooting = true;
6699                return;
6700            }
6701            mCallFinishBooting = false;
6702        }
6703
6704        ArraySet<String> completedIsas = new ArraySet<String>();
6705        for (String abi : Build.SUPPORTED_ABIS) {
6706            Process.establishZygoteConnectionForAbi(abi);
6707            final String instructionSet = VMRuntime.getInstructionSet(abi);
6708            if (!completedIsas.contains(instructionSet)) {
6709                try {
6710                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6711                } catch (InstallerException e) {
6712                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6713                            e.getMessage() +")");
6714                }
6715                completedIsas.add(instructionSet);
6716            }
6717        }
6718
6719        IntentFilter pkgFilter = new IntentFilter();
6720        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6721        pkgFilter.addDataScheme("package");
6722        mContext.registerReceiver(new BroadcastReceiver() {
6723            @Override
6724            public void onReceive(Context context, Intent intent) {
6725                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6726                if (pkgs != null) {
6727                    for (String pkg : pkgs) {
6728                        synchronized (ActivityManagerService.this) {
6729                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6730                                    0, "query restart")) {
6731                                setResultCode(Activity.RESULT_OK);
6732                                return;
6733                            }
6734                        }
6735                    }
6736                }
6737            }
6738        }, pkgFilter);
6739
6740        IntentFilter dumpheapFilter = new IntentFilter();
6741        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6742        mContext.registerReceiver(new BroadcastReceiver() {
6743            @Override
6744            public void onReceive(Context context, Intent intent) {
6745                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6746                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6747                } else {
6748                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6749                }
6750            }
6751        }, dumpheapFilter);
6752
6753        // Let system services know.
6754        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6755
6756        synchronized (this) {
6757            // Ensure that any processes we had put on hold are now started
6758            // up.
6759            final int NP = mProcessesOnHold.size();
6760            if (NP > 0) {
6761                ArrayList<ProcessRecord> procs =
6762                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6763                for (int ip=0; ip<NP; ip++) {
6764                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6765                            + procs.get(ip));
6766                    startProcessLocked(procs.get(ip), "on-hold", null);
6767                }
6768            }
6769
6770            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6771                // Start looking for apps that are abusing wake locks.
6772                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6773                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6774                // Tell anyone interested that we are done booting!
6775                SystemProperties.set("sys.boot_completed", "1");
6776
6777                // And trigger dev.bootcomplete if we are not showing encryption progress
6778                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6779                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6780                    SystemProperties.set("dev.bootcomplete", "1");
6781                }
6782                mUserController.sendBootCompletedLocked(
6783                        new IIntentReceiver.Stub() {
6784                            @Override
6785                            public void performReceive(Intent intent, int resultCode,
6786                                    String data, Bundle extras, boolean ordered,
6787                                    boolean sticky, int sendingUser) {
6788                                synchronized (ActivityManagerService.this) {
6789                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6790                                            true, false);
6791                                }
6792                            }
6793                        });
6794                scheduleStartProfilesLocked();
6795            }
6796        }
6797    }
6798
6799    @Override
6800    public void bootAnimationComplete() {
6801        final boolean callFinishBooting;
6802        synchronized (this) {
6803            callFinishBooting = mCallFinishBooting;
6804            mBootAnimationComplete = true;
6805        }
6806        if (callFinishBooting) {
6807            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6808            finishBooting();
6809            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6810        }
6811    }
6812
6813    final void ensureBootCompleted() {
6814        boolean booting;
6815        boolean enableScreen;
6816        synchronized (this) {
6817            booting = mBooting;
6818            mBooting = false;
6819            enableScreen = !mBooted;
6820            mBooted = true;
6821        }
6822
6823        if (booting) {
6824            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6825            finishBooting();
6826            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6827        }
6828
6829        if (enableScreen) {
6830            enableScreenAfterBoot();
6831        }
6832    }
6833
6834    @Override
6835    public final void activityResumed(IBinder token) {
6836        final long origId = Binder.clearCallingIdentity();
6837        synchronized(this) {
6838            ActivityStack stack = ActivityRecord.getStackLocked(token);
6839            if (stack != null) {
6840                stack.activityResumedLocked(token);
6841            }
6842        }
6843        Binder.restoreCallingIdentity(origId);
6844    }
6845
6846    @Override
6847    public final void activityPaused(IBinder token) {
6848        final long origId = Binder.clearCallingIdentity();
6849        synchronized(this) {
6850            ActivityStack stack = ActivityRecord.getStackLocked(token);
6851            if (stack != null) {
6852                stack.activityPausedLocked(token, false);
6853            }
6854        }
6855        Binder.restoreCallingIdentity(origId);
6856    }
6857
6858    @Override
6859    public final void activityStopped(IBinder token, Bundle icicle,
6860            PersistableBundle persistentState, CharSequence description) {
6861        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6862
6863        // Refuse possible leaked file descriptors
6864        if (icicle != null && icicle.hasFileDescriptors()) {
6865            throw new IllegalArgumentException("File descriptors passed in Bundle");
6866        }
6867
6868        final long origId = Binder.clearCallingIdentity();
6869
6870        synchronized (this) {
6871            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6872            if (r != null) {
6873                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6874            }
6875        }
6876
6877        trimApplications();
6878
6879        Binder.restoreCallingIdentity(origId);
6880    }
6881
6882    @Override
6883    public final void activityDestroyed(IBinder token) {
6884        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6885        synchronized (this) {
6886            ActivityStack stack = ActivityRecord.getStackLocked(token);
6887            if (stack != null) {
6888                stack.activityDestroyedLocked(token, "activityDestroyed");
6889            }
6890        }
6891    }
6892
6893    @Override
6894    public final void activityRelaunched(IBinder token) {
6895        final long origId = Binder.clearCallingIdentity();
6896        synchronized (this) {
6897            mStackSupervisor.activityRelaunchedLocked(token);
6898        }
6899        Binder.restoreCallingIdentity(origId);
6900    }
6901
6902    @Override
6903    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6904            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6905        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6906                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6907        synchronized (this) {
6908            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6909            if (record == null) {
6910                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6911                        + "found for: " + token);
6912            }
6913            record.setSizeConfigurations(horizontalSizeConfiguration,
6914                    verticalSizeConfigurations, smallestSizeConfigurations);
6915        }
6916    }
6917
6918    @Override
6919    public final void backgroundResourcesReleased(IBinder token) {
6920        final long origId = Binder.clearCallingIdentity();
6921        try {
6922            synchronized (this) {
6923                ActivityStack stack = ActivityRecord.getStackLocked(token);
6924                if (stack != null) {
6925                    stack.backgroundResourcesReleased();
6926                }
6927            }
6928        } finally {
6929            Binder.restoreCallingIdentity(origId);
6930        }
6931    }
6932
6933    @Override
6934    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6935        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6936    }
6937
6938    @Override
6939    public final void notifyEnterAnimationComplete(IBinder token) {
6940        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6941    }
6942
6943    @Override
6944    public String getCallingPackage(IBinder token) {
6945        synchronized (this) {
6946            ActivityRecord r = getCallingRecordLocked(token);
6947            return r != null ? r.info.packageName : null;
6948        }
6949    }
6950
6951    @Override
6952    public ComponentName getCallingActivity(IBinder token) {
6953        synchronized (this) {
6954            ActivityRecord r = getCallingRecordLocked(token);
6955            return r != null ? r.intent.getComponent() : null;
6956        }
6957    }
6958
6959    private ActivityRecord getCallingRecordLocked(IBinder token) {
6960        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6961        if (r == null) {
6962            return null;
6963        }
6964        return r.resultTo;
6965    }
6966
6967    @Override
6968    public ComponentName getActivityClassForToken(IBinder token) {
6969        synchronized(this) {
6970            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6971            if (r == null) {
6972                return null;
6973            }
6974            return r.intent.getComponent();
6975        }
6976    }
6977
6978    @Override
6979    public String getPackageForToken(IBinder token) {
6980        synchronized(this) {
6981            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6982            if (r == null) {
6983                return null;
6984            }
6985            return r.packageName;
6986        }
6987    }
6988
6989    @Override
6990    public boolean isRootVoiceInteraction(IBinder token) {
6991        synchronized(this) {
6992            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6993            if (r == null) {
6994                return false;
6995            }
6996            return r.rootVoiceInteraction;
6997        }
6998    }
6999
7000    @Override
7001    public IIntentSender getIntentSender(int type,
7002            String packageName, IBinder token, String resultWho,
7003            int requestCode, Intent[] intents, String[] resolvedTypes,
7004            int flags, Bundle bOptions, int userId) {
7005        enforceNotIsolatedCaller("getIntentSender");
7006        // Refuse possible leaked file descriptors
7007        if (intents != null) {
7008            if (intents.length < 1) {
7009                throw new IllegalArgumentException("Intents array length must be >= 1");
7010            }
7011            for (int i=0; i<intents.length; i++) {
7012                Intent intent = intents[i];
7013                if (intent != null) {
7014                    if (intent.hasFileDescriptors()) {
7015                        throw new IllegalArgumentException("File descriptors passed in Intent");
7016                    }
7017                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7018                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7019                        throw new IllegalArgumentException(
7020                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7021                    }
7022                    intents[i] = new Intent(intent);
7023                }
7024            }
7025            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7026                throw new IllegalArgumentException(
7027                        "Intent array length does not match resolvedTypes length");
7028            }
7029        }
7030        if (bOptions != null) {
7031            if (bOptions.hasFileDescriptors()) {
7032                throw new IllegalArgumentException("File descriptors passed in options");
7033            }
7034        }
7035
7036        synchronized(this) {
7037            int callingUid = Binder.getCallingUid();
7038            int origUserId = userId;
7039            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7040                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7041                    ALLOW_NON_FULL, "getIntentSender", null);
7042            if (origUserId == UserHandle.USER_CURRENT) {
7043                // We don't want to evaluate this until the pending intent is
7044                // actually executed.  However, we do want to always do the
7045                // security checking for it above.
7046                userId = UserHandle.USER_CURRENT;
7047            }
7048            try {
7049                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7050                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7051                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7052                    if (!UserHandle.isSameApp(callingUid, uid)) {
7053                        String msg = "Permission Denial: getIntentSender() from pid="
7054                            + Binder.getCallingPid()
7055                            + ", uid=" + Binder.getCallingUid()
7056                            + ", (need uid=" + uid + ")"
7057                            + " is not allowed to send as package " + packageName;
7058                        Slog.w(TAG, msg);
7059                        throw new SecurityException(msg);
7060                    }
7061                }
7062
7063                return getIntentSenderLocked(type, packageName, callingUid, userId,
7064                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7065
7066            } catch (RemoteException e) {
7067                throw new SecurityException(e);
7068            }
7069        }
7070    }
7071
7072    IIntentSender getIntentSenderLocked(int type, String packageName,
7073            int callingUid, int userId, IBinder token, String resultWho,
7074            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7075            Bundle bOptions) {
7076        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7077        ActivityRecord activity = null;
7078        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7079            activity = ActivityRecord.isInStackLocked(token);
7080            if (activity == null) {
7081                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7082                return null;
7083            }
7084            if (activity.finishing) {
7085                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7086                return null;
7087            }
7088        }
7089
7090        // We're going to be splicing together extras before sending, so we're
7091        // okay poking into any contained extras.
7092        if (intents != null) {
7093            for (int i = 0; i < intents.length; i++) {
7094                intents[i].setDefusable(true);
7095            }
7096        }
7097        Bundle.setDefusable(bOptions, true);
7098
7099        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7100        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7101        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7102        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7103                |PendingIntent.FLAG_UPDATE_CURRENT);
7104
7105        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7106                type, packageName, activity, resultWho,
7107                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7108        WeakReference<PendingIntentRecord> ref;
7109        ref = mIntentSenderRecords.get(key);
7110        PendingIntentRecord rec = ref != null ? ref.get() : null;
7111        if (rec != null) {
7112            if (!cancelCurrent) {
7113                if (updateCurrent) {
7114                    if (rec.key.requestIntent != null) {
7115                        rec.key.requestIntent.replaceExtras(intents != null ?
7116                                intents[intents.length - 1] : null);
7117                    }
7118                    if (intents != null) {
7119                        intents[intents.length-1] = rec.key.requestIntent;
7120                        rec.key.allIntents = intents;
7121                        rec.key.allResolvedTypes = resolvedTypes;
7122                    } else {
7123                        rec.key.allIntents = null;
7124                        rec.key.allResolvedTypes = null;
7125                    }
7126                }
7127                return rec;
7128            }
7129            rec.canceled = true;
7130            mIntentSenderRecords.remove(key);
7131        }
7132        if (noCreate) {
7133            return rec;
7134        }
7135        rec = new PendingIntentRecord(this, key, callingUid);
7136        mIntentSenderRecords.put(key, rec.ref);
7137        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7138            if (activity.pendingResults == null) {
7139                activity.pendingResults
7140                        = new HashSet<WeakReference<PendingIntentRecord>>();
7141            }
7142            activity.pendingResults.add(rec.ref);
7143        }
7144        return rec;
7145    }
7146
7147    @Override
7148    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7149            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7150        if (target instanceof PendingIntentRecord) {
7151            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7152                    finishedReceiver, requiredPermission, options);
7153        } else {
7154            if (intent == null) {
7155                // Weird case: someone has given us their own custom IIntentSender, and now
7156                // they have someone else trying to send to it but of course this isn't
7157                // really a PendingIntent, so there is no base Intent, and the caller isn't
7158                // supplying an Intent... but we never want to dispatch a null Intent to
7159                // a receiver, so um...  let's make something up.
7160                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7161                intent = new Intent(Intent.ACTION_MAIN);
7162            }
7163            try {
7164                target.send(code, intent, resolvedType, null, requiredPermission, options);
7165            } catch (RemoteException e) {
7166            }
7167            // Platform code can rely on getting a result back when the send is done, but if
7168            // this intent sender is from outside of the system we can't rely on it doing that.
7169            // So instead we don't give it the result receiver, and instead just directly
7170            // report the finish immediately.
7171            if (finishedReceiver != null) {
7172                try {
7173                    finishedReceiver.performReceive(intent, 0,
7174                            null, null, false, false, UserHandle.getCallingUserId());
7175                } catch (RemoteException e) {
7176                }
7177            }
7178            return 0;
7179        }
7180    }
7181
7182    /**
7183     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7184     *
7185     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7186     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7187     */
7188    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7189        if (DEBUG_WHITELISTS) {
7190            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7191                    + targetUid + ", " + duration + ")");
7192        }
7193        synchronized (mPidsSelfLocked) {
7194            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7195            if (pr == null) {
7196                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7197                return;
7198            }
7199            if (!pr.whitelistManager) {
7200                if (DEBUG_WHITELISTS) {
7201                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7202                            + callerPid + " is not allowed");
7203                }
7204                return;
7205            }
7206        }
7207
7208        final long token = Binder.clearCallingIdentity();
7209        try {
7210            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7211                    true, "pe from uid:" + callerUid);
7212        } finally {
7213            Binder.restoreCallingIdentity(token);
7214        }
7215    }
7216
7217    @Override
7218    public void cancelIntentSender(IIntentSender sender) {
7219        if (!(sender instanceof PendingIntentRecord)) {
7220            return;
7221        }
7222        synchronized(this) {
7223            PendingIntentRecord rec = (PendingIntentRecord)sender;
7224            try {
7225                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7226                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7227                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7228                    String msg = "Permission Denial: cancelIntentSender() from pid="
7229                        + Binder.getCallingPid()
7230                        + ", uid=" + Binder.getCallingUid()
7231                        + " is not allowed to cancel packges "
7232                        + rec.key.packageName;
7233                    Slog.w(TAG, msg);
7234                    throw new SecurityException(msg);
7235                }
7236            } catch (RemoteException e) {
7237                throw new SecurityException(e);
7238            }
7239            cancelIntentSenderLocked(rec, true);
7240        }
7241    }
7242
7243    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7244        rec.canceled = true;
7245        mIntentSenderRecords.remove(rec.key);
7246        if (cleanActivity && rec.key.activity != null) {
7247            rec.key.activity.pendingResults.remove(rec.ref);
7248        }
7249    }
7250
7251    @Override
7252    public String getPackageForIntentSender(IIntentSender pendingResult) {
7253        if (!(pendingResult instanceof PendingIntentRecord)) {
7254            return null;
7255        }
7256        try {
7257            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7258            return res.key.packageName;
7259        } catch (ClassCastException e) {
7260        }
7261        return null;
7262    }
7263
7264    @Override
7265    public int getUidForIntentSender(IIntentSender sender) {
7266        if (sender instanceof PendingIntentRecord) {
7267            try {
7268                PendingIntentRecord res = (PendingIntentRecord)sender;
7269                return res.uid;
7270            } catch (ClassCastException e) {
7271            }
7272        }
7273        return -1;
7274    }
7275
7276    @Override
7277    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7278        if (!(pendingResult instanceof PendingIntentRecord)) {
7279            return false;
7280        }
7281        try {
7282            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7283            if (res.key.allIntents == null) {
7284                return false;
7285            }
7286            for (int i=0; i<res.key.allIntents.length; i++) {
7287                Intent intent = res.key.allIntents[i];
7288                if (intent.getPackage() != null && intent.getComponent() != null) {
7289                    return false;
7290                }
7291            }
7292            return true;
7293        } catch (ClassCastException e) {
7294        }
7295        return false;
7296    }
7297
7298    @Override
7299    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7300        if (!(pendingResult instanceof PendingIntentRecord)) {
7301            return false;
7302        }
7303        try {
7304            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7305            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7306                return true;
7307            }
7308            return false;
7309        } catch (ClassCastException e) {
7310        }
7311        return false;
7312    }
7313
7314    @Override
7315    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7316        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7317                "getIntentForIntentSender()");
7318        if (!(pendingResult instanceof PendingIntentRecord)) {
7319            return null;
7320        }
7321        try {
7322            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7323            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7324        } catch (ClassCastException e) {
7325        }
7326        return null;
7327    }
7328
7329    @Override
7330    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7331        if (!(pendingResult instanceof PendingIntentRecord)) {
7332            return null;
7333        }
7334        try {
7335            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7336            synchronized (this) {
7337                return getTagForIntentSenderLocked(res, prefix);
7338            }
7339        } catch (ClassCastException e) {
7340        }
7341        return null;
7342    }
7343
7344    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7345        final Intent intent = res.key.requestIntent;
7346        if (intent != null) {
7347            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7348                    || res.lastTagPrefix.equals(prefix))) {
7349                return res.lastTag;
7350            }
7351            res.lastTagPrefix = prefix;
7352            final StringBuilder sb = new StringBuilder(128);
7353            if (prefix != null) {
7354                sb.append(prefix);
7355            }
7356            if (intent.getAction() != null) {
7357                sb.append(intent.getAction());
7358            } else if (intent.getComponent() != null) {
7359                intent.getComponent().appendShortString(sb);
7360            } else {
7361                sb.append("?");
7362            }
7363            return res.lastTag = sb.toString();
7364        }
7365        return null;
7366    }
7367
7368    @Override
7369    public void setProcessLimit(int max) {
7370        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7371                "setProcessLimit()");
7372        synchronized (this) {
7373            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7374            mProcessLimitOverride = max;
7375        }
7376        trimApplications();
7377    }
7378
7379    @Override
7380    public int getProcessLimit() {
7381        synchronized (this) {
7382            return mProcessLimitOverride;
7383        }
7384    }
7385
7386    void foregroundTokenDied(ForegroundToken token) {
7387        synchronized (ActivityManagerService.this) {
7388            synchronized (mPidsSelfLocked) {
7389                ForegroundToken cur
7390                    = mForegroundProcesses.get(token.pid);
7391                if (cur != token) {
7392                    return;
7393                }
7394                mForegroundProcesses.remove(token.pid);
7395                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7396                if (pr == null) {
7397                    return;
7398                }
7399                pr.forcingToForeground = null;
7400                updateProcessForegroundLocked(pr, false, false);
7401            }
7402            updateOomAdjLocked();
7403        }
7404    }
7405
7406    @Override
7407    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7408        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7409                "setProcessForeground()");
7410        synchronized(this) {
7411            boolean changed = false;
7412
7413            synchronized (mPidsSelfLocked) {
7414                ProcessRecord pr = mPidsSelfLocked.get(pid);
7415                if (pr == null && isForeground) {
7416                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7417                    return;
7418                }
7419                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7420                if (oldToken != null) {
7421                    oldToken.token.unlinkToDeath(oldToken, 0);
7422                    mForegroundProcesses.remove(pid);
7423                    if (pr != null) {
7424                        pr.forcingToForeground = null;
7425                    }
7426                    changed = true;
7427                }
7428                if (isForeground && token != null) {
7429                    ForegroundToken newToken = new ForegroundToken() {
7430                        @Override
7431                        public void binderDied() {
7432                            foregroundTokenDied(this);
7433                        }
7434                    };
7435                    newToken.pid = pid;
7436                    newToken.token = token;
7437                    try {
7438                        token.linkToDeath(newToken, 0);
7439                        mForegroundProcesses.put(pid, newToken);
7440                        pr.forcingToForeground = token;
7441                        changed = true;
7442                    } catch (RemoteException e) {
7443                        // If the process died while doing this, we will later
7444                        // do the cleanup with the process death link.
7445                    }
7446                }
7447            }
7448
7449            if (changed) {
7450                updateOomAdjLocked();
7451            }
7452        }
7453    }
7454
7455    @Override
7456    public boolean isAppForeground(int uid) throws RemoteException {
7457        synchronized (this) {
7458            UidRecord uidRec = mActiveUids.get(uid);
7459            if (uidRec == null || uidRec.idle) {
7460                return false;
7461            }
7462            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7463        }
7464    }
7465
7466    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7467    // be guarded by permission checking.
7468    int getUidState(int uid) {
7469        synchronized (this) {
7470            UidRecord uidRec = mActiveUids.get(uid);
7471            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7472        }
7473    }
7474
7475    @Override
7476    public boolean isInMultiWindowMode(IBinder token) {
7477        final long origId = Binder.clearCallingIdentity();
7478        try {
7479            synchronized(this) {
7480                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7481                if (r == null) {
7482                    return false;
7483                }
7484                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7485                return !r.task.mFullscreen;
7486            }
7487        } finally {
7488            Binder.restoreCallingIdentity(origId);
7489        }
7490    }
7491
7492    @Override
7493    public boolean isInPictureInPictureMode(IBinder token) {
7494        final long origId = Binder.clearCallingIdentity();
7495        try {
7496            synchronized(this) {
7497                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7498                if (stack == null) {
7499                    return false;
7500                }
7501                return stack.mStackId == PINNED_STACK_ID;
7502            }
7503        } finally {
7504            Binder.restoreCallingIdentity(origId);
7505        }
7506    }
7507
7508    @Override
7509    public void enterPictureInPictureMode(IBinder token) {
7510        final long origId = Binder.clearCallingIdentity();
7511        try {
7512            synchronized(this) {
7513                if (!mSupportsPictureInPicture) {
7514                    throw new IllegalStateException("enterPictureInPictureMode: "
7515                            + "Device doesn't support picture-in-picture mode.");
7516                }
7517
7518                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7519
7520                if (r == null) {
7521                    throw new IllegalStateException("enterPictureInPictureMode: "
7522                            + "Can't find activity for token=" + token);
7523                }
7524
7525                if (!r.supportsPictureInPicture()) {
7526                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7527                            + "Picture-In-Picture not supported for r=" + r);
7528                }
7529
7530                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7531                // current bounds.
7532                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7533                final Rect bounds = (pinnedStack != null)
7534                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7535
7536                mStackSupervisor.moveActivityToPinnedStackLocked(
7537                        r, "enterPictureInPictureMode", bounds);
7538            }
7539        } finally {
7540            Binder.restoreCallingIdentity(origId);
7541        }
7542    }
7543
7544    // =========================================================
7545    // PROCESS INFO
7546    // =========================================================
7547
7548    static class ProcessInfoService extends IProcessInfoService.Stub {
7549        final ActivityManagerService mActivityManagerService;
7550        ProcessInfoService(ActivityManagerService activityManagerService) {
7551            mActivityManagerService = activityManagerService;
7552        }
7553
7554        @Override
7555        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7556            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7557                    /*in*/ pids, /*out*/ states, null);
7558        }
7559
7560        @Override
7561        public void getProcessStatesAndOomScoresFromPids(
7562                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7563            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7564                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7565        }
7566    }
7567
7568    /**
7569     * For each PID in the given input array, write the current process state
7570     * for that process into the states array, or -1 to indicate that no
7571     * process with the given PID exists. If scores array is provided, write
7572     * the oom score for the process into the scores array, with INVALID_ADJ
7573     * indicating the PID doesn't exist.
7574     */
7575    public void getProcessStatesAndOomScoresForPIDs(
7576            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7577        if (scores != null) {
7578            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7579                    "getProcessStatesAndOomScoresForPIDs()");
7580        }
7581
7582        if (pids == null) {
7583            throw new NullPointerException("pids");
7584        } else if (states == null) {
7585            throw new NullPointerException("states");
7586        } else if (pids.length != states.length) {
7587            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7588        } else if (scores != null && pids.length != scores.length) {
7589            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7590        }
7591
7592        synchronized (mPidsSelfLocked) {
7593            for (int i = 0; i < pids.length; i++) {
7594                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7595                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7596                        pr.curProcState;
7597                if (scores != null) {
7598                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7599                }
7600            }
7601        }
7602    }
7603
7604    // =========================================================
7605    // PERMISSIONS
7606    // =========================================================
7607
7608    static class PermissionController extends IPermissionController.Stub {
7609        ActivityManagerService mActivityManagerService;
7610        PermissionController(ActivityManagerService activityManagerService) {
7611            mActivityManagerService = activityManagerService;
7612        }
7613
7614        @Override
7615        public boolean checkPermission(String permission, int pid, int uid) {
7616            return mActivityManagerService.checkPermission(permission, pid,
7617                    uid) == PackageManager.PERMISSION_GRANTED;
7618        }
7619
7620        @Override
7621        public String[] getPackagesForUid(int uid) {
7622            return mActivityManagerService.mContext.getPackageManager()
7623                    .getPackagesForUid(uid);
7624        }
7625
7626        @Override
7627        public boolean isRuntimePermission(String permission) {
7628            try {
7629                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7630                        .getPermissionInfo(permission, 0);
7631                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7632            } catch (NameNotFoundException nnfe) {
7633                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7634            }
7635            return false;
7636        }
7637    }
7638
7639    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7640        @Override
7641        public int checkComponentPermission(String permission, int pid, int uid,
7642                int owningUid, boolean exported) {
7643            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7644                    owningUid, exported);
7645        }
7646
7647        @Override
7648        public Object getAMSLock() {
7649            return ActivityManagerService.this;
7650        }
7651    }
7652
7653    /**
7654     * This can be called with or without the global lock held.
7655     */
7656    int checkComponentPermission(String permission, int pid, int uid,
7657            int owningUid, boolean exported) {
7658        if (pid == MY_PID) {
7659            return PackageManager.PERMISSION_GRANTED;
7660        }
7661        return ActivityManager.checkComponentPermission(permission, uid,
7662                owningUid, exported);
7663    }
7664
7665    /**
7666     * As the only public entry point for permissions checking, this method
7667     * can enforce the semantic that requesting a check on a null global
7668     * permission is automatically denied.  (Internally a null permission
7669     * string is used when calling {@link #checkComponentPermission} in cases
7670     * when only uid-based security is needed.)
7671     *
7672     * This can be called with or without the global lock held.
7673     */
7674    @Override
7675    public int checkPermission(String permission, int pid, int uid) {
7676        if (permission == null) {
7677            return PackageManager.PERMISSION_DENIED;
7678        }
7679        return checkComponentPermission(permission, pid, uid, -1, true);
7680    }
7681
7682    @Override
7683    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7684        if (permission == null) {
7685            return PackageManager.PERMISSION_DENIED;
7686        }
7687
7688        // We might be performing an operation on behalf of an indirect binder
7689        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7690        // client identity accordingly before proceeding.
7691        Identity tlsIdentity = sCallerIdentity.get();
7692        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7693            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7694                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7695            uid = tlsIdentity.uid;
7696            pid = tlsIdentity.pid;
7697        }
7698
7699        return checkComponentPermission(permission, pid, uid, -1, true);
7700    }
7701
7702    /**
7703     * Binder IPC calls go through the public entry point.
7704     * This can be called with or without the global lock held.
7705     */
7706    int checkCallingPermission(String permission) {
7707        return checkPermission(permission,
7708                Binder.getCallingPid(),
7709                UserHandle.getAppId(Binder.getCallingUid()));
7710    }
7711
7712    /**
7713     * This can be called with or without the global lock held.
7714     */
7715    void enforceCallingPermission(String permission, String func) {
7716        if (checkCallingPermission(permission)
7717                == PackageManager.PERMISSION_GRANTED) {
7718            return;
7719        }
7720
7721        String msg = "Permission Denial: " + func + " from pid="
7722                + Binder.getCallingPid()
7723                + ", uid=" + Binder.getCallingUid()
7724                + " requires " + permission;
7725        Slog.w(TAG, msg);
7726        throw new SecurityException(msg);
7727    }
7728
7729    /**
7730     * Determine if UID is holding permissions required to access {@link Uri} in
7731     * the given {@link ProviderInfo}. Final permission checking is always done
7732     * in {@link ContentProvider}.
7733     */
7734    private final boolean checkHoldingPermissionsLocked(
7735            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7736        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7737                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7738        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7739            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7740                    != PERMISSION_GRANTED) {
7741                return false;
7742            }
7743        }
7744        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7745    }
7746
7747    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7748            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7749        if (pi.applicationInfo.uid == uid) {
7750            return true;
7751        } else if (!pi.exported) {
7752            return false;
7753        }
7754
7755        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7756        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7757        try {
7758            // check if target holds top-level <provider> permissions
7759            if (!readMet && pi.readPermission != null && considerUidPermissions
7760                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7761                readMet = true;
7762            }
7763            if (!writeMet && pi.writePermission != null && considerUidPermissions
7764                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7765                writeMet = true;
7766            }
7767
7768            // track if unprotected read/write is allowed; any denied
7769            // <path-permission> below removes this ability
7770            boolean allowDefaultRead = pi.readPermission == null;
7771            boolean allowDefaultWrite = pi.writePermission == null;
7772
7773            // check if target holds any <path-permission> that match uri
7774            final PathPermission[] pps = pi.pathPermissions;
7775            if (pps != null) {
7776                final String path = grantUri.uri.getPath();
7777                int i = pps.length;
7778                while (i > 0 && (!readMet || !writeMet)) {
7779                    i--;
7780                    PathPermission pp = pps[i];
7781                    if (pp.match(path)) {
7782                        if (!readMet) {
7783                            final String pprperm = pp.getReadPermission();
7784                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7785                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7786                                    + ": match=" + pp.match(path)
7787                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7788                            if (pprperm != null) {
7789                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7790                                        == PERMISSION_GRANTED) {
7791                                    readMet = true;
7792                                } else {
7793                                    allowDefaultRead = false;
7794                                }
7795                            }
7796                        }
7797                        if (!writeMet) {
7798                            final String ppwperm = pp.getWritePermission();
7799                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7800                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7801                                    + ": match=" + pp.match(path)
7802                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7803                            if (ppwperm != null) {
7804                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7805                                        == PERMISSION_GRANTED) {
7806                                    writeMet = true;
7807                                } else {
7808                                    allowDefaultWrite = false;
7809                                }
7810                            }
7811                        }
7812                    }
7813                }
7814            }
7815
7816            // grant unprotected <provider> read/write, if not blocked by
7817            // <path-permission> above
7818            if (allowDefaultRead) readMet = true;
7819            if (allowDefaultWrite) writeMet = true;
7820
7821        } catch (RemoteException e) {
7822            return false;
7823        }
7824
7825        return readMet && writeMet;
7826    }
7827
7828    public int getAppStartMode(int uid, String packageName) {
7829        synchronized (this) {
7830            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7831        }
7832    }
7833
7834    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7835            boolean allowWhenForeground) {
7836        UidRecord uidRec = mActiveUids.get(uid);
7837        if (!mLenientBackgroundCheck) {
7838            if (!allowWhenForeground || uidRec == null
7839                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7840                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7841                        packageName) != AppOpsManager.MODE_ALLOWED) {
7842                    return ActivityManager.APP_START_MODE_DELAYED;
7843                }
7844            }
7845
7846        } else if (uidRec == null || uidRec.idle) {
7847            if (callingPid >= 0) {
7848                ProcessRecord proc;
7849                synchronized (mPidsSelfLocked) {
7850                    proc = mPidsSelfLocked.get(callingPid);
7851                }
7852                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7853                    // Whoever is instigating this is in the foreground, so we will allow it
7854                    // to go through.
7855                    return ActivityManager.APP_START_MODE_NORMAL;
7856                }
7857            }
7858            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7859                    != AppOpsManager.MODE_ALLOWED) {
7860                return ActivityManager.APP_START_MODE_DELAYED;
7861            }
7862        }
7863        return ActivityManager.APP_START_MODE_NORMAL;
7864    }
7865
7866    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7867        ProviderInfo pi = null;
7868        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7869        if (cpr != null) {
7870            pi = cpr.info;
7871        } else {
7872            try {
7873                pi = AppGlobals.getPackageManager().resolveContentProvider(
7874                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7875                        userHandle);
7876            } catch (RemoteException ex) {
7877            }
7878        }
7879        return pi;
7880    }
7881
7882    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7883        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7884        if (targetUris != null) {
7885            return targetUris.get(grantUri);
7886        }
7887        return null;
7888    }
7889
7890    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7891            String targetPkg, int targetUid, GrantUri grantUri) {
7892        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7893        if (targetUris == null) {
7894            targetUris = Maps.newArrayMap();
7895            mGrantedUriPermissions.put(targetUid, targetUris);
7896        }
7897
7898        UriPermission perm = targetUris.get(grantUri);
7899        if (perm == null) {
7900            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7901            targetUris.put(grantUri, perm);
7902        }
7903
7904        return perm;
7905    }
7906
7907    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7908            final int modeFlags) {
7909        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7910        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7911                : UriPermission.STRENGTH_OWNED;
7912
7913        // Root gets to do everything.
7914        if (uid == 0) {
7915            return true;
7916        }
7917
7918        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7919        if (perms == null) return false;
7920
7921        // First look for exact match
7922        final UriPermission exactPerm = perms.get(grantUri);
7923        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7924            return true;
7925        }
7926
7927        // No exact match, look for prefixes
7928        final int N = perms.size();
7929        for (int i = 0; i < N; i++) {
7930            final UriPermission perm = perms.valueAt(i);
7931            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7932                    && perm.getStrength(modeFlags) >= minStrength) {
7933                return true;
7934            }
7935        }
7936
7937        return false;
7938    }
7939
7940    /**
7941     * @param uri This uri must NOT contain an embedded userId.
7942     * @param userId The userId in which the uri is to be resolved.
7943     */
7944    @Override
7945    public int checkUriPermission(Uri uri, int pid, int uid,
7946            final int modeFlags, int userId, IBinder callerToken) {
7947        enforceNotIsolatedCaller("checkUriPermission");
7948
7949        // Another redirected-binder-call permissions check as in
7950        // {@link checkPermissionWithToken}.
7951        Identity tlsIdentity = sCallerIdentity.get();
7952        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7953            uid = tlsIdentity.uid;
7954            pid = tlsIdentity.pid;
7955        }
7956
7957        // Our own process gets to do everything.
7958        if (pid == MY_PID) {
7959            return PackageManager.PERMISSION_GRANTED;
7960        }
7961        synchronized (this) {
7962            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7963                    ? PackageManager.PERMISSION_GRANTED
7964                    : PackageManager.PERMISSION_DENIED;
7965        }
7966    }
7967
7968    /**
7969     * Check if the targetPkg can be granted permission to access uri by
7970     * the callingUid using the given modeFlags.  Throws a security exception
7971     * if callingUid is not allowed to do this.  Returns the uid of the target
7972     * if the URI permission grant should be performed; returns -1 if it is not
7973     * needed (for example targetPkg already has permission to access the URI).
7974     * If you already know the uid of the target, you can supply it in
7975     * lastTargetUid else set that to -1.
7976     */
7977    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7978            final int modeFlags, int lastTargetUid) {
7979        if (!Intent.isAccessUriMode(modeFlags)) {
7980            return -1;
7981        }
7982
7983        if (targetPkg != null) {
7984            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7985                    "Checking grant " + targetPkg + " permission to " + grantUri);
7986        }
7987
7988        final IPackageManager pm = AppGlobals.getPackageManager();
7989
7990        // If this is not a content: uri, we can't do anything with it.
7991        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7992            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7993                    "Can't grant URI permission for non-content URI: " + grantUri);
7994            return -1;
7995        }
7996
7997        final String authority = grantUri.uri.getAuthority();
7998        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
7999                MATCH_DEBUG_TRIAGED_MISSING);
8000        if (pi == null) {
8001            Slog.w(TAG, "No content provider found for permission check: " +
8002                    grantUri.uri.toSafeString());
8003            return -1;
8004        }
8005
8006        int targetUid = lastTargetUid;
8007        if (targetUid < 0 && targetPkg != null) {
8008            try {
8009                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8010                        UserHandle.getUserId(callingUid));
8011                if (targetUid < 0) {
8012                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8013                            "Can't grant URI permission no uid for: " + targetPkg);
8014                    return -1;
8015                }
8016            } catch (RemoteException ex) {
8017                return -1;
8018            }
8019        }
8020
8021        if (targetUid >= 0) {
8022            // First...  does the target actually need this permission?
8023            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8024                // No need to grant the target this permission.
8025                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8026                        "Target " + targetPkg + " already has full permission to " + grantUri);
8027                return -1;
8028            }
8029        } else {
8030            // First...  there is no target package, so can anyone access it?
8031            boolean allowed = pi.exported;
8032            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8033                if (pi.readPermission != null) {
8034                    allowed = false;
8035                }
8036            }
8037            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8038                if (pi.writePermission != null) {
8039                    allowed = false;
8040                }
8041            }
8042            if (allowed) {
8043                return -1;
8044            }
8045        }
8046
8047        /* There is a special cross user grant if:
8048         * - The target is on another user.
8049         * - Apps on the current user can access the uri without any uid permissions.
8050         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8051         * grant uri permissions.
8052         */
8053        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8054                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8055                modeFlags, false /*without considering the uid permissions*/);
8056
8057        // Second...  is the provider allowing granting of URI permissions?
8058        if (!specialCrossUserGrant) {
8059            if (!pi.grantUriPermissions) {
8060                throw new SecurityException("Provider " + pi.packageName
8061                        + "/" + pi.name
8062                        + " does not allow granting of Uri permissions (uri "
8063                        + grantUri + ")");
8064            }
8065            if (pi.uriPermissionPatterns != null) {
8066                final int N = pi.uriPermissionPatterns.length;
8067                boolean allowed = false;
8068                for (int i=0; i<N; i++) {
8069                    if (pi.uriPermissionPatterns[i] != null
8070                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8071                        allowed = true;
8072                        break;
8073                    }
8074                }
8075                if (!allowed) {
8076                    throw new SecurityException("Provider " + pi.packageName
8077                            + "/" + pi.name
8078                            + " does not allow granting of permission to path of Uri "
8079                            + grantUri);
8080                }
8081            }
8082        }
8083
8084        // Third...  does the caller itself have permission to access
8085        // this uri?
8086        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8087            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8088                // Require they hold a strong enough Uri permission
8089                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8090                    throw new SecurityException("Uid " + callingUid
8091                            + " does not have permission to uri " + grantUri);
8092                }
8093            }
8094        }
8095        return targetUid;
8096    }
8097
8098    /**
8099     * @param uri This uri must NOT contain an embedded userId.
8100     * @param userId The userId in which the uri is to be resolved.
8101     */
8102    @Override
8103    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8104            final int modeFlags, int userId) {
8105        enforceNotIsolatedCaller("checkGrantUriPermission");
8106        synchronized(this) {
8107            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8108                    new GrantUri(userId, uri, false), modeFlags, -1);
8109        }
8110    }
8111
8112    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8113            final int modeFlags, UriPermissionOwner owner) {
8114        if (!Intent.isAccessUriMode(modeFlags)) {
8115            return;
8116        }
8117
8118        // So here we are: the caller has the assumed permission
8119        // to the uri, and the target doesn't.  Let's now give this to
8120        // the target.
8121
8122        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8123                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8124
8125        final String authority = grantUri.uri.getAuthority();
8126        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8127                MATCH_DEBUG_TRIAGED_MISSING);
8128        if (pi == null) {
8129            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8130            return;
8131        }
8132
8133        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8134            grantUri.prefix = true;
8135        }
8136        final UriPermission perm = findOrCreateUriPermissionLocked(
8137                pi.packageName, targetPkg, targetUid, grantUri);
8138        perm.grantModes(modeFlags, owner);
8139    }
8140
8141    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8142            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8143        if (targetPkg == null) {
8144            throw new NullPointerException("targetPkg");
8145        }
8146        int targetUid;
8147        final IPackageManager pm = AppGlobals.getPackageManager();
8148        try {
8149            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8150        } catch (RemoteException ex) {
8151            return;
8152        }
8153
8154        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8155                targetUid);
8156        if (targetUid < 0) {
8157            return;
8158        }
8159
8160        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8161                owner);
8162    }
8163
8164    static class NeededUriGrants extends ArrayList<GrantUri> {
8165        final String targetPkg;
8166        final int targetUid;
8167        final int flags;
8168
8169        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8170            this.targetPkg = targetPkg;
8171            this.targetUid = targetUid;
8172            this.flags = flags;
8173        }
8174    }
8175
8176    /**
8177     * Like checkGrantUriPermissionLocked, but takes an Intent.
8178     */
8179    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8180            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8181        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8182                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8183                + " clip=" + (intent != null ? intent.getClipData() : null)
8184                + " from " + intent + "; flags=0x"
8185                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8186
8187        if (targetPkg == null) {
8188            throw new NullPointerException("targetPkg");
8189        }
8190
8191        if (intent == null) {
8192            return null;
8193        }
8194        Uri data = intent.getData();
8195        ClipData clip = intent.getClipData();
8196        if (data == null && clip == null) {
8197            return null;
8198        }
8199        // Default userId for uris in the intent (if they don't specify it themselves)
8200        int contentUserHint = intent.getContentUserHint();
8201        if (contentUserHint == UserHandle.USER_CURRENT) {
8202            contentUserHint = UserHandle.getUserId(callingUid);
8203        }
8204        final IPackageManager pm = AppGlobals.getPackageManager();
8205        int targetUid;
8206        if (needed != null) {
8207            targetUid = needed.targetUid;
8208        } else {
8209            try {
8210                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8211                        targetUserId);
8212            } catch (RemoteException ex) {
8213                return null;
8214            }
8215            if (targetUid < 0) {
8216                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8217                        "Can't grant URI permission no uid for: " + targetPkg
8218                        + " on user " + targetUserId);
8219                return null;
8220            }
8221        }
8222        if (data != null) {
8223            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8224            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8225                    targetUid);
8226            if (targetUid > 0) {
8227                if (needed == null) {
8228                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8229                }
8230                needed.add(grantUri);
8231            }
8232        }
8233        if (clip != null) {
8234            for (int i=0; i<clip.getItemCount(); i++) {
8235                Uri uri = clip.getItemAt(i).getUri();
8236                if (uri != null) {
8237                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8238                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8239                            targetUid);
8240                    if (targetUid > 0) {
8241                        if (needed == null) {
8242                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8243                        }
8244                        needed.add(grantUri);
8245                    }
8246                } else {
8247                    Intent clipIntent = clip.getItemAt(i).getIntent();
8248                    if (clipIntent != null) {
8249                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8250                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8251                        if (newNeeded != null) {
8252                            needed = newNeeded;
8253                        }
8254                    }
8255                }
8256            }
8257        }
8258
8259        return needed;
8260    }
8261
8262    /**
8263     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8264     */
8265    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8266            UriPermissionOwner owner) {
8267        if (needed != null) {
8268            for (int i=0; i<needed.size(); i++) {
8269                GrantUri grantUri = needed.get(i);
8270                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8271                        grantUri, needed.flags, owner);
8272            }
8273        }
8274    }
8275
8276    void grantUriPermissionFromIntentLocked(int callingUid,
8277            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8278        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8279                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8280        if (needed == null) {
8281            return;
8282        }
8283
8284        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8285    }
8286
8287    /**
8288     * @param uri This uri must NOT contain an embedded userId.
8289     * @param userId The userId in which the uri is to be resolved.
8290     */
8291    @Override
8292    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8293            final int modeFlags, int userId) {
8294        enforceNotIsolatedCaller("grantUriPermission");
8295        GrantUri grantUri = new GrantUri(userId, uri, false);
8296        synchronized(this) {
8297            final ProcessRecord r = getRecordForAppLocked(caller);
8298            if (r == null) {
8299                throw new SecurityException("Unable to find app for caller "
8300                        + caller
8301                        + " when granting permission to uri " + grantUri);
8302            }
8303            if (targetPkg == null) {
8304                throw new IllegalArgumentException("null target");
8305            }
8306            if (grantUri == null) {
8307                throw new IllegalArgumentException("null uri");
8308            }
8309
8310            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8311                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8312                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8313                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8314
8315            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8316                    UserHandle.getUserId(r.uid));
8317        }
8318    }
8319
8320    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8321        if (perm.modeFlags == 0) {
8322            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8323                    perm.targetUid);
8324            if (perms != null) {
8325                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8326                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8327
8328                perms.remove(perm.uri);
8329                if (perms.isEmpty()) {
8330                    mGrantedUriPermissions.remove(perm.targetUid);
8331                }
8332            }
8333        }
8334    }
8335
8336    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8337        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8338                "Revoking all granted permissions to " + grantUri);
8339
8340        final IPackageManager pm = AppGlobals.getPackageManager();
8341        final String authority = grantUri.uri.getAuthority();
8342        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8343                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8344        if (pi == null) {
8345            Slog.w(TAG, "No content provider found for permission revoke: "
8346                    + grantUri.toSafeString());
8347            return;
8348        }
8349
8350        // Does the caller have this permission on the URI?
8351        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8352            // If they don't have direct access to the URI, then revoke any
8353            // ownerless URI permissions that have been granted to them.
8354            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8355            if (perms != null) {
8356                boolean persistChanged = false;
8357                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8358                    final UriPermission perm = it.next();
8359                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8360                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8361                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8362                                "Revoking non-owned " + perm.targetUid
8363                                + " permission to " + perm.uri);
8364                        persistChanged |= perm.revokeModes(
8365                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8366                        if (perm.modeFlags == 0) {
8367                            it.remove();
8368                        }
8369                    }
8370                }
8371                if (perms.isEmpty()) {
8372                    mGrantedUriPermissions.remove(callingUid);
8373                }
8374                if (persistChanged) {
8375                    schedulePersistUriGrants();
8376                }
8377            }
8378            return;
8379        }
8380
8381        boolean persistChanged = false;
8382
8383        // Go through all of the permissions and remove any that match.
8384        int N = mGrantedUriPermissions.size();
8385        for (int i = 0; i < N; i++) {
8386            final int targetUid = mGrantedUriPermissions.keyAt(i);
8387            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8388
8389            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8390                final UriPermission perm = it.next();
8391                if (perm.uri.sourceUserId == grantUri.sourceUserId
8392                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8393                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8394                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8395                    persistChanged |= perm.revokeModes(
8396                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8397                    if (perm.modeFlags == 0) {
8398                        it.remove();
8399                    }
8400                }
8401            }
8402
8403            if (perms.isEmpty()) {
8404                mGrantedUriPermissions.remove(targetUid);
8405                N--;
8406                i--;
8407            }
8408        }
8409
8410        if (persistChanged) {
8411            schedulePersistUriGrants();
8412        }
8413    }
8414
8415    /**
8416     * @param uri This uri must NOT contain an embedded userId.
8417     * @param userId The userId in which the uri is to be resolved.
8418     */
8419    @Override
8420    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8421            int userId) {
8422        enforceNotIsolatedCaller("revokeUriPermission");
8423        synchronized(this) {
8424            final ProcessRecord r = getRecordForAppLocked(caller);
8425            if (r == null) {
8426                throw new SecurityException("Unable to find app for caller "
8427                        + caller
8428                        + " when revoking permission to uri " + uri);
8429            }
8430            if (uri == null) {
8431                Slog.w(TAG, "revokeUriPermission: null uri");
8432                return;
8433            }
8434
8435            if (!Intent.isAccessUriMode(modeFlags)) {
8436                return;
8437            }
8438
8439            final String authority = uri.getAuthority();
8440            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8441                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8442            if (pi == null) {
8443                Slog.w(TAG, "No content provider found for permission revoke: "
8444                        + uri.toSafeString());
8445                return;
8446            }
8447
8448            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8449        }
8450    }
8451
8452    /**
8453     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8454     * given package.
8455     *
8456     * @param packageName Package name to match, or {@code null} to apply to all
8457     *            packages.
8458     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8459     *            to all users.
8460     * @param persistable If persistable grants should be removed.
8461     */
8462    private void removeUriPermissionsForPackageLocked(
8463            String packageName, int userHandle, boolean persistable) {
8464        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8465            throw new IllegalArgumentException("Must narrow by either package or user");
8466        }
8467
8468        boolean persistChanged = false;
8469
8470        int N = mGrantedUriPermissions.size();
8471        for (int i = 0; i < N; i++) {
8472            final int targetUid = mGrantedUriPermissions.keyAt(i);
8473            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8474
8475            // Only inspect grants matching user
8476            if (userHandle == UserHandle.USER_ALL
8477                    || userHandle == UserHandle.getUserId(targetUid)) {
8478                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8479                    final UriPermission perm = it.next();
8480
8481                    // Only inspect grants matching package
8482                    if (packageName == null || perm.sourcePkg.equals(packageName)
8483                            || perm.targetPkg.equals(packageName)) {
8484                        persistChanged |= perm.revokeModes(persistable
8485                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8486
8487                        // Only remove when no modes remain; any persisted grants
8488                        // will keep this alive.
8489                        if (perm.modeFlags == 0) {
8490                            it.remove();
8491                        }
8492                    }
8493                }
8494
8495                if (perms.isEmpty()) {
8496                    mGrantedUriPermissions.remove(targetUid);
8497                    N--;
8498                    i--;
8499                }
8500            }
8501        }
8502
8503        if (persistChanged) {
8504            schedulePersistUriGrants();
8505        }
8506    }
8507
8508    @Override
8509    public IBinder newUriPermissionOwner(String name) {
8510        enforceNotIsolatedCaller("newUriPermissionOwner");
8511        synchronized(this) {
8512            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8513            return owner.getExternalTokenLocked();
8514        }
8515    }
8516
8517    @Override
8518    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8519        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8520        synchronized(this) {
8521            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8522            if (r == null) {
8523                throw new IllegalArgumentException("Activity does not exist; token="
8524                        + activityToken);
8525            }
8526            return r.getUriPermissionsLocked().getExternalTokenLocked();
8527        }
8528    }
8529    /**
8530     * @param uri This uri must NOT contain an embedded userId.
8531     * @param sourceUserId The userId in which the uri is to be resolved.
8532     * @param targetUserId The userId of the app that receives the grant.
8533     */
8534    @Override
8535    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8536            final int modeFlags, int sourceUserId, int targetUserId) {
8537        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8538                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8539                "grantUriPermissionFromOwner", null);
8540        synchronized(this) {
8541            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8542            if (owner == null) {
8543                throw new IllegalArgumentException("Unknown owner: " + token);
8544            }
8545            if (fromUid != Binder.getCallingUid()) {
8546                if (Binder.getCallingUid() != Process.myUid()) {
8547                    // Only system code can grant URI permissions on behalf
8548                    // of other users.
8549                    throw new SecurityException("nice try");
8550                }
8551            }
8552            if (targetPkg == null) {
8553                throw new IllegalArgumentException("null target");
8554            }
8555            if (uri == null) {
8556                throw new IllegalArgumentException("null uri");
8557            }
8558
8559            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8560                    modeFlags, owner, targetUserId);
8561        }
8562    }
8563
8564    /**
8565     * @param uri This uri must NOT contain an embedded userId.
8566     * @param userId The userId in which the uri is to be resolved.
8567     */
8568    @Override
8569    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8570        synchronized(this) {
8571            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8572            if (owner == null) {
8573                throw new IllegalArgumentException("Unknown owner: " + token);
8574            }
8575
8576            if (uri == null) {
8577                owner.removeUriPermissionsLocked(mode);
8578            } else {
8579                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8580            }
8581        }
8582    }
8583
8584    private void schedulePersistUriGrants() {
8585        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8586            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8587                    10 * DateUtils.SECOND_IN_MILLIS);
8588        }
8589    }
8590
8591    private void writeGrantedUriPermissions() {
8592        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8593
8594        // Snapshot permissions so we can persist without lock
8595        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8596        synchronized (this) {
8597            final int size = mGrantedUriPermissions.size();
8598            for (int i = 0; i < size; i++) {
8599                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8600                for (UriPermission perm : perms.values()) {
8601                    if (perm.persistedModeFlags != 0) {
8602                        persist.add(perm.snapshot());
8603                    }
8604                }
8605            }
8606        }
8607
8608        FileOutputStream fos = null;
8609        try {
8610            fos = mGrantFile.startWrite();
8611
8612            XmlSerializer out = new FastXmlSerializer();
8613            out.setOutput(fos, StandardCharsets.UTF_8.name());
8614            out.startDocument(null, true);
8615            out.startTag(null, TAG_URI_GRANTS);
8616            for (UriPermission.Snapshot perm : persist) {
8617                out.startTag(null, TAG_URI_GRANT);
8618                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8619                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8620                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8621                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8622                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8623                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8624                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8625                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8626                out.endTag(null, TAG_URI_GRANT);
8627            }
8628            out.endTag(null, TAG_URI_GRANTS);
8629            out.endDocument();
8630
8631            mGrantFile.finishWrite(fos);
8632        } catch (IOException e) {
8633            if (fos != null) {
8634                mGrantFile.failWrite(fos);
8635            }
8636        }
8637    }
8638
8639    private void readGrantedUriPermissionsLocked() {
8640        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8641
8642        final long now = System.currentTimeMillis();
8643
8644        FileInputStream fis = null;
8645        try {
8646            fis = mGrantFile.openRead();
8647            final XmlPullParser in = Xml.newPullParser();
8648            in.setInput(fis, StandardCharsets.UTF_8.name());
8649
8650            int type;
8651            while ((type = in.next()) != END_DOCUMENT) {
8652                final String tag = in.getName();
8653                if (type == START_TAG) {
8654                    if (TAG_URI_GRANT.equals(tag)) {
8655                        final int sourceUserId;
8656                        final int targetUserId;
8657                        final int userHandle = readIntAttribute(in,
8658                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8659                        if (userHandle != UserHandle.USER_NULL) {
8660                            // For backwards compatibility.
8661                            sourceUserId = userHandle;
8662                            targetUserId = userHandle;
8663                        } else {
8664                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8665                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8666                        }
8667                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8668                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8669                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8670                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8671                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8672                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8673
8674                        // Sanity check that provider still belongs to source package
8675                        // Both direct boot aware and unaware packages are fine as we
8676                        // will do filtering at query time to avoid multiple parsing.
8677                        final ProviderInfo pi = getProviderInfoLocked(
8678                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8679                                        | MATCH_DIRECT_BOOT_UNAWARE);
8680                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8681                            int targetUid = -1;
8682                            try {
8683                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8684                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8685                            } catch (RemoteException e) {
8686                            }
8687                            if (targetUid != -1) {
8688                                final UriPermission perm = findOrCreateUriPermissionLocked(
8689                                        sourcePkg, targetPkg, targetUid,
8690                                        new GrantUri(sourceUserId, uri, prefix));
8691                                perm.initPersistedModes(modeFlags, createdTime);
8692                            }
8693                        } else {
8694                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8695                                    + " but instead found " + pi);
8696                        }
8697                    }
8698                }
8699            }
8700        } catch (FileNotFoundException e) {
8701            // Missing grants is okay
8702        } catch (IOException e) {
8703            Slog.wtf(TAG, "Failed reading Uri grants", e);
8704        } catch (XmlPullParserException e) {
8705            Slog.wtf(TAG, "Failed reading Uri grants", e);
8706        } finally {
8707            IoUtils.closeQuietly(fis);
8708        }
8709    }
8710
8711    /**
8712     * @param uri This uri must NOT contain an embedded userId.
8713     * @param userId The userId in which the uri is to be resolved.
8714     */
8715    @Override
8716    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8717        enforceNotIsolatedCaller("takePersistableUriPermission");
8718
8719        Preconditions.checkFlagsArgument(modeFlags,
8720                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8721
8722        synchronized (this) {
8723            final int callingUid = Binder.getCallingUid();
8724            boolean persistChanged = false;
8725            GrantUri grantUri = new GrantUri(userId, uri, false);
8726
8727            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8728                    new GrantUri(userId, uri, false));
8729            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8730                    new GrantUri(userId, uri, true));
8731
8732            final boolean exactValid = (exactPerm != null)
8733                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8734            final boolean prefixValid = (prefixPerm != null)
8735                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8736
8737            if (!(exactValid || prefixValid)) {
8738                throw new SecurityException("No persistable permission grants found for UID "
8739                        + callingUid + " and Uri " + grantUri.toSafeString());
8740            }
8741
8742            if (exactValid) {
8743                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8744            }
8745            if (prefixValid) {
8746                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8747            }
8748
8749            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8750
8751            if (persistChanged) {
8752                schedulePersistUriGrants();
8753            }
8754        }
8755    }
8756
8757    /**
8758     * @param uri This uri must NOT contain an embedded userId.
8759     * @param userId The userId in which the uri is to be resolved.
8760     */
8761    @Override
8762    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8763        enforceNotIsolatedCaller("releasePersistableUriPermission");
8764
8765        Preconditions.checkFlagsArgument(modeFlags,
8766                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8767
8768        synchronized (this) {
8769            final int callingUid = Binder.getCallingUid();
8770            boolean persistChanged = false;
8771
8772            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8773                    new GrantUri(userId, uri, false));
8774            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8775                    new GrantUri(userId, uri, true));
8776            if (exactPerm == null && prefixPerm == null) {
8777                throw new SecurityException("No permission grants found for UID " + callingUid
8778                        + " and Uri " + uri.toSafeString());
8779            }
8780
8781            if (exactPerm != null) {
8782                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8783                removeUriPermissionIfNeededLocked(exactPerm);
8784            }
8785            if (prefixPerm != null) {
8786                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8787                removeUriPermissionIfNeededLocked(prefixPerm);
8788            }
8789
8790            if (persistChanged) {
8791                schedulePersistUriGrants();
8792            }
8793        }
8794    }
8795
8796    /**
8797     * Prune any older {@link UriPermission} for the given UID until outstanding
8798     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8799     *
8800     * @return if any mutations occured that require persisting.
8801     */
8802    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8803        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8804        if (perms == null) return false;
8805        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8806
8807        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8808        for (UriPermission perm : perms.values()) {
8809            if (perm.persistedModeFlags != 0) {
8810                persisted.add(perm);
8811            }
8812        }
8813
8814        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8815        if (trimCount <= 0) return false;
8816
8817        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8818        for (int i = 0; i < trimCount; i++) {
8819            final UriPermission perm = persisted.get(i);
8820
8821            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8822                    "Trimming grant created at " + perm.persistedCreateTime);
8823
8824            perm.releasePersistableModes(~0);
8825            removeUriPermissionIfNeededLocked(perm);
8826        }
8827
8828        return true;
8829    }
8830
8831    @Override
8832    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8833            String packageName, boolean incoming) {
8834        enforceNotIsolatedCaller("getPersistedUriPermissions");
8835        Preconditions.checkNotNull(packageName, "packageName");
8836
8837        final int callingUid = Binder.getCallingUid();
8838        final int callingUserId = UserHandle.getUserId(callingUid);
8839        final IPackageManager pm = AppGlobals.getPackageManager();
8840        try {
8841            final int packageUid = pm.getPackageUid(packageName,
8842                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8843            if (packageUid != callingUid) {
8844                throw new SecurityException(
8845                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8846            }
8847        } catch (RemoteException e) {
8848            throw new SecurityException("Failed to verify package name ownership");
8849        }
8850
8851        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8852        synchronized (this) {
8853            if (incoming) {
8854                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8855                        callingUid);
8856                if (perms == null) {
8857                    Slog.w(TAG, "No permission grants found for " + packageName);
8858                } else {
8859                    for (UriPermission perm : perms.values()) {
8860                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8861                            result.add(perm.buildPersistedPublicApiObject());
8862                        }
8863                    }
8864                }
8865            } else {
8866                final int size = mGrantedUriPermissions.size();
8867                for (int i = 0; i < size; i++) {
8868                    final ArrayMap<GrantUri, UriPermission> perms =
8869                            mGrantedUriPermissions.valueAt(i);
8870                    for (UriPermission perm : perms.values()) {
8871                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8872                            result.add(perm.buildPersistedPublicApiObject());
8873                        }
8874                    }
8875                }
8876            }
8877        }
8878        return new ParceledListSlice<android.content.UriPermission>(result);
8879    }
8880
8881    @Override
8882    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8883            String packageName, int userId) {
8884        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8885                "getGrantedUriPermissions");
8886
8887        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8888        synchronized (this) {
8889            final int size = mGrantedUriPermissions.size();
8890            for (int i = 0; i < size; i++) {
8891                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8892                for (UriPermission perm : perms.values()) {
8893                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8894                            && perm.persistedModeFlags != 0) {
8895                        result.add(perm.buildPersistedPublicApiObject());
8896                    }
8897                }
8898            }
8899        }
8900        return new ParceledListSlice<android.content.UriPermission>(result);
8901    }
8902
8903    @Override
8904    public void clearGrantedUriPermissions(String packageName, int userId) {
8905        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8906                "clearGrantedUriPermissions");
8907        removeUriPermissionsForPackageLocked(packageName, userId, true);
8908    }
8909
8910    @Override
8911    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8912        synchronized (this) {
8913            ProcessRecord app =
8914                who != null ? getRecordForAppLocked(who) : null;
8915            if (app == null) return;
8916
8917            Message msg = Message.obtain();
8918            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8919            msg.obj = app;
8920            msg.arg1 = waiting ? 1 : 0;
8921            mUiHandler.sendMessage(msg);
8922        }
8923    }
8924
8925    @Override
8926    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8927        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8928        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8929        outInfo.availMem = Process.getFreeMemory();
8930        outInfo.totalMem = Process.getTotalMemory();
8931        outInfo.threshold = homeAppMem;
8932        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8933        outInfo.hiddenAppThreshold = cachedAppMem;
8934        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8935                ProcessList.SERVICE_ADJ);
8936        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8937                ProcessList.VISIBLE_APP_ADJ);
8938        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8939                ProcessList.FOREGROUND_APP_ADJ);
8940    }
8941
8942    // =========================================================
8943    // TASK MANAGEMENT
8944    // =========================================================
8945
8946    @Override
8947    public List<IAppTask> getAppTasks(String callingPackage) {
8948        int callingUid = Binder.getCallingUid();
8949        long ident = Binder.clearCallingIdentity();
8950
8951        synchronized(this) {
8952            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8953            try {
8954                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8955
8956                final int N = mRecentTasks.size();
8957                for (int i = 0; i < N; i++) {
8958                    TaskRecord tr = mRecentTasks.get(i);
8959                    // Skip tasks that do not match the caller.  We don't need to verify
8960                    // callingPackage, because we are also limiting to callingUid and know
8961                    // that will limit to the correct security sandbox.
8962                    if (tr.effectiveUid != callingUid) {
8963                        continue;
8964                    }
8965                    Intent intent = tr.getBaseIntent();
8966                    if (intent == null ||
8967                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8968                        continue;
8969                    }
8970                    ActivityManager.RecentTaskInfo taskInfo =
8971                            createRecentTaskInfoFromTaskRecord(tr);
8972                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8973                    list.add(taskImpl);
8974                }
8975            } finally {
8976                Binder.restoreCallingIdentity(ident);
8977            }
8978            return list;
8979        }
8980    }
8981
8982    @Override
8983    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8984        final int callingUid = Binder.getCallingUid();
8985        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8986
8987        synchronized(this) {
8988            if (DEBUG_ALL) Slog.v(
8989                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8990
8991            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8992                    callingUid);
8993
8994            // TODO: Improve with MRU list from all ActivityStacks.
8995            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8996        }
8997
8998        return list;
8999    }
9000
9001    /**
9002     * Creates a new RecentTaskInfo from a TaskRecord.
9003     */
9004    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9005        // Update the task description to reflect any changes in the task stack
9006        tr.updateTaskDescription();
9007
9008        // Compose the recent task info
9009        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9010        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9011        rti.persistentId = tr.taskId;
9012        rti.baseIntent = new Intent(tr.getBaseIntent());
9013        rti.origActivity = tr.origActivity;
9014        rti.realActivity = tr.realActivity;
9015        rti.description = tr.lastDescription;
9016        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9017        rti.userId = tr.userId;
9018        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9019        rti.firstActiveTime = tr.firstActiveTime;
9020        rti.lastActiveTime = tr.lastActiveTime;
9021        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9022        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9023        rti.numActivities = 0;
9024        if (tr.mBounds != null) {
9025            rti.bounds = new Rect(tr.mBounds);
9026        }
9027        rti.isDockable = tr.canGoInDockedStack();
9028        rti.resizeMode = tr.mResizeMode;
9029
9030        ActivityRecord base = null;
9031        ActivityRecord top = null;
9032        ActivityRecord tmp;
9033
9034        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9035            tmp = tr.mActivities.get(i);
9036            if (tmp.finishing) {
9037                continue;
9038            }
9039            base = tmp;
9040            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9041                top = base;
9042            }
9043            rti.numActivities++;
9044        }
9045
9046        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9047        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9048
9049        return rti;
9050    }
9051
9052    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9053        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9054                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9055        if (!allowed) {
9056            if (checkPermission(android.Manifest.permission.GET_TASKS,
9057                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9058                // Temporary compatibility: some existing apps on the system image may
9059                // still be requesting the old permission and not switched to the new
9060                // one; if so, we'll still allow them full access.  This means we need
9061                // to see if they are holding the old permission and are a system app.
9062                try {
9063                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9064                        allowed = true;
9065                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9066                                + " is using old GET_TASKS but privileged; allowing");
9067                    }
9068                } catch (RemoteException e) {
9069                }
9070            }
9071        }
9072        if (!allowed) {
9073            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9074                    + " does not hold REAL_GET_TASKS; limiting output");
9075        }
9076        return allowed;
9077    }
9078
9079    @Override
9080    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9081            int userId) {
9082        final int callingUid = Binder.getCallingUid();
9083        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9084                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9085
9086        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9087        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9088        synchronized (this) {
9089            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9090                    callingUid);
9091            final boolean detailed = checkCallingPermission(
9092                    android.Manifest.permission.GET_DETAILED_TASKS)
9093                    == PackageManager.PERMISSION_GRANTED;
9094
9095            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9096                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9097                return ParceledListSlice.emptyList();
9098            }
9099            mRecentTasks.loadUserRecentsLocked(userId);
9100
9101            final int recentsCount = mRecentTasks.size();
9102            ArrayList<ActivityManager.RecentTaskInfo> res =
9103                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9104
9105            final Set<Integer> includedUsers;
9106            if (includeProfiles) {
9107                includedUsers = mUserController.getProfileIds(userId);
9108            } else {
9109                includedUsers = new HashSet<>();
9110            }
9111            includedUsers.add(Integer.valueOf(userId));
9112
9113            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9114                TaskRecord tr = mRecentTasks.get(i);
9115                // Only add calling user or related users recent tasks
9116                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9117                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9118                    continue;
9119                }
9120
9121                if (tr.realActivitySuspended) {
9122                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9123                    continue;
9124                }
9125
9126                // Return the entry if desired by the caller.  We always return
9127                // the first entry, because callers always expect this to be the
9128                // foreground app.  We may filter others if the caller has
9129                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9130                // we should exclude the entry.
9131
9132                if (i == 0
9133                        || withExcluded
9134                        || (tr.intent == null)
9135                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9136                                == 0)) {
9137                    if (!allowed) {
9138                        // If the caller doesn't have the GET_TASKS permission, then only
9139                        // allow them to see a small subset of tasks -- their own and home.
9140                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9141                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9142                            continue;
9143                        }
9144                    }
9145                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9146                        if (tr.stack != null && tr.stack.isHomeStack()) {
9147                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9148                                    "Skipping, home stack task: " + tr);
9149                            continue;
9150                        }
9151                    }
9152                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9153                        final ActivityStack stack = tr.stack;
9154                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9155                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9156                                    "Skipping, top task in docked stack: " + tr);
9157                            continue;
9158                        }
9159                    }
9160                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9161                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9162                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9163                                    "Skipping, pinned stack task: " + tr);
9164                            continue;
9165                        }
9166                    }
9167                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9168                        // Don't include auto remove tasks that are finished or finishing.
9169                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9170                                "Skipping, auto-remove without activity: " + tr);
9171                        continue;
9172                    }
9173                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9174                            && !tr.isAvailable) {
9175                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9176                                "Skipping, unavail real act: " + tr);
9177                        continue;
9178                    }
9179
9180                    if (!tr.mUserSetupComplete) {
9181                        // Don't include task launched while user is not done setting-up.
9182                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9183                                "Skipping, user setup not complete: " + tr);
9184                        continue;
9185                    }
9186
9187                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9188                    if (!detailed) {
9189                        rti.baseIntent.replaceExtras((Bundle)null);
9190                    }
9191
9192                    res.add(rti);
9193                    maxNum--;
9194                }
9195            }
9196            return new ParceledListSlice<>(res);
9197        }
9198    }
9199
9200    @Override
9201    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9202        synchronized (this) {
9203            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9204                    "getTaskThumbnail()");
9205            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9206                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9207            if (tr != null) {
9208                return tr.getTaskThumbnailLocked();
9209            }
9210        }
9211        return null;
9212    }
9213
9214    @Override
9215    public int addAppTask(IBinder activityToken, Intent intent,
9216            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9217        final int callingUid = Binder.getCallingUid();
9218        final long callingIdent = Binder.clearCallingIdentity();
9219
9220        try {
9221            synchronized (this) {
9222                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9223                if (r == null) {
9224                    throw new IllegalArgumentException("Activity does not exist; token="
9225                            + activityToken);
9226                }
9227                ComponentName comp = intent.getComponent();
9228                if (comp == null) {
9229                    throw new IllegalArgumentException("Intent " + intent
9230                            + " must specify explicit component");
9231                }
9232                if (thumbnail.getWidth() != mThumbnailWidth
9233                        || thumbnail.getHeight() != mThumbnailHeight) {
9234                    throw new IllegalArgumentException("Bad thumbnail size: got "
9235                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9236                            + mThumbnailWidth + "x" + mThumbnailHeight);
9237                }
9238                if (intent.getSelector() != null) {
9239                    intent.setSelector(null);
9240                }
9241                if (intent.getSourceBounds() != null) {
9242                    intent.setSourceBounds(null);
9243                }
9244                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9245                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9246                        // The caller has added this as an auto-remove task...  that makes no
9247                        // sense, so turn off auto-remove.
9248                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9249                    }
9250                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9251                    // Must be a new task.
9252                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9253                }
9254                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9255                    mLastAddedTaskActivity = null;
9256                }
9257                ActivityInfo ainfo = mLastAddedTaskActivity;
9258                if (ainfo == null) {
9259                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9260                            comp, 0, UserHandle.getUserId(callingUid));
9261                    if (ainfo.applicationInfo.uid != callingUid) {
9262                        throw new SecurityException(
9263                                "Can't add task for another application: target uid="
9264                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9265                    }
9266                }
9267
9268                // Use the full screen as the context for the task thumbnail
9269                final Point displaySize = new Point();
9270                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9271                r.task.stack.getDisplaySize(displaySize);
9272                thumbnailInfo.taskWidth = displaySize.x;
9273                thumbnailInfo.taskHeight = displaySize.y;
9274                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9275
9276                TaskRecord task = new TaskRecord(this,
9277                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9278                        ainfo, intent, description, thumbnailInfo);
9279
9280                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9281                if (trimIdx >= 0) {
9282                    // If this would have caused a trim, then we'll abort because that
9283                    // means it would be added at the end of the list but then just removed.
9284                    return INVALID_TASK_ID;
9285                }
9286
9287                final int N = mRecentTasks.size();
9288                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9289                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9290                    tr.removedFromRecents();
9291                }
9292
9293                task.inRecents = true;
9294                mRecentTasks.add(task);
9295                r.task.stack.addTask(task, false, "addAppTask");
9296
9297                task.setLastThumbnailLocked(thumbnail);
9298                task.freeLastThumbnail();
9299
9300                return task.taskId;
9301            }
9302        } finally {
9303            Binder.restoreCallingIdentity(callingIdent);
9304        }
9305    }
9306
9307    @Override
9308    public Point getAppTaskThumbnailSize() {
9309        synchronized (this) {
9310            return new Point(mThumbnailWidth,  mThumbnailHeight);
9311        }
9312    }
9313
9314    @Override
9315    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9316        synchronized (this) {
9317            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9318            if (r != null) {
9319                r.setTaskDescription(td);
9320                r.task.updateTaskDescription();
9321            }
9322        }
9323    }
9324
9325    @Override
9326    public void setTaskResizeable(int taskId, int resizeableMode) {
9327        synchronized (this) {
9328            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9329                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9330            if (task == null) {
9331                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9332                return;
9333            }
9334            if (task.mResizeMode != resizeableMode) {
9335                task.mResizeMode = resizeableMode;
9336                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9337                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9338                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9339            }
9340        }
9341    }
9342
9343    @Override
9344    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9345        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9346        long ident = Binder.clearCallingIdentity();
9347        try {
9348            synchronized (this) {
9349                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9350                if (task == null) {
9351                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9352                    return;
9353                }
9354                int stackId = task.stack.mStackId;
9355                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9356                // in crop windows resize mode or if the task size is affected by the docked stack
9357                // changing size. No need to update configuration.
9358                if (bounds != null && task.inCropWindowsResizeMode()
9359                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9360                    mWindowManager.scrollTask(task.taskId, bounds);
9361                    return;
9362                }
9363
9364                // Place the task in the right stack if it isn't there already based on
9365                // the requested bounds.
9366                // The stack transition logic is:
9367                // - a null bounds on a freeform task moves that task to fullscreen
9368                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9369                //   that task to freeform
9370                // - otherwise the task is not moved
9371                if (!StackId.isTaskResizeAllowed(stackId)) {
9372                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9373                }
9374                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9375                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9376                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9377                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9378                }
9379                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9380                if (stackId != task.stack.mStackId) {
9381                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9382                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9383                    preserveWindow = false;
9384                }
9385
9386                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9387                        false /* deferResume */);
9388            }
9389        } finally {
9390            Binder.restoreCallingIdentity(ident);
9391        }
9392    }
9393
9394    @Override
9395    public Rect getTaskBounds(int taskId) {
9396        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9397        long ident = Binder.clearCallingIdentity();
9398        Rect rect = new Rect();
9399        try {
9400            synchronized (this) {
9401                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9402                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9403                if (task == null) {
9404                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9405                    return rect;
9406                }
9407                if (task.stack != null) {
9408                    // Return the bounds from window manager since it will be adjusted for various
9409                    // things like the presense of a docked stack for tasks that aren't resizeable.
9410                    mWindowManager.getTaskBounds(task.taskId, rect);
9411                } else {
9412                    // Task isn't in window manager yet since it isn't associated with a stack.
9413                    // Return the persist value from activity manager
9414                    if (task.mBounds != null) {
9415                        rect.set(task.mBounds);
9416                    } else if (task.mLastNonFullscreenBounds != null) {
9417                        rect.set(task.mLastNonFullscreenBounds);
9418                    }
9419                }
9420            }
9421        } finally {
9422            Binder.restoreCallingIdentity(ident);
9423        }
9424        return rect;
9425    }
9426
9427    @Override
9428    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9429        if (userId != UserHandle.getCallingUserId()) {
9430            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9431                    "getTaskDescriptionIcon");
9432        }
9433        final File passedIconFile = new File(filePath);
9434        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9435                passedIconFile.getName());
9436        if (!legitIconFile.getPath().equals(filePath)
9437                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9438            throw new IllegalArgumentException("Bad file path: " + filePath
9439                    + " passed for userId " + userId);
9440        }
9441        return mRecentTasks.getTaskDescriptionIcon(filePath);
9442    }
9443
9444    @Override
9445    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9446            throws RemoteException {
9447        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9448                opts.getCustomInPlaceResId() == 0) {
9449            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9450                    "with valid animation");
9451        }
9452        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9453        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9454                opts.getCustomInPlaceResId());
9455        mWindowManager.executeAppTransition();
9456    }
9457
9458    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9459            boolean removeFromRecents) {
9460        if (removeFromRecents) {
9461            mRecentTasks.remove(tr);
9462            tr.removedFromRecents();
9463        }
9464        ComponentName component = tr.getBaseIntent().getComponent();
9465        if (component == null) {
9466            Slog.w(TAG, "No component for base intent of task: " + tr);
9467            return;
9468        }
9469
9470        // Find any running services associated with this app and stop if needed.
9471        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9472
9473        if (!killProcess) {
9474            return;
9475        }
9476
9477        // Determine if the process(es) for this task should be killed.
9478        final String pkg = component.getPackageName();
9479        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9480        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9481        for (int i = 0; i < pmap.size(); i++) {
9482
9483            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9484            for (int j = 0; j < uids.size(); j++) {
9485                ProcessRecord proc = uids.valueAt(j);
9486                if (proc.userId != tr.userId) {
9487                    // Don't kill process for a different user.
9488                    continue;
9489                }
9490                if (proc == mHomeProcess) {
9491                    // Don't kill the home process along with tasks from the same package.
9492                    continue;
9493                }
9494                if (!proc.pkgList.containsKey(pkg)) {
9495                    // Don't kill process that is not associated with this task.
9496                    continue;
9497                }
9498
9499                for (int k = 0; k < proc.activities.size(); k++) {
9500                    TaskRecord otherTask = proc.activities.get(k).task;
9501                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9502                        // Don't kill process(es) that has an activity in a different task that is
9503                        // also in recents.
9504                        return;
9505                    }
9506                }
9507
9508                if (proc.foregroundServices) {
9509                    // Don't kill process(es) with foreground service.
9510                    return;
9511                }
9512
9513                // Add process to kill list.
9514                procsToKill.add(proc);
9515            }
9516        }
9517
9518        // Kill the running processes.
9519        for (int i = 0; i < procsToKill.size(); i++) {
9520            ProcessRecord pr = procsToKill.get(i);
9521            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9522                    && pr.curReceiver == null) {
9523                pr.kill("remove task", true);
9524            } else {
9525                // We delay killing processes that are not in the background or running a receiver.
9526                pr.waitingToKill = "remove task";
9527            }
9528        }
9529    }
9530
9531    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9532        // Remove all tasks with activities in the specified package from the list of recent tasks
9533        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9534            TaskRecord tr = mRecentTasks.get(i);
9535            if (tr.userId != userId) continue;
9536
9537            ComponentName cn = tr.intent.getComponent();
9538            if (cn != null && cn.getPackageName().equals(packageName)) {
9539                // If the package name matches, remove the task.
9540                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9541            }
9542        }
9543    }
9544
9545    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9546            int userId) {
9547
9548        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9549            TaskRecord tr = mRecentTasks.get(i);
9550            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9551                continue;
9552            }
9553
9554            ComponentName cn = tr.intent.getComponent();
9555            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9556                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9557            if (sameComponent) {
9558                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9559            }
9560        }
9561    }
9562
9563    /**
9564     * Removes the task with the specified task id.
9565     *
9566     * @param taskId Identifier of the task to be removed.
9567     * @param killProcess Kill any process associated with the task if possible.
9568     * @param removeFromRecents Whether to also remove the task from recents.
9569     * @return Returns true if the given task was found and removed.
9570     */
9571    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9572            boolean removeFromRecents) {
9573        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9574                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9575        if (tr != null) {
9576            tr.removeTaskActivitiesLocked();
9577            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9578            if (tr.isPersistable) {
9579                notifyTaskPersisterLocked(null, true);
9580            }
9581            return true;
9582        }
9583        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9584        return false;
9585    }
9586
9587    @Override
9588    public void removeStack(int stackId) {
9589        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9590        if (stackId == HOME_STACK_ID) {
9591            throw new IllegalArgumentException("Removing home stack is not allowed.");
9592        }
9593
9594        synchronized (this) {
9595            final long ident = Binder.clearCallingIdentity();
9596            try {
9597                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9598                if (stack == null) {
9599                    return;
9600                }
9601                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9602                for (int i = tasks.size() - 1; i >= 0; i--) {
9603                    removeTaskByIdLocked(
9604                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9605                }
9606            } finally {
9607                Binder.restoreCallingIdentity(ident);
9608            }
9609        }
9610    }
9611
9612    @Override
9613    public boolean removeTask(int taskId) {
9614        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9615        synchronized (this) {
9616            final long ident = Binder.clearCallingIdentity();
9617            try {
9618                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9619            } finally {
9620                Binder.restoreCallingIdentity(ident);
9621            }
9622        }
9623    }
9624
9625    /**
9626     * TODO: Add mController hook
9627     */
9628    @Override
9629    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9630        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9631
9632        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9633        synchronized(this) {
9634            moveTaskToFrontLocked(taskId, flags, bOptions);
9635        }
9636    }
9637
9638    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9639        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9640
9641        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9642                Binder.getCallingUid(), -1, -1, "Task to front")) {
9643            ActivityOptions.abort(options);
9644            return;
9645        }
9646        final long origId = Binder.clearCallingIdentity();
9647        try {
9648            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9649            if (task == null) {
9650                Slog.d(TAG, "Could not find task for id: "+ taskId);
9651                return;
9652            }
9653            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9654                mStackSupervisor.showLockTaskToast();
9655                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9656                return;
9657            }
9658            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9659            if (prev != null && prev.isRecentsActivity()) {
9660                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9661            }
9662            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9663                    false /* forceNonResizable */);
9664        } finally {
9665            Binder.restoreCallingIdentity(origId);
9666        }
9667        ActivityOptions.abort(options);
9668    }
9669
9670    /**
9671     * Moves an activity, and all of the other activities within the same task, to the bottom
9672     * of the history stack.  The activity's order within the task is unchanged.
9673     *
9674     * @param token A reference to the activity we wish to move
9675     * @param nonRoot If false then this only works if the activity is the root
9676     *                of a task; if true it will work for any activity in a task.
9677     * @return Returns true if the move completed, false if not.
9678     */
9679    @Override
9680    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9681        enforceNotIsolatedCaller("moveActivityTaskToBack");
9682        synchronized(this) {
9683            final long origId = Binder.clearCallingIdentity();
9684            try {
9685                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9686                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9687                if (task != null) {
9688                    if (mStackSupervisor.isLockedTask(task)) {
9689                        mStackSupervisor.showLockTaskToast();
9690                        return false;
9691                    }
9692                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9693                }
9694            } finally {
9695                Binder.restoreCallingIdentity(origId);
9696            }
9697        }
9698        return false;
9699    }
9700
9701    @Override
9702    public void moveTaskBackwards(int task) {
9703        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9704                "moveTaskBackwards()");
9705
9706        synchronized(this) {
9707            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9708                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9709                return;
9710            }
9711            final long origId = Binder.clearCallingIdentity();
9712            moveTaskBackwardsLocked(task);
9713            Binder.restoreCallingIdentity(origId);
9714        }
9715    }
9716
9717    private final void moveTaskBackwardsLocked(int task) {
9718        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9719    }
9720
9721    @Override
9722    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9723            IActivityContainerCallback callback) throws RemoteException {
9724        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9725        synchronized (this) {
9726            if (parentActivityToken == null) {
9727                throw new IllegalArgumentException("parent token must not be null");
9728            }
9729            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9730            if (r == null) {
9731                return null;
9732            }
9733            if (callback == null) {
9734                throw new IllegalArgumentException("callback must not be null");
9735            }
9736            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9737        }
9738    }
9739
9740    @Override
9741    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9742        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9743        synchronized (this) {
9744            mStackSupervisor.deleteActivityContainer(container);
9745        }
9746    }
9747
9748    @Override
9749    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9750        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9751        synchronized (this) {
9752            final int stackId = mStackSupervisor.getNextStackId();
9753            final ActivityStack stack =
9754                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9755            if (stack == null) {
9756                return null;
9757            }
9758            return stack.mActivityContainer;
9759        }
9760    }
9761
9762    @Override
9763    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9764        synchronized (this) {
9765            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9766            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9767                return stack.mActivityContainer.getDisplayId();
9768            }
9769            return Display.DEFAULT_DISPLAY;
9770        }
9771    }
9772
9773    @Override
9774    public int getActivityStackId(IBinder token) throws RemoteException {
9775        synchronized (this) {
9776            ActivityStack stack = ActivityRecord.getStackLocked(token);
9777            if (stack == null) {
9778                return INVALID_STACK_ID;
9779            }
9780            return stack.mStackId;
9781        }
9782    }
9783
9784    @Override
9785    public void exitFreeformMode(IBinder token) throws RemoteException {
9786        synchronized (this) {
9787            long ident = Binder.clearCallingIdentity();
9788            try {
9789                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9790                if (r == null) {
9791                    throw new IllegalArgumentException(
9792                            "exitFreeformMode: No activity record matching token=" + token);
9793                }
9794                final ActivityStack stack = r.getStackLocked(token);
9795                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9796                    throw new IllegalStateException(
9797                            "exitFreeformMode: You can only go fullscreen from freeform.");
9798                }
9799                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9800                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9801                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9802            } finally {
9803                Binder.restoreCallingIdentity(ident);
9804            }
9805        }
9806    }
9807
9808    @Override
9809    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9810        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9811        if (stackId == HOME_STACK_ID) {
9812            throw new IllegalArgumentException(
9813                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9814        }
9815        synchronized (this) {
9816            long ident = Binder.clearCallingIdentity();
9817            try {
9818                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9819                        + " to stackId=" + stackId + " toTop=" + toTop);
9820                if (stackId == DOCKED_STACK_ID) {
9821                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9822                            null /* initialBounds */);
9823                }
9824                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9825                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9826                if (result && stackId == DOCKED_STACK_ID) {
9827                    // If task moved to docked stack - show recents if needed.
9828                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9829                            "moveTaskToDockedStack");
9830                }
9831            } finally {
9832                Binder.restoreCallingIdentity(ident);
9833            }
9834        }
9835    }
9836
9837    @Override
9838    public void swapDockedAndFullscreenStack() throws RemoteException {
9839        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9840        synchronized (this) {
9841            long ident = Binder.clearCallingIdentity();
9842            try {
9843                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9844                        FULLSCREEN_WORKSPACE_STACK_ID);
9845                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9846                        : null;
9847                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9848                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9849                        : null;
9850                if (topTask == null || tasks == null || tasks.size() == 0) {
9851                    Slog.w(TAG,
9852                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9853                    return;
9854                }
9855
9856                // TODO: App transition
9857                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9858
9859                // Defer the resume so resume/pausing while moving stacks is dangerous.
9860                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9861                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9862                        ANIMATE, true /* deferResume */);
9863                final int size = tasks.size();
9864                for (int i = 0; i < size; i++) {
9865                    final int id = tasks.get(i).taskId;
9866                    if (id == topTask.taskId) {
9867                        continue;
9868                    }
9869                    mStackSupervisor.moveTaskToStackLocked(id,
9870                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9871                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9872                }
9873
9874                // Because we deferred the resume, to avoid conflicts with stack switches while
9875                // resuming, we need to do it after all the tasks are moved.
9876                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9877                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9878
9879                mWindowManager.executeAppTransition();
9880            } finally {
9881                Binder.restoreCallingIdentity(ident);
9882            }
9883        }
9884    }
9885
9886    /**
9887     * Moves the input task to the docked stack.
9888     *
9889     * @param taskId Id of task to move.
9890     * @param createMode The mode the docked stack should be created in if it doesn't exist
9891     *                   already. See
9892     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9893     *                   and
9894     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9895     * @param toTop If the task and stack should be moved to the top.
9896     * @param animate Whether we should play an animation for the moving the task
9897     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9898     *                      docked stack. Pass {@code null} to use default bounds.
9899     */
9900    @Override
9901    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9902            Rect initialBounds, boolean moveHomeStackFront) {
9903        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9904        synchronized (this) {
9905            long ident = Binder.clearCallingIdentity();
9906            try {
9907                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9908                        + " to createMode=" + createMode + " toTop=" + toTop);
9909                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9910                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9911                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9912                        animate, DEFER_RESUME);
9913                if (moved) {
9914                    if (moveHomeStackFront) {
9915                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9916                    }
9917                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9918                }
9919                return moved;
9920            } finally {
9921                Binder.restoreCallingIdentity(ident);
9922            }
9923        }
9924    }
9925
9926    /**
9927     * Moves the top activity in the input stackId to the pinned stack.
9928     *
9929     * @param stackId Id of stack to move the top activity to pinned stack.
9930     * @param bounds Bounds to use for pinned stack.
9931     *
9932     * @return True if the top activity of the input stack was successfully moved to the pinned
9933     *          stack.
9934     */
9935    @Override
9936    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9937        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9938        synchronized (this) {
9939            if (!mSupportsPictureInPicture) {
9940                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9941                        + "Device doesn't support picture-in-pciture mode");
9942            }
9943
9944            long ident = Binder.clearCallingIdentity();
9945            try {
9946                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9947            } finally {
9948                Binder.restoreCallingIdentity(ident);
9949            }
9950        }
9951    }
9952
9953    @Override
9954    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9955            boolean preserveWindows, boolean animate, int animationDuration) {
9956        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9957        long ident = Binder.clearCallingIdentity();
9958        try {
9959            synchronized (this) {
9960                if (animate) {
9961                    if (stackId == PINNED_STACK_ID) {
9962                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9963                    } else {
9964                        throw new IllegalArgumentException("Stack: " + stackId
9965                                + " doesn't support animated resize.");
9966                    }
9967                } else {
9968                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9969                            null /* tempTaskInsetBounds */, preserveWindows,
9970                            allowResizeInDockedMode, !DEFER_RESUME);
9971                }
9972            }
9973        } finally {
9974            Binder.restoreCallingIdentity(ident);
9975        }
9976    }
9977
9978    @Override
9979    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9980            Rect tempDockedTaskInsetBounds,
9981            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9982        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9983                "resizeDockedStack()");
9984        long ident = Binder.clearCallingIdentity();
9985        try {
9986            synchronized (this) {
9987                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9988                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9989                        PRESERVE_WINDOWS);
9990            }
9991        } finally {
9992            Binder.restoreCallingIdentity(ident);
9993        }
9994    }
9995
9996    @Override
9997    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9998        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9999                "resizePinnedStack()");
10000        final long ident = Binder.clearCallingIdentity();
10001        try {
10002            synchronized (this) {
10003                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10004            }
10005        } finally {
10006            Binder.restoreCallingIdentity(ident);
10007        }
10008    }
10009
10010    @Override
10011    public void positionTaskInStack(int taskId, int stackId, int position) {
10012        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10013        if (stackId == HOME_STACK_ID) {
10014            throw new IllegalArgumentException(
10015                    "positionTaskInStack: Attempt to change the position of task "
10016                    + taskId + " in/to home stack");
10017        }
10018        synchronized (this) {
10019            long ident = Binder.clearCallingIdentity();
10020            try {
10021                if (DEBUG_STACK) Slog.d(TAG_STACK,
10022                        "positionTaskInStack: positioning task=" + taskId
10023                        + " in stackId=" + stackId + " at position=" + position);
10024                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10025            } finally {
10026                Binder.restoreCallingIdentity(ident);
10027            }
10028        }
10029    }
10030
10031    @Override
10032    public List<StackInfo> getAllStackInfos() {
10033        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10034        long ident = Binder.clearCallingIdentity();
10035        try {
10036            synchronized (this) {
10037                return mStackSupervisor.getAllStackInfosLocked();
10038            }
10039        } finally {
10040            Binder.restoreCallingIdentity(ident);
10041        }
10042    }
10043
10044    @Override
10045    public StackInfo getStackInfo(int stackId) {
10046        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10047        long ident = Binder.clearCallingIdentity();
10048        try {
10049            synchronized (this) {
10050                return mStackSupervisor.getStackInfoLocked(stackId);
10051            }
10052        } finally {
10053            Binder.restoreCallingIdentity(ident);
10054        }
10055    }
10056
10057    @Override
10058    public boolean isInHomeStack(int taskId) {
10059        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10060        long ident = Binder.clearCallingIdentity();
10061        try {
10062            synchronized (this) {
10063                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10064                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10065                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10066            }
10067        } finally {
10068            Binder.restoreCallingIdentity(ident);
10069        }
10070    }
10071
10072    @Override
10073    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10074        synchronized(this) {
10075            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10076        }
10077    }
10078
10079    @Override
10080    public void updateDeviceOwner(String packageName) {
10081        final int callingUid = Binder.getCallingUid();
10082        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10083            throw new SecurityException("updateDeviceOwner called from non-system process");
10084        }
10085        synchronized (this) {
10086            mDeviceOwnerName = packageName;
10087        }
10088    }
10089
10090    @Override
10091    public void updateLockTaskPackages(int userId, String[] packages) {
10092        final int callingUid = Binder.getCallingUid();
10093        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10094            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10095                    "updateLockTaskPackages()");
10096        }
10097        synchronized (this) {
10098            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10099                    Arrays.toString(packages));
10100            mLockTaskPackages.put(userId, packages);
10101            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10102        }
10103    }
10104
10105
10106    void startLockTaskModeLocked(TaskRecord task) {
10107        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10108        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10109            return;
10110        }
10111
10112        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10113        // is initiated by system after the pinning request was shown and locked mode is initiated
10114        // by an authorized app directly
10115        final int callingUid = Binder.getCallingUid();
10116        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10117        long ident = Binder.clearCallingIdentity();
10118        try {
10119            if (!isSystemInitiated) {
10120                task.mLockTaskUid = callingUid;
10121                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10122                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10123                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10124                    StatusBarManagerInternal statusBarManager =
10125                            LocalServices.getService(StatusBarManagerInternal.class);
10126                    if (statusBarManager != null) {
10127                        statusBarManager.showScreenPinningRequest(task.taskId);
10128                    }
10129                    return;
10130                }
10131
10132                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10133                if (stack == null || task != stack.topTask()) {
10134                    throw new IllegalArgumentException("Invalid task, not in foreground");
10135                }
10136            }
10137            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10138                    "Locking fully");
10139            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10140                    ActivityManager.LOCK_TASK_MODE_PINNED :
10141                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10142                    "startLockTask", true);
10143        } finally {
10144            Binder.restoreCallingIdentity(ident);
10145        }
10146    }
10147
10148    @Override
10149    public void startLockTaskMode(int taskId) {
10150        synchronized (this) {
10151            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10152            if (task != null) {
10153                startLockTaskModeLocked(task);
10154            }
10155        }
10156    }
10157
10158    @Override
10159    public void startLockTaskMode(IBinder token) {
10160        synchronized (this) {
10161            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10162            if (r == null) {
10163                return;
10164            }
10165            final TaskRecord task = r.task;
10166            if (task != null) {
10167                startLockTaskModeLocked(task);
10168            }
10169        }
10170    }
10171
10172    @Override
10173    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10174        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10175        // This makes inner call to look as if it was initiated by system.
10176        long ident = Binder.clearCallingIdentity();
10177        try {
10178            synchronized (this) {
10179                startLockTaskMode(taskId);
10180            }
10181        } finally {
10182            Binder.restoreCallingIdentity(ident);
10183        }
10184    }
10185
10186    @Override
10187    public void stopLockTaskMode() {
10188        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10189        if (lockTask == null) {
10190            // Our work here is done.
10191            return;
10192        }
10193
10194        final int callingUid = Binder.getCallingUid();
10195        final int lockTaskUid = lockTask.mLockTaskUid;
10196        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10197        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10198            // Done.
10199            return;
10200        } else {
10201            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10202            // It is possible lockTaskMode was started by the system process because
10203            // android:lockTaskMode is set to a locking value in the application manifest
10204            // instead of the app calling startLockTaskMode. In this case
10205            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10206            // {@link TaskRecord.effectiveUid} instead. Also caller with
10207            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10208            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10209                    && callingUid != lockTaskUid
10210                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10211                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10212                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10213            }
10214        }
10215        long ident = Binder.clearCallingIdentity();
10216        try {
10217            Log.d(TAG, "stopLockTaskMode");
10218            // Stop lock task
10219            synchronized (this) {
10220                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10221                        "stopLockTask", true);
10222            }
10223            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10224            if (tm != null) {
10225                tm.showInCallScreen(false);
10226            }
10227        } finally {
10228            Binder.restoreCallingIdentity(ident);
10229        }
10230    }
10231
10232    /**
10233     * This API should be called by SystemUI only when user perform certain action to dismiss
10234     * lock task mode. We should only dismiss pinned lock task mode in this case.
10235     */
10236    @Override
10237    public void stopSystemLockTaskMode() throws RemoteException {
10238        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10239            stopLockTaskMode();
10240        } else {
10241            mStackSupervisor.showLockTaskToast();
10242        }
10243    }
10244
10245    @Override
10246    public boolean isInLockTaskMode() {
10247        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10248    }
10249
10250    @Override
10251    public int getLockTaskModeState() {
10252        synchronized (this) {
10253            return mStackSupervisor.getLockTaskModeState();
10254        }
10255    }
10256
10257    @Override
10258    public void showLockTaskEscapeMessage(IBinder token) {
10259        synchronized (this) {
10260            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10261            if (r == null) {
10262                return;
10263            }
10264            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10265        }
10266    }
10267
10268    // =========================================================
10269    // CONTENT PROVIDERS
10270    // =========================================================
10271
10272    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10273        List<ProviderInfo> providers = null;
10274        try {
10275            providers = AppGlobals.getPackageManager()
10276                    .queryContentProviders(app.processName, app.uid,
10277                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10278                                    | MATCH_DEBUG_TRIAGED_MISSING)
10279                    .getList();
10280        } catch (RemoteException ex) {
10281        }
10282        if (DEBUG_MU) Slog.v(TAG_MU,
10283                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10284        int userId = app.userId;
10285        if (providers != null) {
10286            int N = providers.size();
10287            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10288            for (int i=0; i<N; i++) {
10289                // TODO: keep logic in sync with installEncryptionUnawareProviders
10290                ProviderInfo cpi =
10291                    (ProviderInfo)providers.get(i);
10292                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10293                        cpi.name, cpi.flags);
10294                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10295                    // This is a singleton provider, but a user besides the
10296                    // default user is asking to initialize a process it runs
10297                    // in...  well, no, it doesn't actually run in this process,
10298                    // it runs in the process of the default user.  Get rid of it.
10299                    providers.remove(i);
10300                    N--;
10301                    i--;
10302                    continue;
10303                }
10304
10305                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10306                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10307                if (cpr == null) {
10308                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10309                    mProviderMap.putProviderByClass(comp, cpr);
10310                }
10311                if (DEBUG_MU) Slog.v(TAG_MU,
10312                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10313                app.pubProviders.put(cpi.name, cpr);
10314                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10315                    // Don't add this if it is a platform component that is marked
10316                    // to run in multiple processes, because this is actually
10317                    // part of the framework so doesn't make sense to track as a
10318                    // separate apk in the process.
10319                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10320                            mProcessStats);
10321                }
10322                notifyPackageUse(cpi.applicationInfo.packageName,
10323                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10324            }
10325        }
10326        return providers;
10327    }
10328
10329    /**
10330     * Check if {@link ProcessRecord} has a possible chance at accessing the
10331     * given {@link ProviderInfo}. Final permission checking is always done
10332     * in {@link ContentProvider}.
10333     */
10334    private final String checkContentProviderPermissionLocked(
10335            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10336        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10337        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10338        boolean checkedGrants = false;
10339        if (checkUser) {
10340            // Looking for cross-user grants before enforcing the typical cross-users permissions
10341            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10342            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10343                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10344                    return null;
10345                }
10346                checkedGrants = true;
10347            }
10348            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10349                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10350            if (userId != tmpTargetUserId) {
10351                // When we actually went to determine the final targer user ID, this ended
10352                // up different than our initial check for the authority.  This is because
10353                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10354                // SELF.  So we need to re-check the grants again.
10355                checkedGrants = false;
10356            }
10357        }
10358        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10359                cpi.applicationInfo.uid, cpi.exported)
10360                == PackageManager.PERMISSION_GRANTED) {
10361            return null;
10362        }
10363        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10364                cpi.applicationInfo.uid, cpi.exported)
10365                == PackageManager.PERMISSION_GRANTED) {
10366            return null;
10367        }
10368
10369        PathPermission[] pps = cpi.pathPermissions;
10370        if (pps != null) {
10371            int i = pps.length;
10372            while (i > 0) {
10373                i--;
10374                PathPermission pp = pps[i];
10375                String pprperm = pp.getReadPermission();
10376                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10377                        cpi.applicationInfo.uid, cpi.exported)
10378                        == PackageManager.PERMISSION_GRANTED) {
10379                    return null;
10380                }
10381                String ppwperm = pp.getWritePermission();
10382                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10383                        cpi.applicationInfo.uid, cpi.exported)
10384                        == PackageManager.PERMISSION_GRANTED) {
10385                    return null;
10386                }
10387            }
10388        }
10389        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10390            return null;
10391        }
10392
10393        String msg;
10394        if (!cpi.exported) {
10395            msg = "Permission Denial: opening provider " + cpi.name
10396                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10397                    + ", uid=" + callingUid + ") that is not exported from uid "
10398                    + cpi.applicationInfo.uid;
10399        } else {
10400            msg = "Permission Denial: opening provider " + cpi.name
10401                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10402                    + ", uid=" + callingUid + ") requires "
10403                    + cpi.readPermission + " or " + cpi.writePermission;
10404        }
10405        Slog.w(TAG, msg);
10406        return msg;
10407    }
10408
10409    /**
10410     * Returns if the ContentProvider has granted a uri to callingUid
10411     */
10412    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10413        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10414        if (perms != null) {
10415            for (int i=perms.size()-1; i>=0; i--) {
10416                GrantUri grantUri = perms.keyAt(i);
10417                if (grantUri.sourceUserId == userId || !checkUser) {
10418                    if (matchesProvider(grantUri.uri, cpi)) {
10419                        return true;
10420                    }
10421                }
10422            }
10423        }
10424        return false;
10425    }
10426
10427    /**
10428     * Returns true if the uri authority is one of the authorities specified in the provider.
10429     */
10430    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10431        String uriAuth = uri.getAuthority();
10432        String cpiAuth = cpi.authority;
10433        if (cpiAuth.indexOf(';') == -1) {
10434            return cpiAuth.equals(uriAuth);
10435        }
10436        String[] cpiAuths = cpiAuth.split(";");
10437        int length = cpiAuths.length;
10438        for (int i = 0; i < length; i++) {
10439            if (cpiAuths[i].equals(uriAuth)) return true;
10440        }
10441        return false;
10442    }
10443
10444    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10445            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10446        if (r != null) {
10447            for (int i=0; i<r.conProviders.size(); i++) {
10448                ContentProviderConnection conn = r.conProviders.get(i);
10449                if (conn.provider == cpr) {
10450                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10451                            "Adding provider requested by "
10452                            + r.processName + " from process "
10453                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10454                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10455                    if (stable) {
10456                        conn.stableCount++;
10457                        conn.numStableIncs++;
10458                    } else {
10459                        conn.unstableCount++;
10460                        conn.numUnstableIncs++;
10461                    }
10462                    return conn;
10463                }
10464            }
10465            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10466            if (stable) {
10467                conn.stableCount = 1;
10468                conn.numStableIncs = 1;
10469            } else {
10470                conn.unstableCount = 1;
10471                conn.numUnstableIncs = 1;
10472            }
10473            cpr.connections.add(conn);
10474            r.conProviders.add(conn);
10475            startAssociationLocked(r.uid, r.processName, r.curProcState,
10476                    cpr.uid, cpr.name, cpr.info.processName);
10477            return conn;
10478        }
10479        cpr.addExternalProcessHandleLocked(externalProcessToken);
10480        return null;
10481    }
10482
10483    boolean decProviderCountLocked(ContentProviderConnection conn,
10484            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10485        if (conn != null) {
10486            cpr = conn.provider;
10487            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10488                    "Removing provider requested by "
10489                    + conn.client.processName + " from process "
10490                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10491                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10492            if (stable) {
10493                conn.stableCount--;
10494            } else {
10495                conn.unstableCount--;
10496            }
10497            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10498                cpr.connections.remove(conn);
10499                conn.client.conProviders.remove(conn);
10500                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10501                    // The client is more important than last activity -- note the time this
10502                    // is happening, so we keep the old provider process around a bit as last
10503                    // activity to avoid thrashing it.
10504                    if (cpr.proc != null) {
10505                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10506                    }
10507                }
10508                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10509                return true;
10510            }
10511            return false;
10512        }
10513        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10514        return false;
10515    }
10516
10517    private void checkTime(long startTime, String where) {
10518        long now = SystemClock.uptimeMillis();
10519        if ((now-startTime) > 50) {
10520            // If we are taking more than 50ms, log about it.
10521            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10522        }
10523    }
10524
10525    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10526            PROC_SPACE_TERM,
10527            PROC_SPACE_TERM|PROC_PARENS,
10528            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10529    };
10530
10531    private final long[] mProcessStateStatsLongs = new long[1];
10532
10533    boolean isProcessAliveLocked(ProcessRecord proc) {
10534        if (proc.procStatFile == null) {
10535            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10536        }
10537        mProcessStateStatsLongs[0] = 0;
10538        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10539                mProcessStateStatsLongs, null)) {
10540            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10541            return false;
10542        }
10543        final long state = mProcessStateStatsLongs[0];
10544        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10545                + (char)state);
10546        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10547    }
10548
10549    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10550            String name, IBinder token, boolean stable, int userId) {
10551        ContentProviderRecord cpr;
10552        ContentProviderConnection conn = null;
10553        ProviderInfo cpi = null;
10554
10555        synchronized(this) {
10556            long startTime = SystemClock.uptimeMillis();
10557
10558            ProcessRecord r = null;
10559            if (caller != null) {
10560                r = getRecordForAppLocked(caller);
10561                if (r == null) {
10562                    throw new SecurityException(
10563                            "Unable to find app for caller " + caller
10564                          + " (pid=" + Binder.getCallingPid()
10565                          + ") when getting content provider " + name);
10566                }
10567            }
10568
10569            boolean checkCrossUser = true;
10570
10571            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10572
10573            // First check if this content provider has been published...
10574            cpr = mProviderMap.getProviderByName(name, userId);
10575            // If that didn't work, check if it exists for user 0 and then
10576            // verify that it's a singleton provider before using it.
10577            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10578                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10579                if (cpr != null) {
10580                    cpi = cpr.info;
10581                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10582                            cpi.name, cpi.flags)
10583                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10584                        userId = UserHandle.USER_SYSTEM;
10585                        checkCrossUser = false;
10586                    } else {
10587                        cpr = null;
10588                        cpi = null;
10589                    }
10590                }
10591            }
10592
10593            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10594            if (providerRunning) {
10595                cpi = cpr.info;
10596                String msg;
10597                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10598                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10599                        != null) {
10600                    throw new SecurityException(msg);
10601                }
10602                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10603
10604                if (r != null && cpr.canRunHere(r)) {
10605                    // This provider has been published or is in the process
10606                    // of being published...  but it is also allowed to run
10607                    // in the caller's process, so don't make a connection
10608                    // and just let the caller instantiate its own instance.
10609                    ContentProviderHolder holder = cpr.newHolder(null);
10610                    // don't give caller the provider object, it needs
10611                    // to make its own.
10612                    holder.provider = null;
10613                    return holder;
10614                }
10615
10616                final long origId = Binder.clearCallingIdentity();
10617
10618                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10619
10620                // In this case the provider instance already exists, so we can
10621                // return it right away.
10622                conn = incProviderCountLocked(r, cpr, token, stable);
10623                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10624                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10625                        // If this is a perceptible app accessing the provider,
10626                        // make sure to count it as being accessed and thus
10627                        // back up on the LRU list.  This is good because
10628                        // content providers are often expensive to start.
10629                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10630                        updateLruProcessLocked(cpr.proc, false, null);
10631                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10632                    }
10633                }
10634
10635                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10636                final int verifiedAdj = cpr.proc.verifiedAdj;
10637                boolean success = updateOomAdjLocked(cpr.proc);
10638                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10639                // if the process has been successfully adjusted.  So to reduce races with
10640                // it, we will check whether the process still exists.  Note that this doesn't
10641                // completely get rid of races with LMK killing the process, but should make
10642                // them much smaller.
10643                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10644                    success = false;
10645                }
10646                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10647                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10648                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10649                // NOTE: there is still a race here where a signal could be
10650                // pending on the process even though we managed to update its
10651                // adj level.  Not sure what to do about this, but at least
10652                // the race is now smaller.
10653                if (!success) {
10654                    // Uh oh...  it looks like the provider's process
10655                    // has been killed on us.  We need to wait for a new
10656                    // process to be started, and make sure its death
10657                    // doesn't kill our process.
10658                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10659                            + " is crashing; detaching " + r);
10660                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10661                    checkTime(startTime, "getContentProviderImpl: before appDied");
10662                    appDiedLocked(cpr.proc);
10663                    checkTime(startTime, "getContentProviderImpl: after appDied");
10664                    if (!lastRef) {
10665                        // This wasn't the last ref our process had on
10666                        // the provider...  we have now been killed, bail.
10667                        return null;
10668                    }
10669                    providerRunning = false;
10670                    conn = null;
10671                } else {
10672                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10673                }
10674
10675                Binder.restoreCallingIdentity(origId);
10676            }
10677
10678            if (!providerRunning) {
10679                try {
10680                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10681                    cpi = AppGlobals.getPackageManager().
10682                        resolveContentProvider(name,
10683                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10684                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10685                } catch (RemoteException ex) {
10686                }
10687                if (cpi == null) {
10688                    return null;
10689                }
10690                // If the provider is a singleton AND
10691                // (it's a call within the same user || the provider is a
10692                // privileged app)
10693                // Then allow connecting to the singleton provider
10694                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10695                        cpi.name, cpi.flags)
10696                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10697                if (singleton) {
10698                    userId = UserHandle.USER_SYSTEM;
10699                }
10700                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10701                checkTime(startTime, "getContentProviderImpl: got app info for user");
10702
10703                String msg;
10704                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10705                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10706                        != null) {
10707                    throw new SecurityException(msg);
10708                }
10709                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10710
10711                if (!mProcessesReady
10712                        && !cpi.processName.equals("system")) {
10713                    // If this content provider does not run in the system
10714                    // process, and the system is not yet ready to run other
10715                    // processes, then fail fast instead of hanging.
10716                    throw new IllegalArgumentException(
10717                            "Attempt to launch content provider before system ready");
10718                }
10719
10720                // Make sure that the user who owns this provider is running.  If not,
10721                // we don't want to allow it to run.
10722                if (!mUserController.isUserRunningLocked(userId, 0)) {
10723                    Slog.w(TAG, "Unable to launch app "
10724                            + cpi.applicationInfo.packageName + "/"
10725                            + cpi.applicationInfo.uid + " for provider "
10726                            + name + ": user " + userId + " is stopped");
10727                    return null;
10728                }
10729
10730                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10731                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10732                cpr = mProviderMap.getProviderByClass(comp, userId);
10733                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10734                final boolean firstClass = cpr == null;
10735                if (firstClass) {
10736                    final long ident = Binder.clearCallingIdentity();
10737
10738                    // If permissions need a review before any of the app components can run,
10739                    // we return no provider and launch a review activity if the calling app
10740                    // is in the foreground.
10741                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10742                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10743                            return null;
10744                        }
10745                    }
10746
10747                    try {
10748                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10749                        ApplicationInfo ai =
10750                            AppGlobals.getPackageManager().
10751                                getApplicationInfo(
10752                                        cpi.applicationInfo.packageName,
10753                                        STOCK_PM_FLAGS, userId);
10754                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10755                        if (ai == null) {
10756                            Slog.w(TAG, "No package info for content provider "
10757                                    + cpi.name);
10758                            return null;
10759                        }
10760                        ai = getAppInfoForUser(ai, userId);
10761                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10762                    } catch (RemoteException ex) {
10763                        // pm is in same process, this will never happen.
10764                    } finally {
10765                        Binder.restoreCallingIdentity(ident);
10766                    }
10767                }
10768
10769                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10770
10771                if (r != null && cpr.canRunHere(r)) {
10772                    // If this is a multiprocess provider, then just return its
10773                    // info and allow the caller to instantiate it.  Only do
10774                    // this if the provider is the same user as the caller's
10775                    // process, or can run as root (so can be in any process).
10776                    return cpr.newHolder(null);
10777                }
10778
10779                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10780                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10781                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10782
10783                // This is single process, and our app is now connecting to it.
10784                // See if we are already in the process of launching this
10785                // provider.
10786                final int N = mLaunchingProviders.size();
10787                int i;
10788                for (i = 0; i < N; i++) {
10789                    if (mLaunchingProviders.get(i) == cpr) {
10790                        break;
10791                    }
10792                }
10793
10794                // If the provider is not already being launched, then get it
10795                // started.
10796                if (i >= N) {
10797                    final long origId = Binder.clearCallingIdentity();
10798
10799                    try {
10800                        // Content provider is now in use, its package can't be stopped.
10801                        try {
10802                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10803                            AppGlobals.getPackageManager().setPackageStoppedState(
10804                                    cpr.appInfo.packageName, false, userId);
10805                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10806                        } catch (RemoteException e) {
10807                        } catch (IllegalArgumentException e) {
10808                            Slog.w(TAG, "Failed trying to unstop package "
10809                                    + cpr.appInfo.packageName + ": " + e);
10810                        }
10811
10812                        // Use existing process if already started
10813                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10814                        ProcessRecord proc = getProcessRecordLocked(
10815                                cpi.processName, cpr.appInfo.uid, false);
10816                        if (proc != null && proc.thread != null && !proc.killed) {
10817                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10818                                    "Installing in existing process " + proc);
10819                            if (!proc.pubProviders.containsKey(cpi.name)) {
10820                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10821                                proc.pubProviders.put(cpi.name, cpr);
10822                                try {
10823                                    proc.thread.scheduleInstallProvider(cpi);
10824                                } catch (RemoteException e) {
10825                                }
10826                            }
10827                        } else {
10828                            checkTime(startTime, "getContentProviderImpl: before start process");
10829                            proc = startProcessLocked(cpi.processName,
10830                                    cpr.appInfo, false, 0, "content provider",
10831                                    new ComponentName(cpi.applicationInfo.packageName,
10832                                            cpi.name), false, false, false);
10833                            checkTime(startTime, "getContentProviderImpl: after start process");
10834                            if (proc == null) {
10835                                Slog.w(TAG, "Unable to launch app "
10836                                        + cpi.applicationInfo.packageName + "/"
10837                                        + cpi.applicationInfo.uid + " for provider "
10838                                        + name + ": process is bad");
10839                                return null;
10840                            }
10841                        }
10842                        cpr.launchingApp = proc;
10843                        mLaunchingProviders.add(cpr);
10844                    } finally {
10845                        Binder.restoreCallingIdentity(origId);
10846                    }
10847                }
10848
10849                checkTime(startTime, "getContentProviderImpl: updating data structures");
10850
10851                // Make sure the provider is published (the same provider class
10852                // may be published under multiple names).
10853                if (firstClass) {
10854                    mProviderMap.putProviderByClass(comp, cpr);
10855                }
10856
10857                mProviderMap.putProviderByName(name, cpr);
10858                conn = incProviderCountLocked(r, cpr, token, stable);
10859                if (conn != null) {
10860                    conn.waiting = true;
10861                }
10862            }
10863            checkTime(startTime, "getContentProviderImpl: done!");
10864        }
10865
10866        // Wait for the provider to be published...
10867        synchronized (cpr) {
10868            while (cpr.provider == null) {
10869                if (cpr.launchingApp == null) {
10870                    Slog.w(TAG, "Unable to launch app "
10871                            + cpi.applicationInfo.packageName + "/"
10872                            + cpi.applicationInfo.uid + " for provider "
10873                            + name + ": launching app became null");
10874                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10875                            UserHandle.getUserId(cpi.applicationInfo.uid),
10876                            cpi.applicationInfo.packageName,
10877                            cpi.applicationInfo.uid, name);
10878                    return null;
10879                }
10880                try {
10881                    if (DEBUG_MU) Slog.v(TAG_MU,
10882                            "Waiting to start provider " + cpr
10883                            + " launchingApp=" + cpr.launchingApp);
10884                    if (conn != null) {
10885                        conn.waiting = true;
10886                    }
10887                    cpr.wait();
10888                } catch (InterruptedException ex) {
10889                } finally {
10890                    if (conn != null) {
10891                        conn.waiting = false;
10892                    }
10893                }
10894            }
10895        }
10896        return cpr != null ? cpr.newHolder(conn) : null;
10897    }
10898
10899    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10900            ProcessRecord r, final int userId) {
10901        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10902                cpi.packageName, userId)) {
10903
10904            final boolean callerForeground = r == null || r.setSchedGroup
10905                    != ProcessList.SCHED_GROUP_BACKGROUND;
10906
10907            // Show a permission review UI only for starting from a foreground app
10908            if (!callerForeground) {
10909                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10910                        + cpi.packageName + " requires a permissions review");
10911                return false;
10912            }
10913
10914            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10915            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10916                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10917            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10918
10919            if (DEBUG_PERMISSIONS_REVIEW) {
10920                Slog.i(TAG, "u" + userId + " Launching permission review "
10921                        + "for package " + cpi.packageName);
10922            }
10923
10924            final UserHandle userHandle = new UserHandle(userId);
10925            mHandler.post(new Runnable() {
10926                @Override
10927                public void run() {
10928                    mContext.startActivityAsUser(intent, userHandle);
10929                }
10930            });
10931
10932            return false;
10933        }
10934
10935        return true;
10936    }
10937
10938    PackageManagerInternal getPackageManagerInternalLocked() {
10939        if (mPackageManagerInt == null) {
10940            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10941        }
10942        return mPackageManagerInt;
10943    }
10944
10945    @Override
10946    public final ContentProviderHolder getContentProvider(
10947            IApplicationThread caller, String name, int userId, boolean stable) {
10948        enforceNotIsolatedCaller("getContentProvider");
10949        if (caller == null) {
10950            String msg = "null IApplicationThread when getting content provider "
10951                    + name;
10952            Slog.w(TAG, msg);
10953            throw new SecurityException(msg);
10954        }
10955        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10956        // with cross-user grant.
10957        return getContentProviderImpl(caller, name, null, stable, userId);
10958    }
10959
10960    public ContentProviderHolder getContentProviderExternal(
10961            String name, int userId, IBinder token) {
10962        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10963            "Do not have permission in call getContentProviderExternal()");
10964        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10965                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10966        return getContentProviderExternalUnchecked(name, token, userId);
10967    }
10968
10969    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10970            IBinder token, int userId) {
10971        return getContentProviderImpl(null, name, token, true, userId);
10972    }
10973
10974    /**
10975     * Drop a content provider from a ProcessRecord's bookkeeping
10976     */
10977    public void removeContentProvider(IBinder connection, boolean stable) {
10978        enforceNotIsolatedCaller("removeContentProvider");
10979        long ident = Binder.clearCallingIdentity();
10980        try {
10981            synchronized (this) {
10982                ContentProviderConnection conn;
10983                try {
10984                    conn = (ContentProviderConnection)connection;
10985                } catch (ClassCastException e) {
10986                    String msg ="removeContentProvider: " + connection
10987                            + " not a ContentProviderConnection";
10988                    Slog.w(TAG, msg);
10989                    throw new IllegalArgumentException(msg);
10990                }
10991                if (conn == null) {
10992                    throw new NullPointerException("connection is null");
10993                }
10994                if (decProviderCountLocked(conn, null, null, stable)) {
10995                    updateOomAdjLocked();
10996                }
10997            }
10998        } finally {
10999            Binder.restoreCallingIdentity(ident);
11000        }
11001    }
11002
11003    public void removeContentProviderExternal(String name, IBinder token) {
11004        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11005            "Do not have permission in call removeContentProviderExternal()");
11006        int userId = UserHandle.getCallingUserId();
11007        long ident = Binder.clearCallingIdentity();
11008        try {
11009            removeContentProviderExternalUnchecked(name, token, userId);
11010        } finally {
11011            Binder.restoreCallingIdentity(ident);
11012        }
11013    }
11014
11015    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11016        synchronized (this) {
11017            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11018            if(cpr == null) {
11019                //remove from mProvidersByClass
11020                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11021                return;
11022            }
11023
11024            //update content provider record entry info
11025            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11026            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11027            if (localCpr.hasExternalProcessHandles()) {
11028                if (localCpr.removeExternalProcessHandleLocked(token)) {
11029                    updateOomAdjLocked();
11030                } else {
11031                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11032                            + " with no external reference for token: "
11033                            + token + ".");
11034                }
11035            } else {
11036                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11037                        + " with no external references.");
11038            }
11039        }
11040    }
11041
11042    public final void publishContentProviders(IApplicationThread caller,
11043            List<ContentProviderHolder> providers) {
11044        if (providers == null) {
11045            return;
11046        }
11047
11048        enforceNotIsolatedCaller("publishContentProviders");
11049        synchronized (this) {
11050            final ProcessRecord r = getRecordForAppLocked(caller);
11051            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11052            if (r == null) {
11053                throw new SecurityException(
11054                        "Unable to find app for caller " + caller
11055                      + " (pid=" + Binder.getCallingPid()
11056                      + ") when publishing content providers");
11057            }
11058
11059            final long origId = Binder.clearCallingIdentity();
11060
11061            final int N = providers.size();
11062            for (int i = 0; i < N; i++) {
11063                ContentProviderHolder src = providers.get(i);
11064                if (src == null || src.info == null || src.provider == null) {
11065                    continue;
11066                }
11067                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11068                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11069                if (dst != null) {
11070                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11071                    mProviderMap.putProviderByClass(comp, dst);
11072                    String names[] = dst.info.authority.split(";");
11073                    for (int j = 0; j < names.length; j++) {
11074                        mProviderMap.putProviderByName(names[j], dst);
11075                    }
11076
11077                    int launchingCount = mLaunchingProviders.size();
11078                    int j;
11079                    boolean wasInLaunchingProviders = false;
11080                    for (j = 0; j < launchingCount; j++) {
11081                        if (mLaunchingProviders.get(j) == dst) {
11082                            mLaunchingProviders.remove(j);
11083                            wasInLaunchingProviders = true;
11084                            j--;
11085                            launchingCount--;
11086                        }
11087                    }
11088                    if (wasInLaunchingProviders) {
11089                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11090                    }
11091                    synchronized (dst) {
11092                        dst.provider = src.provider;
11093                        dst.proc = r;
11094                        dst.notifyAll();
11095                    }
11096                    updateOomAdjLocked(r);
11097                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11098                            src.info.authority);
11099                }
11100            }
11101
11102            Binder.restoreCallingIdentity(origId);
11103        }
11104    }
11105
11106    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11107        ContentProviderConnection conn;
11108        try {
11109            conn = (ContentProviderConnection)connection;
11110        } catch (ClassCastException e) {
11111            String msg ="refContentProvider: " + connection
11112                    + " not a ContentProviderConnection";
11113            Slog.w(TAG, msg);
11114            throw new IllegalArgumentException(msg);
11115        }
11116        if (conn == null) {
11117            throw new NullPointerException("connection is null");
11118        }
11119
11120        synchronized (this) {
11121            if (stable > 0) {
11122                conn.numStableIncs += stable;
11123            }
11124            stable = conn.stableCount + stable;
11125            if (stable < 0) {
11126                throw new IllegalStateException("stableCount < 0: " + stable);
11127            }
11128
11129            if (unstable > 0) {
11130                conn.numUnstableIncs += unstable;
11131            }
11132            unstable = conn.unstableCount + unstable;
11133            if (unstable < 0) {
11134                throw new IllegalStateException("unstableCount < 0: " + unstable);
11135            }
11136
11137            if ((stable+unstable) <= 0) {
11138                throw new IllegalStateException("ref counts can't go to zero here: stable="
11139                        + stable + " unstable=" + unstable);
11140            }
11141            conn.stableCount = stable;
11142            conn.unstableCount = unstable;
11143            return !conn.dead;
11144        }
11145    }
11146
11147    public void unstableProviderDied(IBinder connection) {
11148        ContentProviderConnection conn;
11149        try {
11150            conn = (ContentProviderConnection)connection;
11151        } catch (ClassCastException e) {
11152            String msg ="refContentProvider: " + connection
11153                    + " not a ContentProviderConnection";
11154            Slog.w(TAG, msg);
11155            throw new IllegalArgumentException(msg);
11156        }
11157        if (conn == null) {
11158            throw new NullPointerException("connection is null");
11159        }
11160
11161        // Safely retrieve the content provider associated with the connection.
11162        IContentProvider provider;
11163        synchronized (this) {
11164            provider = conn.provider.provider;
11165        }
11166
11167        if (provider == null) {
11168            // Um, yeah, we're way ahead of you.
11169            return;
11170        }
11171
11172        // Make sure the caller is being honest with us.
11173        if (provider.asBinder().pingBinder()) {
11174            // Er, no, still looks good to us.
11175            synchronized (this) {
11176                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11177                        + " says " + conn + " died, but we don't agree");
11178                return;
11179            }
11180        }
11181
11182        // Well look at that!  It's dead!
11183        synchronized (this) {
11184            if (conn.provider.provider != provider) {
11185                // But something changed...  good enough.
11186                return;
11187            }
11188
11189            ProcessRecord proc = conn.provider.proc;
11190            if (proc == null || proc.thread == null) {
11191                // Seems like the process is already cleaned up.
11192                return;
11193            }
11194
11195            // As far as we're concerned, this is just like receiving a
11196            // death notification...  just a bit prematurely.
11197            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11198                    + ") early provider death");
11199            final long ident = Binder.clearCallingIdentity();
11200            try {
11201                appDiedLocked(proc);
11202            } finally {
11203                Binder.restoreCallingIdentity(ident);
11204            }
11205        }
11206    }
11207
11208    @Override
11209    public void appNotRespondingViaProvider(IBinder connection) {
11210        enforceCallingPermission(
11211                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11212
11213        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11214        if (conn == null) {
11215            Slog.w(TAG, "ContentProviderConnection is null");
11216            return;
11217        }
11218
11219        final ProcessRecord host = conn.provider.proc;
11220        if (host == null) {
11221            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11222            return;
11223        }
11224
11225        mHandler.post(new Runnable() {
11226            @Override
11227            public void run() {
11228                mAppErrors.appNotResponding(host, null, null, false,
11229                        "ContentProvider not responding");
11230            }
11231        });
11232    }
11233
11234    public final void installSystemProviders() {
11235        List<ProviderInfo> providers;
11236        synchronized (this) {
11237            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11238            providers = generateApplicationProvidersLocked(app);
11239            if (providers != null) {
11240                for (int i=providers.size()-1; i>=0; i--) {
11241                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11242                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11243                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11244                                + ": not system .apk");
11245                        providers.remove(i);
11246                    }
11247                }
11248            }
11249        }
11250        if (providers != null) {
11251            mSystemThread.installSystemProviders(providers);
11252        }
11253
11254        mCoreSettingsObserver = new CoreSettingsObserver(this);
11255        mFontScaleSettingObserver = new FontScaleSettingObserver();
11256
11257        //mUsageStatsService.monitorPackages();
11258    }
11259
11260    private void startPersistentApps(int matchFlags) {
11261        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11262
11263        synchronized (this) {
11264            try {
11265                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11266                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11267                for (ApplicationInfo app : apps) {
11268                    if (!"android".equals(app.packageName)) {
11269                        addAppLocked(app, false, null /* ABI override */);
11270                    }
11271                }
11272            } catch (RemoteException ex) {
11273            }
11274        }
11275    }
11276
11277    /**
11278     * When a user is unlocked, we need to install encryption-unaware providers
11279     * belonging to any running apps.
11280     */
11281    private void installEncryptionUnawareProviders(int userId) {
11282        // We're only interested in providers that are encryption unaware, and
11283        // we don't care about uninstalled apps, since there's no way they're
11284        // running at this point.
11285        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11286
11287        synchronized (this) {
11288            final int NP = mProcessNames.getMap().size();
11289            for (int ip = 0; ip < NP; ip++) {
11290                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11291                final int NA = apps.size();
11292                for (int ia = 0; ia < NA; ia++) {
11293                    final ProcessRecord app = apps.valueAt(ia);
11294                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11295
11296                    final int NG = app.pkgList.size();
11297                    for (int ig = 0; ig < NG; ig++) {
11298                        try {
11299                            final String pkgName = app.pkgList.keyAt(ig);
11300                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11301                                    .getPackageInfo(pkgName, matchFlags, userId);
11302                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11303                                for (ProviderInfo pi : pkgInfo.providers) {
11304                                    // TODO: keep in sync with generateApplicationProvidersLocked
11305                                    final boolean processMatch = Objects.equals(pi.processName,
11306                                            app.processName) || pi.multiprocess;
11307                                    final boolean userMatch = isSingleton(pi.processName,
11308                                            pi.applicationInfo, pi.name, pi.flags)
11309                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11310                                    if (processMatch && userMatch) {
11311                                        Log.v(TAG, "Installing " + pi);
11312                                        app.thread.scheduleInstallProvider(pi);
11313                                    } else {
11314                                        Log.v(TAG, "Skipping " + pi);
11315                                    }
11316                                }
11317                            }
11318                        } catch (RemoteException ignored) {
11319                        }
11320                    }
11321                }
11322            }
11323        }
11324    }
11325
11326    /**
11327     * Allows apps to retrieve the MIME type of a URI.
11328     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11329     * users, then it does not need permission to access the ContentProvider.
11330     * Either, it needs cross-user uri grants.
11331     *
11332     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11333     *
11334     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11335     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11336     */
11337    public String getProviderMimeType(Uri uri, int userId) {
11338        enforceNotIsolatedCaller("getProviderMimeType");
11339        final String name = uri.getAuthority();
11340        int callingUid = Binder.getCallingUid();
11341        int callingPid = Binder.getCallingPid();
11342        long ident = 0;
11343        boolean clearedIdentity = false;
11344        synchronized (this) {
11345            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11346        }
11347        if (canClearIdentity(callingPid, callingUid, userId)) {
11348            clearedIdentity = true;
11349            ident = Binder.clearCallingIdentity();
11350        }
11351        ContentProviderHolder holder = null;
11352        try {
11353            holder = getContentProviderExternalUnchecked(name, null, userId);
11354            if (holder != null) {
11355                return holder.provider.getType(uri);
11356            }
11357        } catch (RemoteException e) {
11358            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11359            return null;
11360        } catch (Exception e) {
11361            Log.w(TAG, "Exception while determining type of " + uri, e);
11362            return null;
11363        } finally {
11364            // We need to clear the identity to call removeContentProviderExternalUnchecked
11365            if (!clearedIdentity) {
11366                ident = Binder.clearCallingIdentity();
11367            }
11368            try {
11369                if (holder != null) {
11370                    removeContentProviderExternalUnchecked(name, null, userId);
11371                }
11372            } finally {
11373                Binder.restoreCallingIdentity(ident);
11374            }
11375        }
11376
11377        return null;
11378    }
11379
11380    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11381        if (UserHandle.getUserId(callingUid) == userId) {
11382            return true;
11383        }
11384        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11385                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11386                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11387                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11388                return true;
11389        }
11390        return false;
11391    }
11392
11393    // =========================================================
11394    // GLOBAL MANAGEMENT
11395    // =========================================================
11396
11397    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11398            boolean isolated, int isolatedUid) {
11399        String proc = customProcess != null ? customProcess : info.processName;
11400        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11401        final int userId = UserHandle.getUserId(info.uid);
11402        int uid = info.uid;
11403        if (isolated) {
11404            if (isolatedUid == 0) {
11405                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11406                while (true) {
11407                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11408                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11409                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11410                    }
11411                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11412                    mNextIsolatedProcessUid++;
11413                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11414                        // No process for this uid, use it.
11415                        break;
11416                    }
11417                    stepsLeft--;
11418                    if (stepsLeft <= 0) {
11419                        return null;
11420                    }
11421                }
11422            } else {
11423                // Special case for startIsolatedProcess (internal only), where
11424                // the uid of the isolated process is specified by the caller.
11425                uid = isolatedUid;
11426            }
11427        }
11428        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11429        if (!mBooted && !mBooting
11430                && userId == UserHandle.USER_SYSTEM
11431                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11432            r.persistent = true;
11433        }
11434        addProcessNameLocked(r);
11435        return r;
11436    }
11437
11438    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11439            String abiOverride) {
11440        ProcessRecord app;
11441        if (!isolated) {
11442            app = getProcessRecordLocked(info.processName, info.uid, true);
11443        } else {
11444            app = null;
11445        }
11446
11447        if (app == null) {
11448            app = newProcessRecordLocked(info, null, isolated, 0);
11449            updateLruProcessLocked(app, false, null);
11450            updateOomAdjLocked();
11451        }
11452
11453        // This package really, really can not be stopped.
11454        try {
11455            AppGlobals.getPackageManager().setPackageStoppedState(
11456                    info.packageName, false, UserHandle.getUserId(app.uid));
11457        } catch (RemoteException e) {
11458        } catch (IllegalArgumentException e) {
11459            Slog.w(TAG, "Failed trying to unstop package "
11460                    + info.packageName + ": " + e);
11461        }
11462
11463        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11464            app.persistent = true;
11465            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11466        }
11467        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11468            mPersistentStartingProcesses.add(app);
11469            startProcessLocked(app, "added application", app.processName, abiOverride,
11470                    null /* entryPoint */, null /* entryPointArgs */);
11471        }
11472
11473        return app;
11474    }
11475
11476    public void unhandledBack() {
11477        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11478                "unhandledBack()");
11479
11480        synchronized(this) {
11481            final long origId = Binder.clearCallingIdentity();
11482            try {
11483                getFocusedStack().unhandledBackLocked();
11484            } finally {
11485                Binder.restoreCallingIdentity(origId);
11486            }
11487        }
11488    }
11489
11490    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11491        enforceNotIsolatedCaller("openContentUri");
11492        final int userId = UserHandle.getCallingUserId();
11493        String name = uri.getAuthority();
11494        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11495        ParcelFileDescriptor pfd = null;
11496        if (cph != null) {
11497            // We record the binder invoker's uid in thread-local storage before
11498            // going to the content provider to open the file.  Later, in the code
11499            // that handles all permissions checks, we look for this uid and use
11500            // that rather than the Activity Manager's own uid.  The effect is that
11501            // we do the check against the caller's permissions even though it looks
11502            // to the content provider like the Activity Manager itself is making
11503            // the request.
11504            Binder token = new Binder();
11505            sCallerIdentity.set(new Identity(
11506                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11507            try {
11508                pfd = cph.provider.openFile(null, uri, "r", null, token);
11509            } catch (FileNotFoundException e) {
11510                // do nothing; pfd will be returned null
11511            } finally {
11512                // Ensure that whatever happens, we clean up the identity state
11513                sCallerIdentity.remove();
11514                // Ensure we're done with the provider.
11515                removeContentProviderExternalUnchecked(name, null, userId);
11516            }
11517        } else {
11518            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11519        }
11520        return pfd;
11521    }
11522
11523    // Actually is sleeping or shutting down or whatever else in the future
11524    // is an inactive state.
11525    boolean isSleepingOrShuttingDownLocked() {
11526        return isSleepingLocked() || mShuttingDown;
11527    }
11528
11529    boolean isShuttingDownLocked() {
11530        return mShuttingDown;
11531    }
11532
11533    boolean isSleepingLocked() {
11534        return mSleeping;
11535    }
11536
11537    void onWakefulnessChanged(int wakefulness) {
11538        synchronized(this) {
11539            mWakefulness = wakefulness;
11540            updateSleepIfNeededLocked();
11541        }
11542    }
11543
11544    void finishRunningVoiceLocked() {
11545        if (mRunningVoice != null) {
11546            mRunningVoice = null;
11547            mVoiceWakeLock.release();
11548            updateSleepIfNeededLocked();
11549        }
11550    }
11551
11552    void startTimeTrackingFocusedActivityLocked() {
11553        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11554            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11555        }
11556    }
11557
11558    void updateSleepIfNeededLocked() {
11559        if (mSleeping && !shouldSleepLocked()) {
11560            mSleeping = false;
11561            startTimeTrackingFocusedActivityLocked();
11562            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11563            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11564            updateOomAdjLocked();
11565        } else if (!mSleeping && shouldSleepLocked()) {
11566            mSleeping = true;
11567            if (mCurAppTimeTracker != null) {
11568                mCurAppTimeTracker.stop();
11569            }
11570            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11571            mStackSupervisor.goingToSleepLocked();
11572            updateOomAdjLocked();
11573
11574            // Initialize the wake times of all processes.
11575            checkExcessivePowerUsageLocked(false);
11576            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11577            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11578            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11579        }
11580    }
11581
11582    private boolean shouldSleepLocked() {
11583        // Resume applications while running a voice interactor.
11584        if (mRunningVoice != null) {
11585            return false;
11586        }
11587
11588        // TODO: Transform the lock screen state into a sleep token instead.
11589        switch (mWakefulness) {
11590            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11591            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11592            case PowerManagerInternal.WAKEFULNESS_DOZING:
11593                // Pause applications whenever the lock screen is shown or any sleep
11594                // tokens have been acquired.
11595                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11596            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11597            default:
11598                // If we're asleep then pause applications unconditionally.
11599                return true;
11600        }
11601    }
11602
11603    /** Pokes the task persister. */
11604    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11605        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11606    }
11607
11608    /** Notifies all listeners when the task stack has changed. */
11609    void notifyTaskStackChangedLocked() {
11610        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11611        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11612        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11613        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11614    }
11615
11616    /** Notifies all listeners when an Activity is pinned. */
11617    void notifyActivityPinnedLocked() {
11618        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11619        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11620    }
11621
11622    /**
11623     * Notifies all listeners when an attempt was made to start an an activity that is already
11624     * running in the pinned stack and the activity was not actually started, but the task is
11625     * either brought to the front or a new Intent is delivered to it.
11626     */
11627    void notifyPinnedActivityRestartAttemptLocked() {
11628        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11629        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11630    }
11631
11632    /** Notifies all listeners when the pinned stack animation ends. */
11633    @Override
11634    public void notifyPinnedStackAnimationEnded() {
11635        synchronized (this) {
11636            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11637            mHandler.obtainMessage(
11638                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11639        }
11640    }
11641
11642    @Override
11643    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11644        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11645    }
11646
11647    @Override
11648    public boolean shutdown(int timeout) {
11649        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11650                != PackageManager.PERMISSION_GRANTED) {
11651            throw new SecurityException("Requires permission "
11652                    + android.Manifest.permission.SHUTDOWN);
11653        }
11654
11655        boolean timedout = false;
11656
11657        synchronized(this) {
11658            mShuttingDown = true;
11659            updateEventDispatchingLocked();
11660            timedout = mStackSupervisor.shutdownLocked(timeout);
11661        }
11662
11663        mAppOpsService.shutdown();
11664        if (mUsageStatsService != null) {
11665            mUsageStatsService.prepareShutdown();
11666        }
11667        mBatteryStatsService.shutdown();
11668        synchronized (this) {
11669            mProcessStats.shutdownLocked();
11670            notifyTaskPersisterLocked(null, true);
11671        }
11672
11673        return timedout;
11674    }
11675
11676    public final void activitySlept(IBinder token) {
11677        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11678
11679        final long origId = Binder.clearCallingIdentity();
11680
11681        synchronized (this) {
11682            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11683            if (r != null) {
11684                mStackSupervisor.activitySleptLocked(r);
11685            }
11686        }
11687
11688        Binder.restoreCallingIdentity(origId);
11689    }
11690
11691    private String lockScreenShownToString() {
11692        switch (mLockScreenShown) {
11693            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11694            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11695            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11696            default: return "Unknown=" + mLockScreenShown;
11697        }
11698    }
11699
11700    void logLockScreen(String msg) {
11701        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11702                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11703                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11704                + " mSleeping=" + mSleeping);
11705    }
11706
11707    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11708        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11709        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11710        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11711            boolean wasRunningVoice = mRunningVoice != null;
11712            mRunningVoice = session;
11713            if (!wasRunningVoice) {
11714                mVoiceWakeLock.acquire();
11715                updateSleepIfNeededLocked();
11716            }
11717        }
11718    }
11719
11720    private void updateEventDispatchingLocked() {
11721        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11722    }
11723
11724    public void setLockScreenShown(boolean showing, boolean occluded) {
11725        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11726                != PackageManager.PERMISSION_GRANTED) {
11727            throw new SecurityException("Requires permission "
11728                    + android.Manifest.permission.DEVICE_POWER);
11729        }
11730
11731        synchronized(this) {
11732            long ident = Binder.clearCallingIdentity();
11733            try {
11734                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11735                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11736                if (showing && occluded) {
11737                    // The lock screen is currently showing, but is occluded by a window that can
11738                    // show on top of the lock screen. In this can we want to dismiss the docked
11739                    // stack since it will be complicated/risky to try to put the activity on top
11740                    // of the lock screen in the right fullscreen configuration.
11741                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11742                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11743                }
11744
11745                updateSleepIfNeededLocked();
11746            } finally {
11747                Binder.restoreCallingIdentity(ident);
11748            }
11749        }
11750    }
11751
11752    @Override
11753    public void notifyLockedProfile(@UserIdInt int userId) {
11754        try {
11755            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11756                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11757            }
11758        } catch (RemoteException ex) {
11759            throw new SecurityException("Fail to check is caller a privileged app", ex);
11760        }
11761
11762        synchronized (this) {
11763            if (mStackSupervisor.isUserLockedProfile(userId)) {
11764                final long ident = Binder.clearCallingIdentity();
11765                try {
11766                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11767                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11768                        // If there is no device lock, we will show the profile's credential page.
11769                        mActivityStarter.showConfirmDeviceCredential(userId);
11770                    } else {
11771                        // Showing launcher to avoid user entering credential twice.
11772                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11773                    }
11774                } finally {
11775                    Binder.restoreCallingIdentity(ident);
11776                }
11777            }
11778        }
11779    }
11780
11781    @Override
11782    public void startConfirmDeviceCredentialIntent(Intent intent) {
11783        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11784        synchronized (this) {
11785            final long ident = Binder.clearCallingIdentity();
11786            try {
11787                mActivityStarter.startConfirmCredentialIntent(intent);
11788            } finally {
11789                Binder.restoreCallingIdentity(ident);
11790            }
11791        }
11792    }
11793
11794    @Override
11795    public void stopAppSwitches() {
11796        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11797                != PackageManager.PERMISSION_GRANTED) {
11798            throw new SecurityException("viewquires permission "
11799                    + android.Manifest.permission.STOP_APP_SWITCHES);
11800        }
11801
11802        synchronized(this) {
11803            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11804                    + APP_SWITCH_DELAY_TIME;
11805            mDidAppSwitch = false;
11806            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11807            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11808            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11809        }
11810    }
11811
11812    public void resumeAppSwitches() {
11813        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11814                != PackageManager.PERMISSION_GRANTED) {
11815            throw new SecurityException("Requires permission "
11816                    + android.Manifest.permission.STOP_APP_SWITCHES);
11817        }
11818
11819        synchronized(this) {
11820            // Note that we don't execute any pending app switches... we will
11821            // let those wait until either the timeout, or the next start
11822            // activity request.
11823            mAppSwitchesAllowedTime = 0;
11824        }
11825    }
11826
11827    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11828            int callingPid, int callingUid, String name) {
11829        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11830            return true;
11831        }
11832
11833        int perm = checkComponentPermission(
11834                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11835                sourceUid, -1, true);
11836        if (perm == PackageManager.PERMISSION_GRANTED) {
11837            return true;
11838        }
11839
11840        // If the actual IPC caller is different from the logical source, then
11841        // also see if they are allowed to control app switches.
11842        if (callingUid != -1 && callingUid != sourceUid) {
11843            perm = checkComponentPermission(
11844                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11845                    callingUid, -1, true);
11846            if (perm == PackageManager.PERMISSION_GRANTED) {
11847                return true;
11848            }
11849        }
11850
11851        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11852        return false;
11853    }
11854
11855    public void setDebugApp(String packageName, boolean waitForDebugger,
11856            boolean persistent) {
11857        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11858                "setDebugApp()");
11859
11860        long ident = Binder.clearCallingIdentity();
11861        try {
11862            // Note that this is not really thread safe if there are multiple
11863            // callers into it at the same time, but that's not a situation we
11864            // care about.
11865            if (persistent) {
11866                final ContentResolver resolver = mContext.getContentResolver();
11867                Settings.Global.putString(
11868                    resolver, Settings.Global.DEBUG_APP,
11869                    packageName);
11870                Settings.Global.putInt(
11871                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11872                    waitForDebugger ? 1 : 0);
11873            }
11874
11875            synchronized (this) {
11876                if (!persistent) {
11877                    mOrigDebugApp = mDebugApp;
11878                    mOrigWaitForDebugger = mWaitForDebugger;
11879                }
11880                mDebugApp = packageName;
11881                mWaitForDebugger = waitForDebugger;
11882                mDebugTransient = !persistent;
11883                if (packageName != null) {
11884                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11885                            false, UserHandle.USER_ALL, "set debug app");
11886                }
11887            }
11888        } finally {
11889            Binder.restoreCallingIdentity(ident);
11890        }
11891    }
11892
11893    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11894        synchronized (this) {
11895            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11896            if (!isDebuggable) {
11897                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11898                    throw new SecurityException("Process not debuggable: " + app.packageName);
11899                }
11900            }
11901
11902            mTrackAllocationApp = processName;
11903        }
11904    }
11905
11906    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11907        synchronized (this) {
11908            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11909            if (!isDebuggable) {
11910                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11911                    throw new SecurityException("Process not debuggable: " + app.packageName);
11912                }
11913            }
11914            mProfileApp = processName;
11915            mProfileFile = profilerInfo.profileFile;
11916            if (mProfileFd != null) {
11917                try {
11918                    mProfileFd.close();
11919                } catch (IOException e) {
11920                }
11921                mProfileFd = null;
11922            }
11923            mProfileFd = profilerInfo.profileFd;
11924            mSamplingInterval = profilerInfo.samplingInterval;
11925            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11926            mProfileType = 0;
11927        }
11928    }
11929
11930    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11931        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11932        if (!isDebuggable) {
11933            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11934                throw new SecurityException("Process not debuggable: " + app.packageName);
11935            }
11936        }
11937        mNativeDebuggingApp = processName;
11938    }
11939
11940    @Override
11941    public void setAlwaysFinish(boolean enabled) {
11942        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11943                "setAlwaysFinish()");
11944
11945        long ident = Binder.clearCallingIdentity();
11946        try {
11947            Settings.Global.putInt(
11948                    mContext.getContentResolver(),
11949                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11950
11951            synchronized (this) {
11952                mAlwaysFinishActivities = enabled;
11953            }
11954        } finally {
11955            Binder.restoreCallingIdentity(ident);
11956        }
11957    }
11958
11959    @Override
11960    public void setLenientBackgroundCheck(boolean enabled) {
11961        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11962                "setLenientBackgroundCheck()");
11963
11964        long ident = Binder.clearCallingIdentity();
11965        try {
11966            Settings.Global.putInt(
11967                    mContext.getContentResolver(),
11968                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11969
11970            synchronized (this) {
11971                mLenientBackgroundCheck = enabled;
11972            }
11973        } finally {
11974            Binder.restoreCallingIdentity(ident);
11975        }
11976    }
11977
11978    @Override
11979    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11980        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11981                "setActivityController()");
11982        synchronized (this) {
11983            mController = controller;
11984            mControllerIsAMonkey = imAMonkey;
11985            Watchdog.getInstance().setActivityController(controller);
11986        }
11987    }
11988
11989    @Override
11990    public void setUserIsMonkey(boolean userIsMonkey) {
11991        synchronized (this) {
11992            synchronized (mPidsSelfLocked) {
11993                final int callingPid = Binder.getCallingPid();
11994                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11995                if (precessRecord == null) {
11996                    throw new SecurityException("Unknown process: " + callingPid);
11997                }
11998                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11999                    throw new SecurityException("Only an instrumentation process "
12000                            + "with a UiAutomation can call setUserIsMonkey");
12001                }
12002            }
12003            mUserIsMonkey = userIsMonkey;
12004        }
12005    }
12006
12007    @Override
12008    public boolean isUserAMonkey() {
12009        synchronized (this) {
12010            // If there is a controller also implies the user is a monkey.
12011            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12012        }
12013    }
12014
12015    public void requestBugReport(int bugreportType) {
12016        String service = null;
12017        switch (bugreportType) {
12018            case ActivityManager.BUGREPORT_OPTION_FULL:
12019                service = "bugreport";
12020                break;
12021            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12022                service = "bugreportplus";
12023                break;
12024            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12025                service = "bugreportremote";
12026                break;
12027        }
12028        if (service == null) {
12029            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12030                    + bugreportType);
12031        }
12032        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12033        SystemProperties.set("ctl.start", service);
12034    }
12035
12036    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12037        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12038    }
12039
12040    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12041        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12042            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12043        }
12044        return KEY_DISPATCHING_TIMEOUT;
12045    }
12046
12047    @Override
12048    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12049        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12050                != PackageManager.PERMISSION_GRANTED) {
12051            throw new SecurityException("Requires permission "
12052                    + android.Manifest.permission.FILTER_EVENTS);
12053        }
12054        ProcessRecord proc;
12055        long timeout;
12056        synchronized (this) {
12057            synchronized (mPidsSelfLocked) {
12058                proc = mPidsSelfLocked.get(pid);
12059            }
12060            timeout = getInputDispatchingTimeoutLocked(proc);
12061        }
12062
12063        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12064            return -1;
12065        }
12066
12067        return timeout;
12068    }
12069
12070    /**
12071     * Handle input dispatching timeouts.
12072     * Returns whether input dispatching should be aborted or not.
12073     */
12074    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12075            final ActivityRecord activity, final ActivityRecord parent,
12076            final boolean aboveSystem, String reason) {
12077        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12078                != PackageManager.PERMISSION_GRANTED) {
12079            throw new SecurityException("Requires permission "
12080                    + android.Manifest.permission.FILTER_EVENTS);
12081        }
12082
12083        final String annotation;
12084        if (reason == null) {
12085            annotation = "Input dispatching timed out";
12086        } else {
12087            annotation = "Input dispatching timed out (" + reason + ")";
12088        }
12089
12090        if (proc != null) {
12091            synchronized (this) {
12092                if (proc.debugging) {
12093                    return false;
12094                }
12095
12096                if (mDidDexOpt) {
12097                    // Give more time since we were dexopting.
12098                    mDidDexOpt = false;
12099                    return false;
12100                }
12101
12102                if (proc.instrumentationClass != null) {
12103                    Bundle info = new Bundle();
12104                    info.putString("shortMsg", "keyDispatchingTimedOut");
12105                    info.putString("longMsg", annotation);
12106                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12107                    return true;
12108                }
12109            }
12110            mHandler.post(new Runnable() {
12111                @Override
12112                public void run() {
12113                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12114                }
12115            });
12116        }
12117
12118        return true;
12119    }
12120
12121    @Override
12122    public Bundle getAssistContextExtras(int requestType) {
12123        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12124                null, null, true /* focused */, true /* newSessionId */,
12125                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12126        if (pae == null) {
12127            return null;
12128        }
12129        synchronized (pae) {
12130            while (!pae.haveResult) {
12131                try {
12132                    pae.wait();
12133                } catch (InterruptedException e) {
12134                }
12135            }
12136        }
12137        synchronized (this) {
12138            buildAssistBundleLocked(pae, pae.result);
12139            mPendingAssistExtras.remove(pae);
12140            mUiHandler.removeCallbacks(pae);
12141        }
12142        return pae.extras;
12143    }
12144
12145    @Override
12146    public boolean isAssistDataAllowedOnCurrentActivity() {
12147        int userId;
12148        synchronized (this) {
12149            userId = mUserController.getCurrentUserIdLocked();
12150            ActivityRecord activity = getFocusedStack().topActivity();
12151            if (activity == null) {
12152                return false;
12153            }
12154            userId = activity.userId;
12155        }
12156        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12157                Context.DEVICE_POLICY_SERVICE);
12158        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12159    }
12160
12161    @Override
12162    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12163        long ident = Binder.clearCallingIdentity();
12164        try {
12165            synchronized (this) {
12166                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12167                ActivityRecord top = getFocusedStack().topActivity();
12168                if (top != caller) {
12169                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12170                            + " is not current top " + top);
12171                    return false;
12172                }
12173                if (!top.nowVisible) {
12174                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12175                            + " is not visible");
12176                    return false;
12177                }
12178            }
12179            AssistUtils utils = new AssistUtils(mContext);
12180            return utils.showSessionForActiveService(args,
12181                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12182        } finally {
12183            Binder.restoreCallingIdentity(ident);
12184        }
12185    }
12186
12187    @Override
12188    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12189            Bundle receiverExtras,
12190            IBinder activityToken, boolean focused, boolean newSessionId) {
12191        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12192                activityToken, focused, newSessionId,
12193                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12194                != null;
12195    }
12196
12197    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12198            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12199            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12200        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12201                "enqueueAssistContext()");
12202        synchronized (this) {
12203            ActivityRecord activity = getFocusedStack().topActivity();
12204            if (activity == null) {
12205                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12206                return null;
12207            }
12208            if (activity.app == null || activity.app.thread == null) {
12209                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12210                return null;
12211            }
12212            if (focused) {
12213                if (activityToken != null) {
12214                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12215                    if (activity != caller) {
12216                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12217                                + " is not current top " + activity);
12218                        return null;
12219                    }
12220                }
12221            } else {
12222                activity = ActivityRecord.forTokenLocked(activityToken);
12223                if (activity == null) {
12224                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12225                            + " couldn't be found");
12226                    return null;
12227                }
12228            }
12229
12230            PendingAssistExtras pae;
12231            Bundle extras = new Bundle();
12232            if (args != null) {
12233                extras.putAll(args);
12234            }
12235            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12236            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12237            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12238                    userHandle);
12239            // Increment the sessionId if necessary
12240            if (newSessionId) {
12241                mViSessionId++;
12242            }
12243            try {
12244                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12245                        requestType, mViSessionId);
12246                mPendingAssistExtras.add(pae);
12247                mUiHandler.postDelayed(pae, timeout);
12248            } catch (RemoteException e) {
12249                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12250                return null;
12251            }
12252            return pae;
12253        }
12254    }
12255
12256    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12257        IResultReceiver receiver;
12258        synchronized (this) {
12259            mPendingAssistExtras.remove(pae);
12260            receiver = pae.receiver;
12261        }
12262        if (receiver != null) {
12263            // Caller wants result sent back to them.
12264            Bundle sendBundle = new Bundle();
12265            // At least return the receiver extras
12266            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12267                    pae.receiverExtras);
12268            try {
12269                pae.receiver.send(0, sendBundle);
12270            } catch (RemoteException e) {
12271            }
12272        }
12273    }
12274
12275    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12276        if (result != null) {
12277            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12278        }
12279        if (pae.hint != null) {
12280            pae.extras.putBoolean(pae.hint, true);
12281        }
12282    }
12283
12284    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12285            AssistContent content, Uri referrer) {
12286        PendingAssistExtras pae = (PendingAssistExtras)token;
12287        synchronized (pae) {
12288            pae.result = extras;
12289            pae.structure = structure;
12290            pae.content = content;
12291            if (referrer != null) {
12292                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12293            }
12294            pae.haveResult = true;
12295            pae.notifyAll();
12296            if (pae.intent == null && pae.receiver == null) {
12297                // Caller is just waiting for the result.
12298                return;
12299            }
12300        }
12301
12302        // We are now ready to launch the assist activity.
12303        IResultReceiver sendReceiver = null;
12304        Bundle sendBundle = null;
12305        synchronized (this) {
12306            buildAssistBundleLocked(pae, extras);
12307            boolean exists = mPendingAssistExtras.remove(pae);
12308            mUiHandler.removeCallbacks(pae);
12309            if (!exists) {
12310                // Timed out.
12311                return;
12312            }
12313            if ((sendReceiver=pae.receiver) != null) {
12314                // Caller wants result sent back to them.
12315                sendBundle = new Bundle();
12316                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12317                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12318                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12319                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12320                        pae.receiverExtras);
12321            }
12322        }
12323        if (sendReceiver != null) {
12324            try {
12325                sendReceiver.send(0, sendBundle);
12326            } catch (RemoteException e) {
12327            }
12328            return;
12329        }
12330
12331        long ident = Binder.clearCallingIdentity();
12332        try {
12333            pae.intent.replaceExtras(pae.extras);
12334            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12335                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12336                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12337            closeSystemDialogs("assist");
12338            try {
12339                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12340            } catch (ActivityNotFoundException e) {
12341                Slog.w(TAG, "No activity to handle assist action.", e);
12342            }
12343        } finally {
12344            Binder.restoreCallingIdentity(ident);
12345        }
12346    }
12347
12348    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12349            Bundle args) {
12350        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12351                true /* focused */, true /* newSessionId */,
12352                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12353    }
12354
12355    public void registerProcessObserver(IProcessObserver observer) {
12356        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12357                "registerProcessObserver()");
12358        synchronized (this) {
12359            mProcessObservers.register(observer);
12360        }
12361    }
12362
12363    @Override
12364    public void unregisterProcessObserver(IProcessObserver observer) {
12365        synchronized (this) {
12366            mProcessObservers.unregister(observer);
12367        }
12368    }
12369
12370    @Override
12371    public void registerUidObserver(IUidObserver observer, int which) {
12372        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12373                "registerUidObserver()");
12374        synchronized (this) {
12375            mUidObservers.register(observer, which);
12376        }
12377    }
12378
12379    @Override
12380    public void unregisterUidObserver(IUidObserver observer) {
12381        synchronized (this) {
12382            mUidObservers.unregister(observer);
12383        }
12384    }
12385
12386    @Override
12387    public boolean convertFromTranslucent(IBinder token) {
12388        final long origId = Binder.clearCallingIdentity();
12389        try {
12390            synchronized (this) {
12391                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12392                if (r == null) {
12393                    return false;
12394                }
12395                final boolean translucentChanged = r.changeWindowTranslucency(true);
12396                if (translucentChanged) {
12397                    r.task.stack.releaseBackgroundResources(r);
12398                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12399                }
12400                mWindowManager.setAppFullscreen(token, true);
12401                return translucentChanged;
12402            }
12403        } finally {
12404            Binder.restoreCallingIdentity(origId);
12405        }
12406    }
12407
12408    @Override
12409    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12410        final long origId = Binder.clearCallingIdentity();
12411        try {
12412            synchronized (this) {
12413                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12414                if (r == null) {
12415                    return false;
12416                }
12417                int index = r.task.mActivities.lastIndexOf(r);
12418                if (index > 0) {
12419                    ActivityRecord under = r.task.mActivities.get(index - 1);
12420                    under.returningOptions = options;
12421                }
12422                final boolean translucentChanged = r.changeWindowTranslucency(false);
12423                if (translucentChanged) {
12424                    r.task.stack.convertActivityToTranslucent(r);
12425                }
12426                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12427                mWindowManager.setAppFullscreen(token, false);
12428                return translucentChanged;
12429            }
12430        } finally {
12431            Binder.restoreCallingIdentity(origId);
12432        }
12433    }
12434
12435    @Override
12436    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12437        final long origId = Binder.clearCallingIdentity();
12438        try {
12439            synchronized (this) {
12440                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12441                if (r != null) {
12442                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12443                }
12444            }
12445            return false;
12446        } finally {
12447            Binder.restoreCallingIdentity(origId);
12448        }
12449    }
12450
12451    @Override
12452    public boolean isBackgroundVisibleBehind(IBinder token) {
12453        final long origId = Binder.clearCallingIdentity();
12454        try {
12455            synchronized (this) {
12456                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12457                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12458                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12459                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12460                return visible;
12461            }
12462        } finally {
12463            Binder.restoreCallingIdentity(origId);
12464        }
12465    }
12466
12467    @Override
12468    public ActivityOptions getActivityOptions(IBinder token) {
12469        final long origId = Binder.clearCallingIdentity();
12470        try {
12471            synchronized (this) {
12472                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12473                if (r != null) {
12474                    final ActivityOptions activityOptions = r.pendingOptions;
12475                    r.pendingOptions = null;
12476                    return activityOptions;
12477                }
12478                return null;
12479            }
12480        } finally {
12481            Binder.restoreCallingIdentity(origId);
12482        }
12483    }
12484
12485    @Override
12486    public void setImmersive(IBinder token, boolean immersive) {
12487        synchronized(this) {
12488            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12489            if (r == null) {
12490                throw new IllegalArgumentException();
12491            }
12492            r.immersive = immersive;
12493
12494            // update associated state if we're frontmost
12495            if (r == mFocusedActivity) {
12496                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12497                applyUpdateLockStateLocked(r);
12498            }
12499        }
12500    }
12501
12502    @Override
12503    public boolean isImmersive(IBinder token) {
12504        synchronized (this) {
12505            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12506            if (r == null) {
12507                throw new IllegalArgumentException();
12508            }
12509            return r.immersive;
12510        }
12511    }
12512
12513    @Override
12514    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12515        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12516            throw new UnsupportedOperationException("VR mode not supported on this device!");
12517        }
12518
12519        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12520
12521        ActivityRecord r;
12522        synchronized (this) {
12523            r = ActivityRecord.isInStackLocked(token);
12524        }
12525
12526        if (r == null) {
12527            throw new IllegalArgumentException();
12528        }
12529
12530        int err;
12531        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12532                VrManagerInternal.NO_ERROR) {
12533            return err;
12534        }
12535
12536        synchronized(this) {
12537            r.requestedVrComponent = (enabled) ? packageName : null;
12538
12539            // Update associated state if this activity is currently focused
12540            if (r == mFocusedActivity) {
12541                applyUpdateVrModeLocked(r);
12542            }
12543            return 0;
12544        }
12545    }
12546
12547    @Override
12548    public boolean isVrModePackageEnabled(ComponentName packageName) {
12549        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12550            throw new UnsupportedOperationException("VR mode not supported on this device!");
12551        }
12552
12553        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12554
12555        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12556                VrManagerInternal.NO_ERROR;
12557    }
12558
12559    public boolean isTopActivityImmersive() {
12560        enforceNotIsolatedCaller("startActivity");
12561        synchronized (this) {
12562            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12563            return (r != null) ? r.immersive : false;
12564        }
12565    }
12566
12567    @Override
12568    public boolean isTopOfTask(IBinder token) {
12569        synchronized (this) {
12570            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12571            if (r == null) {
12572                throw new IllegalArgumentException();
12573            }
12574            return r.task.getTopActivity() == r;
12575        }
12576    }
12577
12578    public final void enterSafeMode() {
12579        synchronized(this) {
12580            // It only makes sense to do this before the system is ready
12581            // and started launching other packages.
12582            if (!mSystemReady) {
12583                try {
12584                    AppGlobals.getPackageManager().enterSafeMode();
12585                } catch (RemoteException e) {
12586                }
12587            }
12588
12589            mSafeMode = true;
12590        }
12591    }
12592
12593    public final void showSafeModeOverlay() {
12594        View v = LayoutInflater.from(mContext).inflate(
12595                com.android.internal.R.layout.safe_mode, null);
12596        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12597        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12598        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12599        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12600        lp.gravity = Gravity.BOTTOM | Gravity.START;
12601        lp.format = v.getBackground().getOpacity();
12602        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12603                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12604        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12605        ((WindowManager)mContext.getSystemService(
12606                Context.WINDOW_SERVICE)).addView(v, lp);
12607    }
12608
12609    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12610        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12611            return;
12612        }
12613        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12614        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12615        synchronized (stats) {
12616            if (mBatteryStatsService.isOnBattery()) {
12617                mBatteryStatsService.enforceCallingPermission();
12618                int MY_UID = Binder.getCallingUid();
12619                final int uid;
12620                if (sender == null) {
12621                    uid = sourceUid;
12622                } else {
12623                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12624                }
12625                BatteryStatsImpl.Uid.Pkg pkg =
12626                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12627                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12628                pkg.noteWakeupAlarmLocked(tag);
12629            }
12630        }
12631    }
12632
12633    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12634        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12635            return;
12636        }
12637        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12638        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12639        synchronized (stats) {
12640            mBatteryStatsService.enforceCallingPermission();
12641            int MY_UID = Binder.getCallingUid();
12642            final int uid;
12643            if (sender == null) {
12644                uid = sourceUid;
12645            } else {
12646                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12647            }
12648            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12649        }
12650    }
12651
12652    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12653        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12654            return;
12655        }
12656        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12657        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12658        synchronized (stats) {
12659            mBatteryStatsService.enforceCallingPermission();
12660            int MY_UID = Binder.getCallingUid();
12661            final int uid;
12662            if (sender == null) {
12663                uid = sourceUid;
12664            } else {
12665                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12666            }
12667            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12668        }
12669    }
12670
12671    public boolean killPids(int[] pids, String pReason, boolean secure) {
12672        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12673            throw new SecurityException("killPids only available to the system");
12674        }
12675        String reason = (pReason == null) ? "Unknown" : pReason;
12676        // XXX Note: don't acquire main activity lock here, because the window
12677        // manager calls in with its locks held.
12678
12679        boolean killed = false;
12680        synchronized (mPidsSelfLocked) {
12681            int worstType = 0;
12682            for (int i=0; i<pids.length; i++) {
12683                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12684                if (proc != null) {
12685                    int type = proc.setAdj;
12686                    if (type > worstType) {
12687                        worstType = type;
12688                    }
12689                }
12690            }
12691
12692            // If the worst oom_adj is somewhere in the cached proc LRU range,
12693            // then constrain it so we will kill all cached procs.
12694            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12695                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12696                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12697            }
12698
12699            // If this is not a secure call, don't let it kill processes that
12700            // are important.
12701            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12702                worstType = ProcessList.SERVICE_ADJ;
12703            }
12704
12705            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12706            for (int i=0; i<pids.length; i++) {
12707                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12708                if (proc == null) {
12709                    continue;
12710                }
12711                int adj = proc.setAdj;
12712                if (adj >= worstType && !proc.killedByAm) {
12713                    proc.kill(reason, true);
12714                    killed = true;
12715                }
12716            }
12717        }
12718        return killed;
12719    }
12720
12721    @Override
12722    public void killUid(int appId, int userId, String reason) {
12723        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12724        synchronized (this) {
12725            final long identity = Binder.clearCallingIdentity();
12726            try {
12727                killPackageProcessesLocked(null, appId, userId,
12728                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12729                        reason != null ? reason : "kill uid");
12730            } finally {
12731                Binder.restoreCallingIdentity(identity);
12732            }
12733        }
12734    }
12735
12736    @Override
12737    public boolean killProcessesBelowForeground(String reason) {
12738        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12739            throw new SecurityException("killProcessesBelowForeground() only available to system");
12740        }
12741
12742        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12743    }
12744
12745    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12746        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12747            throw new SecurityException("killProcessesBelowAdj() only available to system");
12748        }
12749
12750        boolean killed = false;
12751        synchronized (mPidsSelfLocked) {
12752            final int size = mPidsSelfLocked.size();
12753            for (int i = 0; i < size; i++) {
12754                final int pid = mPidsSelfLocked.keyAt(i);
12755                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12756                if (proc == null) continue;
12757
12758                final int adj = proc.setAdj;
12759                if (adj > belowAdj && !proc.killedByAm) {
12760                    proc.kill(reason, true);
12761                    killed = true;
12762                }
12763            }
12764        }
12765        return killed;
12766    }
12767
12768    @Override
12769    public void hang(final IBinder who, boolean allowRestart) {
12770        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12771                != PackageManager.PERMISSION_GRANTED) {
12772            throw new SecurityException("Requires permission "
12773                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12774        }
12775
12776        final IBinder.DeathRecipient death = new DeathRecipient() {
12777            @Override
12778            public void binderDied() {
12779                synchronized (this) {
12780                    notifyAll();
12781                }
12782            }
12783        };
12784
12785        try {
12786            who.linkToDeath(death, 0);
12787        } catch (RemoteException e) {
12788            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12789            return;
12790        }
12791
12792        synchronized (this) {
12793            Watchdog.getInstance().setAllowRestart(allowRestart);
12794            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12795            synchronized (death) {
12796                while (who.isBinderAlive()) {
12797                    try {
12798                        death.wait();
12799                    } catch (InterruptedException e) {
12800                    }
12801                }
12802            }
12803            Watchdog.getInstance().setAllowRestart(true);
12804        }
12805    }
12806
12807    @Override
12808    public void restart() {
12809        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12810                != PackageManager.PERMISSION_GRANTED) {
12811            throw new SecurityException("Requires permission "
12812                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12813        }
12814
12815        Log.i(TAG, "Sending shutdown broadcast...");
12816
12817        BroadcastReceiver br = new BroadcastReceiver() {
12818            @Override public void onReceive(Context context, Intent intent) {
12819                // Now the broadcast is done, finish up the low-level shutdown.
12820                Log.i(TAG, "Shutting down activity manager...");
12821                shutdown(10000);
12822                Log.i(TAG, "Shutdown complete, restarting!");
12823                Process.killProcess(Process.myPid());
12824                System.exit(10);
12825            }
12826        };
12827
12828        // First send the high-level shut down broadcast.
12829        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12830        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12831        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12832        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12833        mContext.sendOrderedBroadcastAsUser(intent,
12834                UserHandle.ALL, null, br, mHandler, 0, null, null);
12835        */
12836        br.onReceive(mContext, intent);
12837    }
12838
12839    private long getLowRamTimeSinceIdle(long now) {
12840        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12841    }
12842
12843    @Override
12844    public void performIdleMaintenance() {
12845        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12846                != PackageManager.PERMISSION_GRANTED) {
12847            throw new SecurityException("Requires permission "
12848                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12849        }
12850
12851        synchronized (this) {
12852            final long now = SystemClock.uptimeMillis();
12853            final long timeSinceLastIdle = now - mLastIdleTime;
12854            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12855            mLastIdleTime = now;
12856            mLowRamTimeSinceLastIdle = 0;
12857            if (mLowRamStartTime != 0) {
12858                mLowRamStartTime = now;
12859            }
12860
12861            StringBuilder sb = new StringBuilder(128);
12862            sb.append("Idle maintenance over ");
12863            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12864            sb.append(" low RAM for ");
12865            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12866            Slog.i(TAG, sb.toString());
12867
12868            // If at least 1/3 of our time since the last idle period has been spent
12869            // with RAM low, then we want to kill processes.
12870            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12871
12872            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12873                ProcessRecord proc = mLruProcesses.get(i);
12874                if (proc.notCachedSinceIdle) {
12875                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12876                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12877                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12878                        if (doKilling && proc.initialIdlePss != 0
12879                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12880                            sb = new StringBuilder(128);
12881                            sb.append("Kill");
12882                            sb.append(proc.processName);
12883                            sb.append(" in idle maint: pss=");
12884                            sb.append(proc.lastPss);
12885                            sb.append(", swapPss=");
12886                            sb.append(proc.lastSwapPss);
12887                            sb.append(", initialPss=");
12888                            sb.append(proc.initialIdlePss);
12889                            sb.append(", period=");
12890                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12891                            sb.append(", lowRamPeriod=");
12892                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12893                            Slog.wtfQuiet(TAG, sb.toString());
12894                            proc.kill("idle maint (pss " + proc.lastPss
12895                                    + " from " + proc.initialIdlePss + ")", true);
12896                        }
12897                    }
12898                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12899                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12900                    proc.notCachedSinceIdle = true;
12901                    proc.initialIdlePss = 0;
12902                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12903                            mTestPssMode, isSleepingLocked(), now);
12904                }
12905            }
12906
12907            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12908            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12909        }
12910    }
12911
12912    @Override
12913    public void sendIdleJobTrigger() {
12914        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12915                != PackageManager.PERMISSION_GRANTED) {
12916            throw new SecurityException("Requires permission "
12917                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12918        }
12919
12920        final long ident = Binder.clearCallingIdentity();
12921        try {
12922            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12923                    .setPackage("android")
12924                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12925            broadcastIntent(null, intent, null, null, 0, null, null, null,
12926                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12927        } finally {
12928            Binder.restoreCallingIdentity(ident);
12929        }
12930    }
12931
12932    private void retrieveSettings() {
12933        final ContentResolver resolver = mContext.getContentResolver();
12934        final boolean freeformWindowManagement =
12935                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12936                        || Settings.Global.getInt(
12937                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12938        final boolean supportsPictureInPicture =
12939                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12940
12941        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12942        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12943        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12944        final boolean alwaysFinishActivities =
12945                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12946        final boolean lenientBackgroundCheck =
12947                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12948        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12949        final boolean forceResizable = Settings.Global.getInt(
12950                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12951        final boolean supportsLeanbackOnly =
12952                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12953
12954        // Transfer any global setting for forcing RTL layout, into a System Property
12955        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12956
12957        final Configuration configuration = new Configuration();
12958        Settings.System.getConfiguration(resolver, configuration);
12959        if (forceRtl) {
12960            // This will take care of setting the correct layout direction flags
12961            configuration.setLayoutDirection(configuration.locale);
12962        }
12963
12964        synchronized (this) {
12965            mDebugApp = mOrigDebugApp = debugApp;
12966            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12967            mAlwaysFinishActivities = alwaysFinishActivities;
12968            mLenientBackgroundCheck = lenientBackgroundCheck;
12969            mSupportsLeanbackOnly = supportsLeanbackOnly;
12970            mForceResizableActivities = forceResizable;
12971            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12972            if (supportsMultiWindow || forceResizable) {
12973                mSupportsMultiWindow = true;
12974                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12975                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12976            } else {
12977                mSupportsMultiWindow = false;
12978                mSupportsFreeformWindowManagement = false;
12979                mSupportsPictureInPicture = false;
12980            }
12981            // This happens before any activities are started, so we can
12982            // change mConfiguration in-place.
12983            updateConfigurationLocked(configuration, null, true);
12984            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12985                    "Initial config: " + mConfiguration);
12986
12987            // Load resources only after the current configuration has been set.
12988            final Resources res = mContext.getResources();
12989            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12990            mThumbnailWidth = res.getDimensionPixelSize(
12991                    com.android.internal.R.dimen.thumbnail_width);
12992            mThumbnailHeight = res.getDimensionPixelSize(
12993                    com.android.internal.R.dimen.thumbnail_height);
12994            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12995                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12996            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12997                    com.android.internal.R.string.config_appsNotReportingCrashes));
12998            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12999                mFullscreenThumbnailScale = (float) res
13000                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13001                    (float) mConfiguration.screenWidthDp;
13002            } else {
13003                mFullscreenThumbnailScale = res.getFraction(
13004                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13005            }
13006        }
13007    }
13008
13009    public boolean testIsSystemReady() {
13010        // no need to synchronize(this) just to read & return the value
13011        return mSystemReady;
13012    }
13013
13014    public void systemReady(final Runnable goingCallback) {
13015        synchronized(this) {
13016            if (mSystemReady) {
13017                // If we're done calling all the receivers, run the next "boot phase" passed in
13018                // by the SystemServer
13019                if (goingCallback != null) {
13020                    goingCallback.run();
13021                }
13022                return;
13023            }
13024
13025            mLocalDeviceIdleController
13026                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13027
13028            // Make sure we have the current profile info, since it is needed for security checks.
13029            mUserController.onSystemReady();
13030            mRecentTasks.onSystemReadyLocked();
13031            mAppOpsService.systemReady();
13032            mSystemReady = true;
13033        }
13034
13035        ArrayList<ProcessRecord> procsToKill = null;
13036        synchronized(mPidsSelfLocked) {
13037            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13038                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13039                if (!isAllowedWhileBooting(proc.info)){
13040                    if (procsToKill == null) {
13041                        procsToKill = new ArrayList<ProcessRecord>();
13042                    }
13043                    procsToKill.add(proc);
13044                }
13045            }
13046        }
13047
13048        synchronized(this) {
13049            if (procsToKill != null) {
13050                for (int i=procsToKill.size()-1; i>=0; i--) {
13051                    ProcessRecord proc = procsToKill.get(i);
13052                    Slog.i(TAG, "Removing system update proc: " + proc);
13053                    removeProcessLocked(proc, true, false, "system update done");
13054                }
13055            }
13056
13057            // Now that we have cleaned up any update processes, we
13058            // are ready to start launching real processes and know that
13059            // we won't trample on them any more.
13060            mProcessesReady = true;
13061        }
13062
13063        Slog.i(TAG, "System now ready");
13064        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13065            SystemClock.uptimeMillis());
13066
13067        synchronized(this) {
13068            // Make sure we have no pre-ready processes sitting around.
13069
13070            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13071                ResolveInfo ri = mContext.getPackageManager()
13072                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13073                                STOCK_PM_FLAGS);
13074                CharSequence errorMsg = null;
13075                if (ri != null) {
13076                    ActivityInfo ai = ri.activityInfo;
13077                    ApplicationInfo app = ai.applicationInfo;
13078                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13079                        mTopAction = Intent.ACTION_FACTORY_TEST;
13080                        mTopData = null;
13081                        mTopComponent = new ComponentName(app.packageName,
13082                                ai.name);
13083                    } else {
13084                        errorMsg = mContext.getResources().getText(
13085                                com.android.internal.R.string.factorytest_not_system);
13086                    }
13087                } else {
13088                    errorMsg = mContext.getResources().getText(
13089                            com.android.internal.R.string.factorytest_no_action);
13090                }
13091                if (errorMsg != null) {
13092                    mTopAction = null;
13093                    mTopData = null;
13094                    mTopComponent = null;
13095                    Message msg = Message.obtain();
13096                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13097                    msg.getData().putCharSequence("msg", errorMsg);
13098                    mUiHandler.sendMessage(msg);
13099                }
13100            }
13101        }
13102
13103        retrieveSettings();
13104        final int currentUserId;
13105        synchronized (this) {
13106            currentUserId = mUserController.getCurrentUserIdLocked();
13107            readGrantedUriPermissionsLocked();
13108        }
13109
13110        if (goingCallback != null) goingCallback.run();
13111
13112        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13113                Integer.toString(currentUserId), currentUserId);
13114        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13115                Integer.toString(currentUserId), currentUserId);
13116        mSystemServiceManager.startUser(currentUserId);
13117
13118        synchronized (this) {
13119            // Only start up encryption-aware persistent apps; once user is
13120            // unlocked we'll come back around and start unaware apps
13121            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13122
13123            // Start up initial activity.
13124            mBooting = true;
13125            // Enable home activity for system user, so that the system can always boot
13126            if (UserManager.isSplitSystemUser()) {
13127                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13128                try {
13129                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13130                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13131                            UserHandle.USER_SYSTEM);
13132                } catch (RemoteException e) {
13133                    throw e.rethrowAsRuntimeException();
13134                }
13135            }
13136            startHomeActivityLocked(currentUserId, "systemReady");
13137
13138            try {
13139                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13140                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13141                            + " data partition or your device will be unstable.");
13142                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13143                }
13144            } catch (RemoteException e) {
13145            }
13146
13147            if (!Build.isBuildConsistent()) {
13148                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13149                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13150            }
13151
13152            long ident = Binder.clearCallingIdentity();
13153            try {
13154                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13155                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13156                        | Intent.FLAG_RECEIVER_FOREGROUND);
13157                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13158                broadcastIntentLocked(null, null, intent,
13159                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13160                        null, false, false, MY_PID, Process.SYSTEM_UID,
13161                        currentUserId);
13162                intent = new Intent(Intent.ACTION_USER_STARTING);
13163                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13164                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13165                broadcastIntentLocked(null, null, intent,
13166                        null, new IIntentReceiver.Stub() {
13167                            @Override
13168                            public void performReceive(Intent intent, int resultCode, String data,
13169                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13170                                    throws RemoteException {
13171                            }
13172                        }, 0, null, null,
13173                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13174                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13175            } catch (Throwable t) {
13176                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13177            } finally {
13178                Binder.restoreCallingIdentity(ident);
13179            }
13180            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13181            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13182        }
13183    }
13184
13185    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13186        synchronized (this) {
13187            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13188        }
13189    }
13190
13191    void skipCurrentReceiverLocked(ProcessRecord app) {
13192        for (BroadcastQueue queue : mBroadcastQueues) {
13193            queue.skipCurrentReceiverLocked(app);
13194        }
13195    }
13196
13197    /**
13198     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13199     * The application process will exit immediately after this call returns.
13200     * @param app object of the crashing app, null for the system server
13201     * @param crashInfo describing the exception
13202     */
13203    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13204        ProcessRecord r = findAppProcess(app, "Crash");
13205        final String processName = app == null ? "system_server"
13206                : (r == null ? "unknown" : r.processName);
13207
13208        handleApplicationCrashInner("crash", r, processName, crashInfo);
13209    }
13210
13211    /* Native crash reporting uses this inner version because it needs to be somewhat
13212     * decoupled from the AM-managed cleanup lifecycle
13213     */
13214    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13215            ApplicationErrorReport.CrashInfo crashInfo) {
13216        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13217                UserHandle.getUserId(Binder.getCallingUid()), processName,
13218                r == null ? -1 : r.info.flags,
13219                crashInfo.exceptionClassName,
13220                crashInfo.exceptionMessage,
13221                crashInfo.throwFileName,
13222                crashInfo.throwLineNumber);
13223
13224        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13225
13226        mAppErrors.crashApplication(r, crashInfo);
13227    }
13228
13229    public void handleApplicationStrictModeViolation(
13230            IBinder app,
13231            int violationMask,
13232            StrictMode.ViolationInfo info) {
13233        ProcessRecord r = findAppProcess(app, "StrictMode");
13234        if (r == null) {
13235            return;
13236        }
13237
13238        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13239            Integer stackFingerprint = info.hashCode();
13240            boolean logIt = true;
13241            synchronized (mAlreadyLoggedViolatedStacks) {
13242                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13243                    logIt = false;
13244                    // TODO: sub-sample into EventLog for these, with
13245                    // the info.durationMillis?  Then we'd get
13246                    // the relative pain numbers, without logging all
13247                    // the stack traces repeatedly.  We'd want to do
13248                    // likewise in the client code, which also does
13249                    // dup suppression, before the Binder call.
13250                } else {
13251                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13252                        mAlreadyLoggedViolatedStacks.clear();
13253                    }
13254                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13255                }
13256            }
13257            if (logIt) {
13258                logStrictModeViolationToDropBox(r, info);
13259            }
13260        }
13261
13262        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13263            AppErrorResult result = new AppErrorResult();
13264            synchronized (this) {
13265                final long origId = Binder.clearCallingIdentity();
13266
13267                Message msg = Message.obtain();
13268                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13269                HashMap<String, Object> data = new HashMap<String, Object>();
13270                data.put("result", result);
13271                data.put("app", r);
13272                data.put("violationMask", violationMask);
13273                data.put("info", info);
13274                msg.obj = data;
13275                mUiHandler.sendMessage(msg);
13276
13277                Binder.restoreCallingIdentity(origId);
13278            }
13279            int res = result.get();
13280            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13281        }
13282    }
13283
13284    // Depending on the policy in effect, there could be a bunch of
13285    // these in quick succession so we try to batch these together to
13286    // minimize disk writes, number of dropbox entries, and maximize
13287    // compression, by having more fewer, larger records.
13288    private void logStrictModeViolationToDropBox(
13289            ProcessRecord process,
13290            StrictMode.ViolationInfo info) {
13291        if (info == null) {
13292            return;
13293        }
13294        final boolean isSystemApp = process == null ||
13295                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13296                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13297        final String processName = process == null ? "unknown" : process.processName;
13298        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13299        final DropBoxManager dbox = (DropBoxManager)
13300                mContext.getSystemService(Context.DROPBOX_SERVICE);
13301
13302        // Exit early if the dropbox isn't configured to accept this report type.
13303        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13304
13305        boolean bufferWasEmpty;
13306        boolean needsFlush;
13307        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13308        synchronized (sb) {
13309            bufferWasEmpty = sb.length() == 0;
13310            appendDropBoxProcessHeaders(process, processName, sb);
13311            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13312            sb.append("System-App: ").append(isSystemApp).append("\n");
13313            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13314            if (info.violationNumThisLoop != 0) {
13315                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13316            }
13317            if (info.numAnimationsRunning != 0) {
13318                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13319            }
13320            if (info.broadcastIntentAction != null) {
13321                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13322            }
13323            if (info.durationMillis != -1) {
13324                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13325            }
13326            if (info.numInstances != -1) {
13327                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13328            }
13329            if (info.tags != null) {
13330                for (String tag : info.tags) {
13331                    sb.append("Span-Tag: ").append(tag).append("\n");
13332                }
13333            }
13334            sb.append("\n");
13335            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13336                sb.append(info.crashInfo.stackTrace);
13337                sb.append("\n");
13338            }
13339            if (info.message != null) {
13340                sb.append(info.message);
13341                sb.append("\n");
13342            }
13343
13344            // Only buffer up to ~64k.  Various logging bits truncate
13345            // things at 128k.
13346            needsFlush = (sb.length() > 64 * 1024);
13347        }
13348
13349        // Flush immediately if the buffer's grown too large, or this
13350        // is a non-system app.  Non-system apps are isolated with a
13351        // different tag & policy and not batched.
13352        //
13353        // Batching is useful during internal testing with
13354        // StrictMode settings turned up high.  Without batching,
13355        // thousands of separate files could be created on boot.
13356        if (!isSystemApp || needsFlush) {
13357            new Thread("Error dump: " + dropboxTag) {
13358                @Override
13359                public void run() {
13360                    String report;
13361                    synchronized (sb) {
13362                        report = sb.toString();
13363                        sb.delete(0, sb.length());
13364                        sb.trimToSize();
13365                    }
13366                    if (report.length() != 0) {
13367                        dbox.addText(dropboxTag, report);
13368                    }
13369                }
13370            }.start();
13371            return;
13372        }
13373
13374        // System app batching:
13375        if (!bufferWasEmpty) {
13376            // An existing dropbox-writing thread is outstanding, so
13377            // we don't need to start it up.  The existing thread will
13378            // catch the buffer appends we just did.
13379            return;
13380        }
13381
13382        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13383        // (After this point, we shouldn't access AMS internal data structures.)
13384        new Thread("Error dump: " + dropboxTag) {
13385            @Override
13386            public void run() {
13387                // 5 second sleep to let stacks arrive and be batched together
13388                try {
13389                    Thread.sleep(5000);  // 5 seconds
13390                } catch (InterruptedException e) {}
13391
13392                String errorReport;
13393                synchronized (mStrictModeBuffer) {
13394                    errorReport = mStrictModeBuffer.toString();
13395                    if (errorReport.length() == 0) {
13396                        return;
13397                    }
13398                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13399                    mStrictModeBuffer.trimToSize();
13400                }
13401                dbox.addText(dropboxTag, errorReport);
13402            }
13403        }.start();
13404    }
13405
13406    /**
13407     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13408     * @param app object of the crashing app, null for the system server
13409     * @param tag reported by the caller
13410     * @param system whether this wtf is coming from the system
13411     * @param crashInfo describing the context of the error
13412     * @return true if the process should exit immediately (WTF is fatal)
13413     */
13414    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13415            final ApplicationErrorReport.CrashInfo crashInfo) {
13416        final int callingUid = Binder.getCallingUid();
13417        final int callingPid = Binder.getCallingPid();
13418
13419        if (system) {
13420            // If this is coming from the system, we could very well have low-level
13421            // system locks held, so we want to do this all asynchronously.  And we
13422            // never want this to become fatal, so there is that too.
13423            mHandler.post(new Runnable() {
13424                @Override public void run() {
13425                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13426                }
13427            });
13428            return false;
13429        }
13430
13431        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13432                crashInfo);
13433
13434        if (r != null && r.pid != Process.myPid() &&
13435                Settings.Global.getInt(mContext.getContentResolver(),
13436                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13437            mAppErrors.crashApplication(r, crashInfo);
13438            return true;
13439        } else {
13440            return false;
13441        }
13442    }
13443
13444    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13445            final ApplicationErrorReport.CrashInfo crashInfo) {
13446        final ProcessRecord r = findAppProcess(app, "WTF");
13447        final String processName = app == null ? "system_server"
13448                : (r == null ? "unknown" : r.processName);
13449
13450        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13451                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13452
13453        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13454
13455        return r;
13456    }
13457
13458    /**
13459     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13460     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13461     */
13462    private ProcessRecord findAppProcess(IBinder app, String reason) {
13463        if (app == null) {
13464            return null;
13465        }
13466
13467        synchronized (this) {
13468            final int NP = mProcessNames.getMap().size();
13469            for (int ip=0; ip<NP; ip++) {
13470                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13471                final int NA = apps.size();
13472                for (int ia=0; ia<NA; ia++) {
13473                    ProcessRecord p = apps.valueAt(ia);
13474                    if (p.thread != null && p.thread.asBinder() == app) {
13475                        return p;
13476                    }
13477                }
13478            }
13479
13480            Slog.w(TAG, "Can't find mystery application for " + reason
13481                    + " from pid=" + Binder.getCallingPid()
13482                    + " uid=" + Binder.getCallingUid() + ": " + app);
13483            return null;
13484        }
13485    }
13486
13487    /**
13488     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13489     * to append various headers to the dropbox log text.
13490     */
13491    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13492            StringBuilder sb) {
13493        // Watchdog thread ends up invoking this function (with
13494        // a null ProcessRecord) to add the stack file to dropbox.
13495        // Do not acquire a lock on this (am) in such cases, as it
13496        // could cause a potential deadlock, if and when watchdog
13497        // is invoked due to unavailability of lock on am and it
13498        // would prevent watchdog from killing system_server.
13499        if (process == null) {
13500            sb.append("Process: ").append(processName).append("\n");
13501            return;
13502        }
13503        // Note: ProcessRecord 'process' is guarded by the service
13504        // instance.  (notably process.pkgList, which could otherwise change
13505        // concurrently during execution of this method)
13506        synchronized (this) {
13507            sb.append("Process: ").append(processName).append("\n");
13508            int flags = process.info.flags;
13509            IPackageManager pm = AppGlobals.getPackageManager();
13510            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13511            for (int ip=0; ip<process.pkgList.size(); ip++) {
13512                String pkg = process.pkgList.keyAt(ip);
13513                sb.append("Package: ").append(pkg);
13514                try {
13515                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13516                    if (pi != null) {
13517                        sb.append(" v").append(pi.versionCode);
13518                        if (pi.versionName != null) {
13519                            sb.append(" (").append(pi.versionName).append(")");
13520                        }
13521                    }
13522                } catch (RemoteException e) {
13523                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13524                }
13525                sb.append("\n");
13526            }
13527        }
13528    }
13529
13530    private static String processClass(ProcessRecord process) {
13531        if (process == null || process.pid == MY_PID) {
13532            return "system_server";
13533        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13534            return "system_app";
13535        } else {
13536            return "data_app";
13537        }
13538    }
13539
13540    private volatile long mWtfClusterStart;
13541    private volatile int mWtfClusterCount;
13542
13543    /**
13544     * Write a description of an error (crash, WTF, ANR) to the drop box.
13545     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13546     * @param process which caused the error, null means the system server
13547     * @param activity which triggered the error, null if unknown
13548     * @param parent activity related to the error, null if unknown
13549     * @param subject line related to the error, null if absent
13550     * @param report in long form describing the error, null if absent
13551     * @param dataFile text file to include in the report, null if none
13552     * @param crashInfo giving an application stack trace, null if absent
13553     */
13554    public void addErrorToDropBox(String eventType,
13555            ProcessRecord process, String processName, ActivityRecord activity,
13556            ActivityRecord parent, String subject,
13557            final String report, final File dataFile,
13558            final ApplicationErrorReport.CrashInfo crashInfo) {
13559        // NOTE -- this must never acquire the ActivityManagerService lock,
13560        // otherwise the watchdog may be prevented from resetting the system.
13561
13562        final String dropboxTag = processClass(process) + "_" + eventType;
13563        final DropBoxManager dbox = (DropBoxManager)
13564                mContext.getSystemService(Context.DROPBOX_SERVICE);
13565
13566        // Exit early if the dropbox isn't configured to accept this report type.
13567        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13568
13569        // Rate-limit how often we're willing to do the heavy lifting below to
13570        // collect and record logs; currently 5 logs per 10 second period.
13571        final long now = SystemClock.elapsedRealtime();
13572        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13573            mWtfClusterStart = now;
13574            mWtfClusterCount = 1;
13575        } else {
13576            if (mWtfClusterCount++ >= 5) return;
13577        }
13578
13579        final StringBuilder sb = new StringBuilder(1024);
13580        appendDropBoxProcessHeaders(process, processName, sb);
13581        if (process != null) {
13582            sb.append("Foreground: ")
13583                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13584                    .append("\n");
13585        }
13586        if (activity != null) {
13587            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13588        }
13589        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13590            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13591        }
13592        if (parent != null && parent != activity) {
13593            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13594        }
13595        if (subject != null) {
13596            sb.append("Subject: ").append(subject).append("\n");
13597        }
13598        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13599        if (Debug.isDebuggerConnected()) {
13600            sb.append("Debugger: Connected\n");
13601        }
13602        sb.append("\n");
13603
13604        // Do the rest in a worker thread to avoid blocking the caller on I/O
13605        // (After this point, we shouldn't access AMS internal data structures.)
13606        Thread worker = new Thread("Error dump: " + dropboxTag) {
13607            @Override
13608            public void run() {
13609                if (report != null) {
13610                    sb.append(report);
13611                }
13612
13613                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13614                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13615                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13616                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13617
13618                if (dataFile != null && maxDataFileSize > 0) {
13619                    try {
13620                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13621                                    "\n\n[[TRUNCATED]]"));
13622                    } catch (IOException e) {
13623                        Slog.e(TAG, "Error reading " + dataFile, e);
13624                    }
13625                }
13626                if (crashInfo != null && crashInfo.stackTrace != null) {
13627                    sb.append(crashInfo.stackTrace);
13628                }
13629
13630                if (lines > 0) {
13631                    sb.append("\n");
13632
13633                    // Merge several logcat streams, and take the last N lines
13634                    InputStreamReader input = null;
13635                    try {
13636                        java.lang.Process logcat = new ProcessBuilder(
13637                                "/system/bin/timeout", "-k", "15s", "10s",
13638                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13639                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13640                                        .redirectErrorStream(true).start();
13641
13642                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13643                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13644                        input = new InputStreamReader(logcat.getInputStream());
13645
13646                        int num;
13647                        char[] buf = new char[8192];
13648                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13649                    } catch (IOException e) {
13650                        Slog.e(TAG, "Error running logcat", e);
13651                    } finally {
13652                        if (input != null) try { input.close(); } catch (IOException e) {}
13653                    }
13654                }
13655
13656                dbox.addText(dropboxTag, sb.toString());
13657            }
13658        };
13659
13660        if (process == null) {
13661            // If process is null, we are being called from some internal code
13662            // and may be about to die -- run this synchronously.
13663            worker.run();
13664        } else {
13665            worker.start();
13666        }
13667    }
13668
13669    @Override
13670    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13671        enforceNotIsolatedCaller("getProcessesInErrorState");
13672        // assume our apps are happy - lazy create the list
13673        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13674
13675        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13676                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13677        int userId = UserHandle.getUserId(Binder.getCallingUid());
13678
13679        synchronized (this) {
13680
13681            // iterate across all processes
13682            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13683                ProcessRecord app = mLruProcesses.get(i);
13684                if (!allUsers && app.userId != userId) {
13685                    continue;
13686                }
13687                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13688                    // This one's in trouble, so we'll generate a report for it
13689                    // crashes are higher priority (in case there's a crash *and* an anr)
13690                    ActivityManager.ProcessErrorStateInfo report = null;
13691                    if (app.crashing) {
13692                        report = app.crashingReport;
13693                    } else if (app.notResponding) {
13694                        report = app.notRespondingReport;
13695                    }
13696
13697                    if (report != null) {
13698                        if (errList == null) {
13699                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13700                        }
13701                        errList.add(report);
13702                    } else {
13703                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13704                                " crashing = " + app.crashing +
13705                                " notResponding = " + app.notResponding);
13706                    }
13707                }
13708            }
13709        }
13710
13711        return errList;
13712    }
13713
13714    static int procStateToImportance(int procState, int memAdj,
13715            ActivityManager.RunningAppProcessInfo currApp) {
13716        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13717        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13718            currApp.lru = memAdj;
13719        } else {
13720            currApp.lru = 0;
13721        }
13722        return imp;
13723    }
13724
13725    private void fillInProcMemInfo(ProcessRecord app,
13726            ActivityManager.RunningAppProcessInfo outInfo) {
13727        outInfo.pid = app.pid;
13728        outInfo.uid = app.info.uid;
13729        if (mHeavyWeightProcess == app) {
13730            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13731        }
13732        if (app.persistent) {
13733            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13734        }
13735        if (app.activities.size() > 0) {
13736            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13737        }
13738        outInfo.lastTrimLevel = app.trimMemoryLevel;
13739        int adj = app.curAdj;
13740        int procState = app.curProcState;
13741        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13742        outInfo.importanceReasonCode = app.adjTypeCode;
13743        outInfo.processState = app.curProcState;
13744    }
13745
13746    @Override
13747    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13748        enforceNotIsolatedCaller("getRunningAppProcesses");
13749
13750        final int callingUid = Binder.getCallingUid();
13751
13752        // Lazy instantiation of list
13753        List<ActivityManager.RunningAppProcessInfo> runList = null;
13754        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13755                callingUid) == PackageManager.PERMISSION_GRANTED;
13756        final int userId = UserHandle.getUserId(callingUid);
13757        final boolean allUids = isGetTasksAllowed(
13758                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13759
13760        synchronized (this) {
13761            // Iterate across all processes
13762            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13763                ProcessRecord app = mLruProcesses.get(i);
13764                if ((!allUsers && app.userId != userId)
13765                        || (!allUids && app.uid != callingUid)) {
13766                    continue;
13767                }
13768                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13769                    // Generate process state info for running application
13770                    ActivityManager.RunningAppProcessInfo currApp =
13771                        new ActivityManager.RunningAppProcessInfo(app.processName,
13772                                app.pid, app.getPackageList());
13773                    fillInProcMemInfo(app, currApp);
13774                    if (app.adjSource instanceof ProcessRecord) {
13775                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13776                        currApp.importanceReasonImportance =
13777                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13778                                        app.adjSourceProcState);
13779                    } else if (app.adjSource instanceof ActivityRecord) {
13780                        ActivityRecord r = (ActivityRecord)app.adjSource;
13781                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13782                    }
13783                    if (app.adjTarget instanceof ComponentName) {
13784                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13785                    }
13786                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13787                    //        + " lru=" + currApp.lru);
13788                    if (runList == null) {
13789                        runList = new ArrayList<>();
13790                    }
13791                    runList.add(currApp);
13792                }
13793            }
13794        }
13795        return runList;
13796    }
13797
13798    @Override
13799    public List<ApplicationInfo> getRunningExternalApplications() {
13800        enforceNotIsolatedCaller("getRunningExternalApplications");
13801        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13802        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13803        if (runningApps != null && runningApps.size() > 0) {
13804            Set<String> extList = new HashSet<String>();
13805            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13806                if (app.pkgList != null) {
13807                    for (String pkg : app.pkgList) {
13808                        extList.add(pkg);
13809                    }
13810                }
13811            }
13812            IPackageManager pm = AppGlobals.getPackageManager();
13813            for (String pkg : extList) {
13814                try {
13815                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13816                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13817                        retList.add(info);
13818                    }
13819                } catch (RemoteException e) {
13820                }
13821            }
13822        }
13823        return retList;
13824    }
13825
13826    @Override
13827    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13828        enforceNotIsolatedCaller("getMyMemoryState");
13829        synchronized (this) {
13830            ProcessRecord proc;
13831            synchronized (mPidsSelfLocked) {
13832                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13833            }
13834            fillInProcMemInfo(proc, outInfo);
13835        }
13836    }
13837
13838    @Override
13839    public int getMemoryTrimLevel() {
13840        enforceNotIsolatedCaller("getMyMemoryState");
13841        synchronized (this) {
13842            return mLastMemoryLevel;
13843        }
13844    }
13845
13846    @Override
13847    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13848            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13849        (new ActivityManagerShellCommand(this, false)).exec(
13850                this, in, out, err, args, resultReceiver);
13851    }
13852
13853    @Override
13854    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13855        if (checkCallingPermission(android.Manifest.permission.DUMP)
13856                != PackageManager.PERMISSION_GRANTED) {
13857            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13858                    + Binder.getCallingPid()
13859                    + ", uid=" + Binder.getCallingUid()
13860                    + " without permission "
13861                    + android.Manifest.permission.DUMP);
13862            return;
13863        }
13864
13865        boolean dumpAll = false;
13866        boolean dumpClient = false;
13867        boolean dumpCheckin = false;
13868        boolean dumpCheckinFormat = false;
13869        String dumpPackage = null;
13870
13871        int opti = 0;
13872        while (opti < args.length) {
13873            String opt = args[opti];
13874            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13875                break;
13876            }
13877            opti++;
13878            if ("-a".equals(opt)) {
13879                dumpAll = true;
13880            } else if ("-c".equals(opt)) {
13881                dumpClient = true;
13882            } else if ("-p".equals(opt)) {
13883                if (opti < args.length) {
13884                    dumpPackage = args[opti];
13885                    opti++;
13886                } else {
13887                    pw.println("Error: -p option requires package argument");
13888                    return;
13889                }
13890                dumpClient = true;
13891            } else if ("--checkin".equals(opt)) {
13892                dumpCheckin = dumpCheckinFormat = true;
13893            } else if ("-C".equals(opt)) {
13894                dumpCheckinFormat = true;
13895            } else if ("-h".equals(opt)) {
13896                ActivityManagerShellCommand.dumpHelp(pw, true);
13897                return;
13898            } else {
13899                pw.println("Unknown argument: " + opt + "; use -h for help");
13900            }
13901        }
13902
13903        long origId = Binder.clearCallingIdentity();
13904        boolean more = false;
13905        // Is the caller requesting to dump a particular piece of data?
13906        if (opti < args.length) {
13907            String cmd = args[opti];
13908            opti++;
13909            if ("activities".equals(cmd) || "a".equals(cmd)) {
13910                synchronized (this) {
13911                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13912                }
13913            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13914                synchronized (this) {
13915                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13916                }
13917            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13918                String[] newArgs;
13919                String name;
13920                if (opti >= args.length) {
13921                    name = null;
13922                    newArgs = EMPTY_STRING_ARRAY;
13923                } else {
13924                    dumpPackage = args[opti];
13925                    opti++;
13926                    newArgs = new String[args.length - opti];
13927                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13928                            args.length - opti);
13929                }
13930                synchronized (this) {
13931                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13932                }
13933            } else if ("broadcast-stats".equals(cmd)) {
13934                String[] newArgs;
13935                String name;
13936                if (opti >= args.length) {
13937                    name = null;
13938                    newArgs = EMPTY_STRING_ARRAY;
13939                } else {
13940                    dumpPackage = args[opti];
13941                    opti++;
13942                    newArgs = new String[args.length - opti];
13943                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13944                            args.length - opti);
13945                }
13946                synchronized (this) {
13947                    if (dumpCheckinFormat) {
13948                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13949                                dumpPackage);
13950                    } else {
13951                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13952                    }
13953                }
13954            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13955                String[] newArgs;
13956                String name;
13957                if (opti >= args.length) {
13958                    name = null;
13959                    newArgs = EMPTY_STRING_ARRAY;
13960                } else {
13961                    dumpPackage = args[opti];
13962                    opti++;
13963                    newArgs = new String[args.length - opti];
13964                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13965                            args.length - opti);
13966                }
13967                synchronized (this) {
13968                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13969                }
13970            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13971                String[] newArgs;
13972                String name;
13973                if (opti >= args.length) {
13974                    name = null;
13975                    newArgs = EMPTY_STRING_ARRAY;
13976                } else {
13977                    dumpPackage = args[opti];
13978                    opti++;
13979                    newArgs = new String[args.length - opti];
13980                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13981                            args.length - opti);
13982                }
13983                synchronized (this) {
13984                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13985                }
13986            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13987                synchronized (this) {
13988                    dumpOomLocked(fd, pw, args, opti, true);
13989                }
13990            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13991                synchronized (this) {
13992                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13993                }
13994            } else if ("provider".equals(cmd)) {
13995                String[] newArgs;
13996                String name;
13997                if (opti >= args.length) {
13998                    name = null;
13999                    newArgs = EMPTY_STRING_ARRAY;
14000                } else {
14001                    name = args[opti];
14002                    opti++;
14003                    newArgs = new String[args.length - opti];
14004                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14005                }
14006                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14007                    pw.println("No providers match: " + name);
14008                    pw.println("Use -h for help.");
14009                }
14010            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14011                synchronized (this) {
14012                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14013                }
14014            } else if ("service".equals(cmd)) {
14015                String[] newArgs;
14016                String name;
14017                if (opti >= args.length) {
14018                    name = null;
14019                    newArgs = EMPTY_STRING_ARRAY;
14020                } else {
14021                    name = args[opti];
14022                    opti++;
14023                    newArgs = new String[args.length - opti];
14024                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14025                            args.length - opti);
14026                }
14027                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14028                    pw.println("No services match: " + name);
14029                    pw.println("Use -h for help.");
14030                }
14031            } else if ("package".equals(cmd)) {
14032                String[] newArgs;
14033                if (opti >= args.length) {
14034                    pw.println("package: no package name specified");
14035                    pw.println("Use -h for help.");
14036                } else {
14037                    dumpPackage = args[opti];
14038                    opti++;
14039                    newArgs = new String[args.length - opti];
14040                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14041                            args.length - opti);
14042                    args = newArgs;
14043                    opti = 0;
14044                    more = true;
14045                }
14046            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14047                synchronized (this) {
14048                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14049                }
14050            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14051                if (dumpClient) {
14052                    ActiveServices.ServiceDumper dumper;
14053                    synchronized (this) {
14054                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14055                                dumpPackage);
14056                    }
14057                    dumper.dumpWithClient();
14058                } else {
14059                    synchronized (this) {
14060                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14061                                dumpPackage).dumpLocked();
14062                    }
14063                }
14064            } else if ("locks".equals(cmd)) {
14065                LockGuard.dump(fd, pw, args);
14066            } else {
14067                // Dumping a single activity?
14068                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14069                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14070                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14071                    if (res < 0) {
14072                        pw.println("Bad activity command, or no activities match: " + cmd);
14073                        pw.println("Use -h for help.");
14074                    }
14075                }
14076            }
14077            if (!more) {
14078                Binder.restoreCallingIdentity(origId);
14079                return;
14080            }
14081        }
14082
14083        // No piece of data specified, dump everything.
14084        if (dumpCheckinFormat) {
14085            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14086        } else if (dumpClient) {
14087            ActiveServices.ServiceDumper sdumper;
14088            synchronized (this) {
14089                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14090                pw.println();
14091                if (dumpAll) {
14092                    pw.println("-------------------------------------------------------------------------------");
14093                }
14094                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14095                pw.println();
14096                if (dumpAll) {
14097                    pw.println("-------------------------------------------------------------------------------");
14098                }
14099                if (dumpAll || dumpPackage != null) {
14100                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14101                    pw.println();
14102                    if (dumpAll) {
14103                        pw.println("-------------------------------------------------------------------------------");
14104                    }
14105                }
14106                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14107                pw.println();
14108                if (dumpAll) {
14109                    pw.println("-------------------------------------------------------------------------------");
14110                }
14111                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14112                pw.println();
14113                if (dumpAll) {
14114                    pw.println("-------------------------------------------------------------------------------");
14115                }
14116                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14117                        dumpPackage);
14118            }
14119            sdumper.dumpWithClient();
14120            pw.println();
14121            synchronized (this) {
14122                if (dumpAll) {
14123                    pw.println("-------------------------------------------------------------------------------");
14124                }
14125                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14126                pw.println();
14127                if (dumpAll) {
14128                    pw.println("-------------------------------------------------------------------------------");
14129                }
14130                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14131                if (mAssociations.size() > 0) {
14132                    pw.println();
14133                    if (dumpAll) {
14134                        pw.println("-------------------------------------------------------------------------------");
14135                    }
14136                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14137                }
14138                pw.println();
14139                if (dumpAll) {
14140                    pw.println("-------------------------------------------------------------------------------");
14141                }
14142                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14143            }
14144
14145        } else {
14146            synchronized (this) {
14147                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14148                pw.println();
14149                if (dumpAll) {
14150                    pw.println("-------------------------------------------------------------------------------");
14151                }
14152                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14153                pw.println();
14154                if (dumpAll) {
14155                    pw.println("-------------------------------------------------------------------------------");
14156                }
14157                if (dumpAll || dumpPackage != null) {
14158                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14159                    pw.println();
14160                    if (dumpAll) {
14161                        pw.println("-------------------------------------------------------------------------------");
14162                    }
14163                }
14164                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14165                pw.println();
14166                if (dumpAll) {
14167                    pw.println("-------------------------------------------------------------------------------");
14168                }
14169                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14170                pw.println();
14171                if (dumpAll) {
14172                    pw.println("-------------------------------------------------------------------------------");
14173                }
14174                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14175                        .dumpLocked();
14176                pw.println();
14177                if (dumpAll) {
14178                    pw.println("-------------------------------------------------------------------------------");
14179                }
14180                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14181                pw.println();
14182                if (dumpAll) {
14183                    pw.println("-------------------------------------------------------------------------------");
14184                }
14185                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14186                if (mAssociations.size() > 0) {
14187                    pw.println();
14188                    if (dumpAll) {
14189                        pw.println("-------------------------------------------------------------------------------");
14190                    }
14191                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14192                }
14193                pw.println();
14194                if (dumpAll) {
14195                    pw.println("-------------------------------------------------------------------------------");
14196                }
14197                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14198            }
14199        }
14200        Binder.restoreCallingIdentity(origId);
14201    }
14202
14203    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14204            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14205        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14206
14207        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14208                dumpPackage);
14209        boolean needSep = printedAnything;
14210
14211        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14212                dumpPackage, needSep, "  mFocusedActivity: ");
14213        if (printed) {
14214            printedAnything = true;
14215            needSep = false;
14216        }
14217
14218        if (dumpPackage == null) {
14219            if (needSep) {
14220                pw.println();
14221            }
14222            needSep = true;
14223            printedAnything = true;
14224            mStackSupervisor.dump(pw, "  ");
14225        }
14226
14227        if (!printedAnything) {
14228            pw.println("  (nothing)");
14229        }
14230    }
14231
14232    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14233            int opti, boolean dumpAll, String dumpPackage) {
14234        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14235
14236        boolean printedAnything = false;
14237
14238        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14239            boolean printedHeader = false;
14240
14241            final int N = mRecentTasks.size();
14242            for (int i=0; i<N; i++) {
14243                TaskRecord tr = mRecentTasks.get(i);
14244                if (dumpPackage != null) {
14245                    if (tr.realActivity == null ||
14246                            !dumpPackage.equals(tr.realActivity)) {
14247                        continue;
14248                    }
14249                }
14250                if (!printedHeader) {
14251                    pw.println("  Recent tasks:");
14252                    printedHeader = true;
14253                    printedAnything = true;
14254                }
14255                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14256                        pw.println(tr);
14257                if (dumpAll) {
14258                    mRecentTasks.get(i).dump(pw, "    ");
14259                }
14260            }
14261        }
14262
14263        if (!printedAnything) {
14264            pw.println("  (nothing)");
14265        }
14266    }
14267
14268    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14269            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14270        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14271
14272        int dumpUid = 0;
14273        if (dumpPackage != null) {
14274            IPackageManager pm = AppGlobals.getPackageManager();
14275            try {
14276                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14277            } catch (RemoteException e) {
14278            }
14279        }
14280
14281        boolean printedAnything = false;
14282
14283        final long now = SystemClock.uptimeMillis();
14284
14285        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14286            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14287                    = mAssociations.valueAt(i1);
14288            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14289                SparseArray<ArrayMap<String, Association>> sourceUids
14290                        = targetComponents.valueAt(i2);
14291                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14292                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14293                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14294                        Association ass = sourceProcesses.valueAt(i4);
14295                        if (dumpPackage != null) {
14296                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14297                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14298                                continue;
14299                            }
14300                        }
14301                        printedAnything = true;
14302                        pw.print("  ");
14303                        pw.print(ass.mTargetProcess);
14304                        pw.print("/");
14305                        UserHandle.formatUid(pw, ass.mTargetUid);
14306                        pw.print(" <- ");
14307                        pw.print(ass.mSourceProcess);
14308                        pw.print("/");
14309                        UserHandle.formatUid(pw, ass.mSourceUid);
14310                        pw.println();
14311                        pw.print("    via ");
14312                        pw.print(ass.mTargetComponent.flattenToShortString());
14313                        pw.println();
14314                        pw.print("    ");
14315                        long dur = ass.mTime;
14316                        if (ass.mNesting > 0) {
14317                            dur += now - ass.mStartTime;
14318                        }
14319                        TimeUtils.formatDuration(dur, pw);
14320                        pw.print(" (");
14321                        pw.print(ass.mCount);
14322                        pw.print(" times)");
14323                        pw.print("  ");
14324                        for (int i=0; i<ass.mStateTimes.length; i++) {
14325                            long amt = ass.mStateTimes[i];
14326                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14327                                amt += now - ass.mLastStateUptime;
14328                            }
14329                            if (amt != 0) {
14330                                pw.print(" ");
14331                                pw.print(ProcessList.makeProcStateString(
14332                                            i + ActivityManager.MIN_PROCESS_STATE));
14333                                pw.print("=");
14334                                TimeUtils.formatDuration(amt, pw);
14335                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14336                                    pw.print("*");
14337                                }
14338                            }
14339                        }
14340                        pw.println();
14341                        if (ass.mNesting > 0) {
14342                            pw.print("    Currently active: ");
14343                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14344                            pw.println();
14345                        }
14346                    }
14347                }
14348            }
14349
14350        }
14351
14352        if (!printedAnything) {
14353            pw.println("  (nothing)");
14354        }
14355    }
14356
14357    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14358            String header, boolean needSep) {
14359        boolean printed = false;
14360        int whichAppId = -1;
14361        if (dumpPackage != null) {
14362            try {
14363                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14364                        dumpPackage, 0);
14365                whichAppId = UserHandle.getAppId(info.uid);
14366            } catch (NameNotFoundException e) {
14367                e.printStackTrace();
14368            }
14369        }
14370        for (int i=0; i<uids.size(); i++) {
14371            UidRecord uidRec = uids.valueAt(i);
14372            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14373                continue;
14374            }
14375            if (!printed) {
14376                printed = true;
14377                if (needSep) {
14378                    pw.println();
14379                }
14380                pw.print("  ");
14381                pw.println(header);
14382                needSep = true;
14383            }
14384            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14385            pw.print(": "); pw.println(uidRec);
14386        }
14387        return printed;
14388    }
14389
14390    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14391            int opti, boolean dumpAll, String dumpPackage) {
14392        boolean needSep = false;
14393        boolean printedAnything = false;
14394        int numPers = 0;
14395
14396        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14397
14398        if (dumpAll) {
14399            final int NP = mProcessNames.getMap().size();
14400            for (int ip=0; ip<NP; ip++) {
14401                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14402                final int NA = procs.size();
14403                for (int ia=0; ia<NA; ia++) {
14404                    ProcessRecord r = procs.valueAt(ia);
14405                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14406                        continue;
14407                    }
14408                    if (!needSep) {
14409                        pw.println("  All known processes:");
14410                        needSep = true;
14411                        printedAnything = true;
14412                    }
14413                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14414                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14415                        pw.print(" "); pw.println(r);
14416                    r.dump(pw, "    ");
14417                    if (r.persistent) {
14418                        numPers++;
14419                    }
14420                }
14421            }
14422        }
14423
14424        if (mIsolatedProcesses.size() > 0) {
14425            boolean printed = false;
14426            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14427                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14428                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14429                    continue;
14430                }
14431                if (!printed) {
14432                    if (needSep) {
14433                        pw.println();
14434                    }
14435                    pw.println("  Isolated process list (sorted by uid):");
14436                    printedAnything = true;
14437                    printed = true;
14438                    needSep = true;
14439                }
14440                pw.println(String.format("%sIsolated #%2d: %s",
14441                        "    ", i, r.toString()));
14442            }
14443        }
14444
14445        if (mActiveUids.size() > 0) {
14446            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14447                printedAnything = needSep = true;
14448            }
14449        }
14450        if (mValidateUids.size() > 0) {
14451            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14452                printedAnything = needSep = true;
14453            }
14454        }
14455
14456        if (mLruProcesses.size() > 0) {
14457            if (needSep) {
14458                pw.println();
14459            }
14460            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14461                    pw.print(" total, non-act at ");
14462                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14463                    pw.print(", non-svc at ");
14464                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14465                    pw.println("):");
14466            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14467            needSep = true;
14468            printedAnything = true;
14469        }
14470
14471        if (dumpAll || dumpPackage != null) {
14472            synchronized (mPidsSelfLocked) {
14473                boolean printed = false;
14474                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14475                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14476                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14477                        continue;
14478                    }
14479                    if (!printed) {
14480                        if (needSep) pw.println();
14481                        needSep = true;
14482                        pw.println("  PID mappings:");
14483                        printed = true;
14484                        printedAnything = true;
14485                    }
14486                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14487                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14488                }
14489            }
14490        }
14491
14492        if (mForegroundProcesses.size() > 0) {
14493            synchronized (mPidsSelfLocked) {
14494                boolean printed = false;
14495                for (int i=0; i<mForegroundProcesses.size(); i++) {
14496                    ProcessRecord r = mPidsSelfLocked.get(
14497                            mForegroundProcesses.valueAt(i).pid);
14498                    if (dumpPackage != null && (r == null
14499                            || !r.pkgList.containsKey(dumpPackage))) {
14500                        continue;
14501                    }
14502                    if (!printed) {
14503                        if (needSep) pw.println();
14504                        needSep = true;
14505                        pw.println("  Foreground Processes:");
14506                        printed = true;
14507                        printedAnything = true;
14508                    }
14509                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14510                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14511                }
14512            }
14513        }
14514
14515        if (mPersistentStartingProcesses.size() > 0) {
14516            if (needSep) pw.println();
14517            needSep = true;
14518            printedAnything = true;
14519            pw.println("  Persisent processes that are starting:");
14520            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14521                    "Starting Norm", "Restarting PERS", dumpPackage);
14522        }
14523
14524        if (mRemovedProcesses.size() > 0) {
14525            if (needSep) pw.println();
14526            needSep = true;
14527            printedAnything = true;
14528            pw.println("  Processes that are being removed:");
14529            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14530                    "Removed Norm", "Removed PERS", dumpPackage);
14531        }
14532
14533        if (mProcessesOnHold.size() > 0) {
14534            if (needSep) pw.println();
14535            needSep = true;
14536            printedAnything = true;
14537            pw.println("  Processes that are on old until the system is ready:");
14538            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14539                    "OnHold Norm", "OnHold PERS", dumpPackage);
14540        }
14541
14542        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14543
14544        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14545        if (needSep) {
14546            printedAnything = true;
14547        }
14548
14549        if (dumpPackage == null) {
14550            pw.println();
14551            needSep = false;
14552            mUserController.dump(pw, dumpAll);
14553        }
14554        if (mHomeProcess != null && (dumpPackage == null
14555                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14556            if (needSep) {
14557                pw.println();
14558                needSep = false;
14559            }
14560            pw.println("  mHomeProcess: " + mHomeProcess);
14561        }
14562        if (mPreviousProcess != null && (dumpPackage == null
14563                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14564            if (needSep) {
14565                pw.println();
14566                needSep = false;
14567            }
14568            pw.println("  mPreviousProcess: " + mPreviousProcess);
14569        }
14570        if (dumpAll) {
14571            StringBuilder sb = new StringBuilder(128);
14572            sb.append("  mPreviousProcessVisibleTime: ");
14573            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14574            pw.println(sb);
14575        }
14576        if (mHeavyWeightProcess != null && (dumpPackage == null
14577                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14578            if (needSep) {
14579                pw.println();
14580                needSep = false;
14581            }
14582            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14583        }
14584        if (dumpPackage == null) {
14585            pw.println("  mConfiguration: " + mConfiguration);
14586        }
14587        if (dumpAll) {
14588            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14589            if (mCompatModePackages.getPackages().size() > 0) {
14590                boolean printed = false;
14591                for (Map.Entry<String, Integer> entry
14592                        : mCompatModePackages.getPackages().entrySet()) {
14593                    String pkg = entry.getKey();
14594                    int mode = entry.getValue();
14595                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14596                        continue;
14597                    }
14598                    if (!printed) {
14599                        pw.println("  mScreenCompatPackages:");
14600                        printed = true;
14601                    }
14602                    pw.print("    "); pw.print(pkg); pw.print(": ");
14603                            pw.print(mode); pw.println();
14604                }
14605            }
14606        }
14607        if (dumpPackage == null) {
14608            pw.println("  mWakefulness="
14609                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14610            pw.println("  mSleepTokens=" + mSleepTokens);
14611            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14612                    + lockScreenShownToString());
14613            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14614            if (mRunningVoice != null) {
14615                pw.println("  mRunningVoice=" + mRunningVoice);
14616                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14617            }
14618        }
14619        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14620                || mOrigWaitForDebugger) {
14621            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14622                    || dumpPackage.equals(mOrigDebugApp)) {
14623                if (needSep) {
14624                    pw.println();
14625                    needSep = false;
14626                }
14627                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14628                        + " mDebugTransient=" + mDebugTransient
14629                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14630            }
14631        }
14632        if (mCurAppTimeTracker != null) {
14633            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14634        }
14635        if (mMemWatchProcesses.getMap().size() > 0) {
14636            pw.println("  Mem watch processes:");
14637            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14638                    = mMemWatchProcesses.getMap();
14639            for (int i=0; i<procs.size(); i++) {
14640                final String proc = procs.keyAt(i);
14641                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14642                for (int j=0; j<uids.size(); j++) {
14643                    if (needSep) {
14644                        pw.println();
14645                        needSep = false;
14646                    }
14647                    StringBuilder sb = new StringBuilder();
14648                    sb.append("    ").append(proc).append('/');
14649                    UserHandle.formatUid(sb, uids.keyAt(j));
14650                    Pair<Long, String> val = uids.valueAt(j);
14651                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14652                    if (val.second != null) {
14653                        sb.append(", report to ").append(val.second);
14654                    }
14655                    pw.println(sb.toString());
14656                }
14657            }
14658            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14659            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14660            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14661                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14662        }
14663        if (mTrackAllocationApp != null) {
14664            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14665                if (needSep) {
14666                    pw.println();
14667                    needSep = false;
14668                }
14669                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14670            }
14671        }
14672        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14673                || mProfileFd != null) {
14674            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14675                if (needSep) {
14676                    pw.println();
14677                    needSep = false;
14678                }
14679                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14680                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14681                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14682                        + mAutoStopProfiler);
14683                pw.println("  mProfileType=" + mProfileType);
14684            }
14685        }
14686        if (mNativeDebuggingApp != null) {
14687            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14688                if (needSep) {
14689                    pw.println();
14690                    needSep = false;
14691                }
14692                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14693            }
14694        }
14695        if (dumpPackage == null) {
14696            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14697                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14698                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14699            }
14700            if (mController != null) {
14701                pw.println("  mController=" + mController
14702                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14703            }
14704            if (dumpAll) {
14705                pw.println("  Total persistent processes: " + numPers);
14706                pw.println("  mProcessesReady=" + mProcessesReady
14707                        + " mSystemReady=" + mSystemReady
14708                        + " mBooted=" + mBooted
14709                        + " mFactoryTest=" + mFactoryTest);
14710                pw.println("  mBooting=" + mBooting
14711                        + " mCallFinishBooting=" + mCallFinishBooting
14712                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14713                pw.print("  mLastPowerCheckRealtime=");
14714                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14715                        pw.println("");
14716                pw.print("  mLastPowerCheckUptime=");
14717                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14718                        pw.println("");
14719                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14720                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14721                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14722                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14723                        + " (" + mLruProcesses.size() + " total)"
14724                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14725                        + " mNumServiceProcs=" + mNumServiceProcs
14726                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14727                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14728                        + " mLastMemoryLevel=" + mLastMemoryLevel
14729                        + " mLastNumProcesses=" + mLastNumProcesses);
14730                long now = SystemClock.uptimeMillis();
14731                pw.print("  mLastIdleTime=");
14732                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14733                        pw.print(" mLowRamSinceLastIdle=");
14734                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14735                        pw.println();
14736            }
14737        }
14738
14739        if (!printedAnything) {
14740            pw.println("  (nothing)");
14741        }
14742    }
14743
14744    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14745            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14746        if (mProcessesToGc.size() > 0) {
14747            boolean printed = false;
14748            long now = SystemClock.uptimeMillis();
14749            for (int i=0; i<mProcessesToGc.size(); i++) {
14750                ProcessRecord proc = mProcessesToGc.get(i);
14751                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14752                    continue;
14753                }
14754                if (!printed) {
14755                    if (needSep) pw.println();
14756                    needSep = true;
14757                    pw.println("  Processes that are waiting to GC:");
14758                    printed = true;
14759                }
14760                pw.print("    Process "); pw.println(proc);
14761                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14762                        pw.print(", last gced=");
14763                        pw.print(now-proc.lastRequestedGc);
14764                        pw.print(" ms ago, last lowMem=");
14765                        pw.print(now-proc.lastLowMemory);
14766                        pw.println(" ms ago");
14767
14768            }
14769        }
14770        return needSep;
14771    }
14772
14773    void printOomLevel(PrintWriter pw, String name, int adj) {
14774        pw.print("    ");
14775        if (adj >= 0) {
14776            pw.print(' ');
14777            if (adj < 10) pw.print(' ');
14778        } else {
14779            if (adj > -10) pw.print(' ');
14780        }
14781        pw.print(adj);
14782        pw.print(": ");
14783        pw.print(name);
14784        pw.print(" (");
14785        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14786        pw.println(")");
14787    }
14788
14789    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14790            int opti, boolean dumpAll) {
14791        boolean needSep = false;
14792
14793        if (mLruProcesses.size() > 0) {
14794            if (needSep) pw.println();
14795            needSep = true;
14796            pw.println("  OOM levels:");
14797            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14798            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14799            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14800            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14801            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14802            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14803            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14804            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14805            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14806            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14807            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14808            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14809            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14810            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14811
14812            if (needSep) pw.println();
14813            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14814                    pw.print(" total, non-act at ");
14815                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14816                    pw.print(", non-svc at ");
14817                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14818                    pw.println("):");
14819            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14820            needSep = true;
14821        }
14822
14823        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14824
14825        pw.println();
14826        pw.println("  mHomeProcess: " + mHomeProcess);
14827        pw.println("  mPreviousProcess: " + mPreviousProcess);
14828        if (mHeavyWeightProcess != null) {
14829            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14830        }
14831
14832        return true;
14833    }
14834
14835    /**
14836     * There are three ways to call this:
14837     *  - no provider specified: dump all the providers
14838     *  - a flattened component name that matched an existing provider was specified as the
14839     *    first arg: dump that one provider
14840     *  - the first arg isn't the flattened component name of an existing provider:
14841     *    dump all providers whose component contains the first arg as a substring
14842     */
14843    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14844            int opti, boolean dumpAll) {
14845        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14846    }
14847
14848    static class ItemMatcher {
14849        ArrayList<ComponentName> components;
14850        ArrayList<String> strings;
14851        ArrayList<Integer> objects;
14852        boolean all;
14853
14854        ItemMatcher() {
14855            all = true;
14856        }
14857
14858        void build(String name) {
14859            ComponentName componentName = ComponentName.unflattenFromString(name);
14860            if (componentName != null) {
14861                if (components == null) {
14862                    components = new ArrayList<ComponentName>();
14863                }
14864                components.add(componentName);
14865                all = false;
14866            } else {
14867                int objectId = 0;
14868                // Not a '/' separated full component name; maybe an object ID?
14869                try {
14870                    objectId = Integer.parseInt(name, 16);
14871                    if (objects == null) {
14872                        objects = new ArrayList<Integer>();
14873                    }
14874                    objects.add(objectId);
14875                    all = false;
14876                } catch (RuntimeException e) {
14877                    // Not an integer; just do string match.
14878                    if (strings == null) {
14879                        strings = new ArrayList<String>();
14880                    }
14881                    strings.add(name);
14882                    all = false;
14883                }
14884            }
14885        }
14886
14887        int build(String[] args, int opti) {
14888            for (; opti<args.length; opti++) {
14889                String name = args[opti];
14890                if ("--".equals(name)) {
14891                    return opti+1;
14892                }
14893                build(name);
14894            }
14895            return opti;
14896        }
14897
14898        boolean match(Object object, ComponentName comp) {
14899            if (all) {
14900                return true;
14901            }
14902            if (components != null) {
14903                for (int i=0; i<components.size(); i++) {
14904                    if (components.get(i).equals(comp)) {
14905                        return true;
14906                    }
14907                }
14908            }
14909            if (objects != null) {
14910                for (int i=0; i<objects.size(); i++) {
14911                    if (System.identityHashCode(object) == objects.get(i)) {
14912                        return true;
14913                    }
14914                }
14915            }
14916            if (strings != null) {
14917                String flat = comp.flattenToString();
14918                for (int i=0; i<strings.size(); i++) {
14919                    if (flat.contains(strings.get(i))) {
14920                        return true;
14921                    }
14922                }
14923            }
14924            return false;
14925        }
14926    }
14927
14928    /**
14929     * There are three things that cmd can be:
14930     *  - a flattened component name that matches an existing activity
14931     *  - the cmd arg isn't the flattened component name of an existing activity:
14932     *    dump all activity whose component contains the cmd as a substring
14933     *  - A hex number of the ActivityRecord object instance.
14934     */
14935    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14936            int opti, boolean dumpAll) {
14937        ArrayList<ActivityRecord> activities;
14938
14939        synchronized (this) {
14940            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14941        }
14942
14943        if (activities.size() <= 0) {
14944            return false;
14945        }
14946
14947        String[] newArgs = new String[args.length - opti];
14948        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14949
14950        TaskRecord lastTask = null;
14951        boolean needSep = false;
14952        for (int i=activities.size()-1; i>=0; i--) {
14953            ActivityRecord r = activities.get(i);
14954            if (needSep) {
14955                pw.println();
14956            }
14957            needSep = true;
14958            synchronized (this) {
14959                if (lastTask != r.task) {
14960                    lastTask = r.task;
14961                    pw.print("TASK "); pw.print(lastTask.affinity);
14962                            pw.print(" id="); pw.println(lastTask.taskId);
14963                    if (dumpAll) {
14964                        lastTask.dump(pw, "  ");
14965                    }
14966                }
14967            }
14968            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14969        }
14970        return true;
14971    }
14972
14973    /**
14974     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14975     * there is a thread associated with the activity.
14976     */
14977    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14978            final ActivityRecord r, String[] args, boolean dumpAll) {
14979        String innerPrefix = prefix + "  ";
14980        synchronized (this) {
14981            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14982                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14983                    pw.print(" pid=");
14984                    if (r.app != null) pw.println(r.app.pid);
14985                    else pw.println("(not running)");
14986            if (dumpAll) {
14987                r.dump(pw, innerPrefix);
14988            }
14989        }
14990        if (r.app != null && r.app.thread != null) {
14991            // flush anything that is already in the PrintWriter since the thread is going
14992            // to write to the file descriptor directly
14993            pw.flush();
14994            try {
14995                TransferPipe tp = new TransferPipe();
14996                try {
14997                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14998                            r.appToken, innerPrefix, args);
14999                    tp.go(fd);
15000                } finally {
15001                    tp.kill();
15002                }
15003            } catch (IOException e) {
15004                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15005            } catch (RemoteException e) {
15006                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15007            }
15008        }
15009    }
15010
15011    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15012            int opti, boolean dumpAll, String dumpPackage) {
15013        boolean needSep = false;
15014        boolean onlyHistory = false;
15015        boolean printedAnything = false;
15016
15017        if ("history".equals(dumpPackage)) {
15018            if (opti < args.length && "-s".equals(args[opti])) {
15019                dumpAll = false;
15020            }
15021            onlyHistory = true;
15022            dumpPackage = null;
15023        }
15024
15025        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15026        if (!onlyHistory && dumpAll) {
15027            if (mRegisteredReceivers.size() > 0) {
15028                boolean printed = false;
15029                Iterator it = mRegisteredReceivers.values().iterator();
15030                while (it.hasNext()) {
15031                    ReceiverList r = (ReceiverList)it.next();
15032                    if (dumpPackage != null && (r.app == null ||
15033                            !dumpPackage.equals(r.app.info.packageName))) {
15034                        continue;
15035                    }
15036                    if (!printed) {
15037                        pw.println("  Registered Receivers:");
15038                        needSep = true;
15039                        printed = true;
15040                        printedAnything = true;
15041                    }
15042                    pw.print("  * "); pw.println(r);
15043                    r.dump(pw, "    ");
15044                }
15045            }
15046
15047            if (mReceiverResolver.dump(pw, needSep ?
15048                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15049                    "    ", dumpPackage, false, false)) {
15050                needSep = true;
15051                printedAnything = true;
15052            }
15053        }
15054
15055        for (BroadcastQueue q : mBroadcastQueues) {
15056            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15057            printedAnything |= needSep;
15058        }
15059
15060        needSep = true;
15061
15062        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15063            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15064                if (needSep) {
15065                    pw.println();
15066                }
15067                needSep = true;
15068                printedAnything = true;
15069                pw.print("  Sticky broadcasts for user ");
15070                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15071                StringBuilder sb = new StringBuilder(128);
15072                for (Map.Entry<String, ArrayList<Intent>> ent
15073                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15074                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15075                    if (dumpAll) {
15076                        pw.println(":");
15077                        ArrayList<Intent> intents = ent.getValue();
15078                        final int N = intents.size();
15079                        for (int i=0; i<N; i++) {
15080                            sb.setLength(0);
15081                            sb.append("    Intent: ");
15082                            intents.get(i).toShortString(sb, false, true, false, false);
15083                            pw.println(sb.toString());
15084                            Bundle bundle = intents.get(i).getExtras();
15085                            if (bundle != null) {
15086                                pw.print("      ");
15087                                pw.println(bundle.toString());
15088                            }
15089                        }
15090                    } else {
15091                        pw.println("");
15092                    }
15093                }
15094            }
15095        }
15096
15097        if (!onlyHistory && dumpAll) {
15098            pw.println();
15099            for (BroadcastQueue queue : mBroadcastQueues) {
15100                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15101                        + queue.mBroadcastsScheduled);
15102            }
15103            pw.println("  mHandler:");
15104            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15105            needSep = true;
15106            printedAnything = true;
15107        }
15108
15109        if (!printedAnything) {
15110            pw.println("  (nothing)");
15111        }
15112    }
15113
15114    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15115            int opti, boolean dumpAll, String dumpPackage) {
15116        if (mCurBroadcastStats == null) {
15117            return;
15118        }
15119
15120        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15121        final long now = SystemClock.elapsedRealtime();
15122        if (mLastBroadcastStats != null) {
15123            pw.print("  Last stats (from ");
15124            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15125            pw.print(" to ");
15126            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15127            pw.print(", ");
15128            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15129                    - mLastBroadcastStats.mStartUptime, pw);
15130            pw.println(" uptime):");
15131            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15132                pw.println("    (nothing)");
15133            }
15134            pw.println();
15135        }
15136        pw.print("  Current stats (from ");
15137        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15138        pw.print(" to now, ");
15139        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15140                - mCurBroadcastStats.mStartUptime, pw);
15141        pw.println(" uptime):");
15142        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15143            pw.println("    (nothing)");
15144        }
15145    }
15146
15147    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15148            int opti, boolean fullCheckin, String dumpPackage) {
15149        if (mCurBroadcastStats == null) {
15150            return;
15151        }
15152
15153        if (mLastBroadcastStats != null) {
15154            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15155            if (fullCheckin) {
15156                mLastBroadcastStats = null;
15157                return;
15158            }
15159        }
15160        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15161        if (fullCheckin) {
15162            mCurBroadcastStats = null;
15163        }
15164    }
15165
15166    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15167            int opti, boolean dumpAll, String dumpPackage) {
15168        boolean needSep;
15169        boolean printedAnything = false;
15170
15171        ItemMatcher matcher = new ItemMatcher();
15172        matcher.build(args, opti);
15173
15174        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15175
15176        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15177        printedAnything |= needSep;
15178
15179        if (mLaunchingProviders.size() > 0) {
15180            boolean printed = false;
15181            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15182                ContentProviderRecord r = mLaunchingProviders.get(i);
15183                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15184                    continue;
15185                }
15186                if (!printed) {
15187                    if (needSep) pw.println();
15188                    needSep = true;
15189                    pw.println("  Launching content providers:");
15190                    printed = true;
15191                    printedAnything = true;
15192                }
15193                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15194                        pw.println(r);
15195            }
15196        }
15197
15198        if (!printedAnything) {
15199            pw.println("  (nothing)");
15200        }
15201    }
15202
15203    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15204            int opti, boolean dumpAll, String dumpPackage) {
15205        boolean needSep = false;
15206        boolean printedAnything = false;
15207
15208        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15209
15210        if (mGrantedUriPermissions.size() > 0) {
15211            boolean printed = false;
15212            int dumpUid = -2;
15213            if (dumpPackage != null) {
15214                try {
15215                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15216                            MATCH_UNINSTALLED_PACKAGES, 0);
15217                } catch (NameNotFoundException e) {
15218                    dumpUid = -1;
15219                }
15220            }
15221            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15222                int uid = mGrantedUriPermissions.keyAt(i);
15223                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15224                    continue;
15225                }
15226                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15227                if (!printed) {
15228                    if (needSep) pw.println();
15229                    needSep = true;
15230                    pw.println("  Granted Uri Permissions:");
15231                    printed = true;
15232                    printedAnything = true;
15233                }
15234                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15235                for (UriPermission perm : perms.values()) {
15236                    pw.print("    "); pw.println(perm);
15237                    if (dumpAll) {
15238                        perm.dump(pw, "      ");
15239                    }
15240                }
15241            }
15242        }
15243
15244        if (!printedAnything) {
15245            pw.println("  (nothing)");
15246        }
15247    }
15248
15249    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15250            int opti, boolean dumpAll, String dumpPackage) {
15251        boolean printed = false;
15252
15253        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15254
15255        if (mIntentSenderRecords.size() > 0) {
15256            Iterator<WeakReference<PendingIntentRecord>> it
15257                    = mIntentSenderRecords.values().iterator();
15258            while (it.hasNext()) {
15259                WeakReference<PendingIntentRecord> ref = it.next();
15260                PendingIntentRecord rec = ref != null ? ref.get(): null;
15261                if (dumpPackage != null && (rec == null
15262                        || !dumpPackage.equals(rec.key.packageName))) {
15263                    continue;
15264                }
15265                printed = true;
15266                if (rec != null) {
15267                    pw.print("  * "); pw.println(rec);
15268                    if (dumpAll) {
15269                        rec.dump(pw, "    ");
15270                    }
15271                } else {
15272                    pw.print("  * "); pw.println(ref);
15273                }
15274            }
15275        }
15276
15277        if (!printed) {
15278            pw.println("  (nothing)");
15279        }
15280    }
15281
15282    private static final int dumpProcessList(PrintWriter pw,
15283            ActivityManagerService service, List list,
15284            String prefix, String normalLabel, String persistentLabel,
15285            String dumpPackage) {
15286        int numPers = 0;
15287        final int N = list.size()-1;
15288        for (int i=N; i>=0; i--) {
15289            ProcessRecord r = (ProcessRecord)list.get(i);
15290            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15291                continue;
15292            }
15293            pw.println(String.format("%s%s #%2d: %s",
15294                    prefix, (r.persistent ? persistentLabel : normalLabel),
15295                    i, r.toString()));
15296            if (r.persistent) {
15297                numPers++;
15298            }
15299        }
15300        return numPers;
15301    }
15302
15303    private static final boolean dumpProcessOomList(PrintWriter pw,
15304            ActivityManagerService service, List<ProcessRecord> origList,
15305            String prefix, String normalLabel, String persistentLabel,
15306            boolean inclDetails, String dumpPackage) {
15307
15308        ArrayList<Pair<ProcessRecord, Integer>> list
15309                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15310        for (int i=0; i<origList.size(); i++) {
15311            ProcessRecord r = origList.get(i);
15312            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15313                continue;
15314            }
15315            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15316        }
15317
15318        if (list.size() <= 0) {
15319            return false;
15320        }
15321
15322        Comparator<Pair<ProcessRecord, Integer>> comparator
15323                = new Comparator<Pair<ProcessRecord, Integer>>() {
15324            @Override
15325            public int compare(Pair<ProcessRecord, Integer> object1,
15326                    Pair<ProcessRecord, Integer> object2) {
15327                if (object1.first.setAdj != object2.first.setAdj) {
15328                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15329                }
15330                if (object1.first.setProcState != object2.first.setProcState) {
15331                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15332                }
15333                if (object1.second.intValue() != object2.second.intValue()) {
15334                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15335                }
15336                return 0;
15337            }
15338        };
15339
15340        Collections.sort(list, comparator);
15341
15342        final long curRealtime = SystemClock.elapsedRealtime();
15343        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15344        final long curUptime = SystemClock.uptimeMillis();
15345        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15346
15347        for (int i=list.size()-1; i>=0; i--) {
15348            ProcessRecord r = list.get(i).first;
15349            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15350            char schedGroup;
15351            switch (r.setSchedGroup) {
15352                case ProcessList.SCHED_GROUP_BACKGROUND:
15353                    schedGroup = 'B';
15354                    break;
15355                case ProcessList.SCHED_GROUP_DEFAULT:
15356                    schedGroup = 'F';
15357                    break;
15358                case ProcessList.SCHED_GROUP_TOP_APP:
15359                    schedGroup = 'T';
15360                    break;
15361                default:
15362                    schedGroup = '?';
15363                    break;
15364            }
15365            char foreground;
15366            if (r.foregroundActivities) {
15367                foreground = 'A';
15368            } else if (r.foregroundServices) {
15369                foreground = 'S';
15370            } else {
15371                foreground = ' ';
15372            }
15373            String procState = ProcessList.makeProcStateString(r.curProcState);
15374            pw.print(prefix);
15375            pw.print(r.persistent ? persistentLabel : normalLabel);
15376            pw.print(" #");
15377            int num = (origList.size()-1)-list.get(i).second;
15378            if (num < 10) pw.print(' ');
15379            pw.print(num);
15380            pw.print(": ");
15381            pw.print(oomAdj);
15382            pw.print(' ');
15383            pw.print(schedGroup);
15384            pw.print('/');
15385            pw.print(foreground);
15386            pw.print('/');
15387            pw.print(procState);
15388            pw.print(" trm:");
15389            if (r.trimMemoryLevel < 10) pw.print(' ');
15390            pw.print(r.trimMemoryLevel);
15391            pw.print(' ');
15392            pw.print(r.toShortString());
15393            pw.print(" (");
15394            pw.print(r.adjType);
15395            pw.println(')');
15396            if (r.adjSource != null || r.adjTarget != null) {
15397                pw.print(prefix);
15398                pw.print("    ");
15399                if (r.adjTarget instanceof ComponentName) {
15400                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15401                } else if (r.adjTarget != null) {
15402                    pw.print(r.adjTarget.toString());
15403                } else {
15404                    pw.print("{null}");
15405                }
15406                pw.print("<=");
15407                if (r.adjSource instanceof ProcessRecord) {
15408                    pw.print("Proc{");
15409                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15410                    pw.println("}");
15411                } else if (r.adjSource != null) {
15412                    pw.println(r.adjSource.toString());
15413                } else {
15414                    pw.println("{null}");
15415                }
15416            }
15417            if (inclDetails) {
15418                pw.print(prefix);
15419                pw.print("    ");
15420                pw.print("oom: max="); pw.print(r.maxAdj);
15421                pw.print(" curRaw="); pw.print(r.curRawAdj);
15422                pw.print(" setRaw="); pw.print(r.setRawAdj);
15423                pw.print(" cur="); pw.print(r.curAdj);
15424                pw.print(" set="); pw.println(r.setAdj);
15425                pw.print(prefix);
15426                pw.print("    ");
15427                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15428                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15429                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15430                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15431                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15432                pw.println();
15433                pw.print(prefix);
15434                pw.print("    ");
15435                pw.print("cached="); pw.print(r.cached);
15436                pw.print(" empty="); pw.print(r.empty);
15437                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15438
15439                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15440                    if (r.lastWakeTime != 0) {
15441                        long wtime;
15442                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15443                        synchronized (stats) {
15444                            wtime = stats.getProcessWakeTime(r.info.uid,
15445                                    r.pid, curRealtime);
15446                        }
15447                        long timeUsed = wtime - r.lastWakeTime;
15448                        pw.print(prefix);
15449                        pw.print("    ");
15450                        pw.print("keep awake over ");
15451                        TimeUtils.formatDuration(realtimeSince, pw);
15452                        pw.print(" used ");
15453                        TimeUtils.formatDuration(timeUsed, pw);
15454                        pw.print(" (");
15455                        pw.print((timeUsed*100)/realtimeSince);
15456                        pw.println("%)");
15457                    }
15458                    if (r.lastCpuTime != 0) {
15459                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15460                        pw.print(prefix);
15461                        pw.print("    ");
15462                        pw.print("run cpu over ");
15463                        TimeUtils.formatDuration(uptimeSince, pw);
15464                        pw.print(" used ");
15465                        TimeUtils.formatDuration(timeUsed, pw);
15466                        pw.print(" (");
15467                        pw.print((timeUsed*100)/uptimeSince);
15468                        pw.println("%)");
15469                    }
15470                }
15471            }
15472        }
15473        return true;
15474    }
15475
15476    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15477            String[] args) {
15478        ArrayList<ProcessRecord> procs;
15479        synchronized (this) {
15480            if (args != null && args.length > start
15481                    && args[start].charAt(0) != '-') {
15482                procs = new ArrayList<ProcessRecord>();
15483                int pid = -1;
15484                try {
15485                    pid = Integer.parseInt(args[start]);
15486                } catch (NumberFormatException e) {
15487                }
15488                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15489                    ProcessRecord proc = mLruProcesses.get(i);
15490                    if (proc.pid == pid) {
15491                        procs.add(proc);
15492                    } else if (allPkgs && proc.pkgList != null
15493                            && proc.pkgList.containsKey(args[start])) {
15494                        procs.add(proc);
15495                    } else if (proc.processName.equals(args[start])) {
15496                        procs.add(proc);
15497                    }
15498                }
15499                if (procs.size() <= 0) {
15500                    return null;
15501                }
15502            } else {
15503                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15504            }
15505        }
15506        return procs;
15507    }
15508
15509    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15510            PrintWriter pw, String[] args) {
15511        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15512        if (procs == null) {
15513            pw.println("No process found for: " + args[0]);
15514            return;
15515        }
15516
15517        long uptime = SystemClock.uptimeMillis();
15518        long realtime = SystemClock.elapsedRealtime();
15519        pw.println("Applications Graphics Acceleration Info:");
15520        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15521
15522        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15523            ProcessRecord r = procs.get(i);
15524            if (r.thread != null) {
15525                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15526                pw.flush();
15527                try {
15528                    TransferPipe tp = new TransferPipe();
15529                    try {
15530                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15531                        tp.go(fd);
15532                    } finally {
15533                        tp.kill();
15534                    }
15535                } catch (IOException e) {
15536                    pw.println("Failure while dumping the app: " + r);
15537                    pw.flush();
15538                } catch (RemoteException e) {
15539                    pw.println("Got a RemoteException while dumping the app " + r);
15540                    pw.flush();
15541                }
15542            }
15543        }
15544    }
15545
15546    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15547        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15548        if (procs == null) {
15549            pw.println("No process found for: " + args[0]);
15550            return;
15551        }
15552
15553        pw.println("Applications Database Info:");
15554
15555        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15556            ProcessRecord r = procs.get(i);
15557            if (r.thread != null) {
15558                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15559                pw.flush();
15560                try {
15561                    TransferPipe tp = new TransferPipe();
15562                    try {
15563                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15564                        tp.go(fd);
15565                    } finally {
15566                        tp.kill();
15567                    }
15568                } catch (IOException e) {
15569                    pw.println("Failure while dumping the app: " + r);
15570                    pw.flush();
15571                } catch (RemoteException e) {
15572                    pw.println("Got a RemoteException while dumping the app " + r);
15573                    pw.flush();
15574                }
15575            }
15576        }
15577    }
15578
15579    final static class MemItem {
15580        final boolean isProc;
15581        final String label;
15582        final String shortLabel;
15583        final long pss;
15584        final long swapPss;
15585        final int id;
15586        final boolean hasActivities;
15587        ArrayList<MemItem> subitems;
15588
15589        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15590                boolean _hasActivities) {
15591            isProc = true;
15592            label = _label;
15593            shortLabel = _shortLabel;
15594            pss = _pss;
15595            swapPss = _swapPss;
15596            id = _id;
15597            hasActivities = _hasActivities;
15598        }
15599
15600        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15601            isProc = false;
15602            label = _label;
15603            shortLabel = _shortLabel;
15604            pss = _pss;
15605            swapPss = _swapPss;
15606            id = _id;
15607            hasActivities = false;
15608        }
15609    }
15610
15611    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15612            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15613        if (sort && !isCompact) {
15614            Collections.sort(items, new Comparator<MemItem>() {
15615                @Override
15616                public int compare(MemItem lhs, MemItem rhs) {
15617                    if (lhs.pss < rhs.pss) {
15618                        return 1;
15619                    } else if (lhs.pss > rhs.pss) {
15620                        return -1;
15621                    }
15622                    return 0;
15623                }
15624            });
15625        }
15626
15627        for (int i=0; i<items.size(); i++) {
15628            MemItem mi = items.get(i);
15629            if (!isCompact) {
15630                if (dumpSwapPss) {
15631                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15632                            mi.label, stringifyKBSize(mi.swapPss));
15633                } else {
15634                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15635                }
15636            } else if (mi.isProc) {
15637                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15638                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15639                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15640                pw.println(mi.hasActivities ? ",a" : ",e");
15641            } else {
15642                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15643                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15644            }
15645            if (mi.subitems != null) {
15646                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15647                        true, isCompact, dumpSwapPss);
15648            }
15649        }
15650    }
15651
15652    // These are in KB.
15653    static final long[] DUMP_MEM_BUCKETS = new long[] {
15654        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15655        120*1024, 160*1024, 200*1024,
15656        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15657        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15658    };
15659
15660    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15661            boolean stackLike) {
15662        int start = label.lastIndexOf('.');
15663        if (start >= 0) start++;
15664        else start = 0;
15665        int end = label.length();
15666        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15667            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15668                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15669                out.append(bucket);
15670                out.append(stackLike ? "MB." : "MB ");
15671                out.append(label, start, end);
15672                return;
15673            }
15674        }
15675        out.append(memKB/1024);
15676        out.append(stackLike ? "MB." : "MB ");
15677        out.append(label, start, end);
15678    }
15679
15680    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15681            ProcessList.NATIVE_ADJ,
15682            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15683            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15684            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15685            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15686            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15687            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15688    };
15689    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15690            "Native",
15691            "System", "Persistent", "Persistent Service", "Foreground",
15692            "Visible", "Perceptible",
15693            "Heavy Weight", "Backup",
15694            "A Services", "Home",
15695            "Previous", "B Services", "Cached"
15696    };
15697    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15698            "native",
15699            "sys", "pers", "persvc", "fore",
15700            "vis", "percept",
15701            "heavy", "backup",
15702            "servicea", "home",
15703            "prev", "serviceb", "cached"
15704    };
15705
15706    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15707            long realtime, boolean isCheckinRequest, boolean isCompact) {
15708        if (isCompact) {
15709            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15710        }
15711        if (isCheckinRequest || isCompact) {
15712            // short checkin version
15713            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15714        } else {
15715            pw.println("Applications Memory Usage (in Kilobytes):");
15716            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15717        }
15718    }
15719
15720    private static final int KSM_SHARED = 0;
15721    private static final int KSM_SHARING = 1;
15722    private static final int KSM_UNSHARED = 2;
15723    private static final int KSM_VOLATILE = 3;
15724
15725    private final long[] getKsmInfo() {
15726        long[] longOut = new long[4];
15727        final int[] SINGLE_LONG_FORMAT = new int[] {
15728            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15729        };
15730        long[] longTmp = new long[1];
15731        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15732                SINGLE_LONG_FORMAT, null, longTmp, null);
15733        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15734        longTmp[0] = 0;
15735        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15736                SINGLE_LONG_FORMAT, null, longTmp, null);
15737        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15738        longTmp[0] = 0;
15739        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15740                SINGLE_LONG_FORMAT, null, longTmp, null);
15741        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15742        longTmp[0] = 0;
15743        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15744                SINGLE_LONG_FORMAT, null, longTmp, null);
15745        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15746        return longOut;
15747    }
15748
15749    private static String stringifySize(long size, int order) {
15750        Locale locale = Locale.US;
15751        switch (order) {
15752            case 1:
15753                return String.format(locale, "%,13d", size);
15754            case 1024:
15755                return String.format(locale, "%,9dK", size / 1024);
15756            case 1024 * 1024:
15757                return String.format(locale, "%,5dM", size / 1024 / 1024);
15758            case 1024 * 1024 * 1024:
15759                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15760            default:
15761                throw new IllegalArgumentException("Invalid size order");
15762        }
15763    }
15764
15765    private static String stringifyKBSize(long size) {
15766        return stringifySize(size * 1024, 1024);
15767    }
15768
15769    // Update this version number in case you change the 'compact' format
15770    private static final int MEMINFO_COMPACT_VERSION = 1;
15771
15772    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15773            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15774        boolean dumpDetails = false;
15775        boolean dumpFullDetails = false;
15776        boolean dumpDalvik = false;
15777        boolean dumpSummaryOnly = false;
15778        boolean dumpUnreachable = false;
15779        boolean oomOnly = false;
15780        boolean isCompact = false;
15781        boolean localOnly = false;
15782        boolean packages = false;
15783        boolean isCheckinRequest = false;
15784        boolean dumpSwapPss = false;
15785
15786        int opti = 0;
15787        while (opti < args.length) {
15788            String opt = args[opti];
15789            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15790                break;
15791            }
15792            opti++;
15793            if ("-a".equals(opt)) {
15794                dumpDetails = true;
15795                dumpFullDetails = true;
15796                dumpDalvik = true;
15797                dumpSwapPss = true;
15798            } else if ("-d".equals(opt)) {
15799                dumpDalvik = true;
15800            } else if ("-c".equals(opt)) {
15801                isCompact = true;
15802            } else if ("-s".equals(opt)) {
15803                dumpDetails = true;
15804                dumpSummaryOnly = true;
15805            } else if ("-S".equals(opt)) {
15806                dumpSwapPss = true;
15807            } else if ("--unreachable".equals(opt)) {
15808                dumpUnreachable = true;
15809            } else if ("--oom".equals(opt)) {
15810                oomOnly = true;
15811            } else if ("--local".equals(opt)) {
15812                localOnly = true;
15813            } else if ("--package".equals(opt)) {
15814                packages = true;
15815            } else if ("--checkin".equals(opt)) {
15816                isCheckinRequest = true;
15817
15818            } else if ("-h".equals(opt)) {
15819                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15820                pw.println("  -a: include all available information for each process.");
15821                pw.println("  -d: include dalvik details.");
15822                pw.println("  -c: dump in a compact machine-parseable representation.");
15823                pw.println("  -s: dump only summary of application memory usage.");
15824                pw.println("  -S: dump also SwapPss.");
15825                pw.println("  --oom: only show processes organized by oom adj.");
15826                pw.println("  --local: only collect details locally, don't call process.");
15827                pw.println("  --package: interpret process arg as package, dumping all");
15828                pw.println("             processes that have loaded that package.");
15829                pw.println("  --checkin: dump data for a checkin");
15830                pw.println("If [process] is specified it can be the name or ");
15831                pw.println("pid of a specific process to dump.");
15832                return;
15833            } else {
15834                pw.println("Unknown argument: " + opt + "; use -h for help");
15835            }
15836        }
15837
15838        long uptime = SystemClock.uptimeMillis();
15839        long realtime = SystemClock.elapsedRealtime();
15840        final long[] tmpLong = new long[1];
15841
15842        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15843        if (procs == null) {
15844            // No Java processes.  Maybe they want to print a native process.
15845            if (args != null && args.length > opti
15846                    && args[opti].charAt(0) != '-') {
15847                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15848                        = new ArrayList<ProcessCpuTracker.Stats>();
15849                updateCpuStatsNow();
15850                int findPid = -1;
15851                try {
15852                    findPid = Integer.parseInt(args[opti]);
15853                } catch (NumberFormatException e) {
15854                }
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.pid == findPid || (st.baseName != null
15860                                && st.baseName.equals(args[opti]))) {
15861                            nativeProcs.add(st);
15862                        }
15863                    }
15864                }
15865                if (nativeProcs.size() > 0) {
15866                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15867                            isCompact);
15868                    Debug.MemoryInfo mi = null;
15869                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15870                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15871                        final int pid = r.pid;
15872                        if (!isCheckinRequest && dumpDetails) {
15873                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15874                        }
15875                        if (mi == null) {
15876                            mi = new Debug.MemoryInfo();
15877                        }
15878                        if (dumpDetails || (!brief && !oomOnly)) {
15879                            Debug.getMemoryInfo(pid, mi);
15880                        } else {
15881                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15882                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15883                        }
15884                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15885                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15886                        if (isCheckinRequest) {
15887                            pw.println();
15888                        }
15889                    }
15890                    return;
15891                }
15892            }
15893            pw.println("No process found for: " + args[opti]);
15894            return;
15895        }
15896
15897        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15898            dumpDetails = true;
15899        }
15900
15901        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15902
15903        String[] innerArgs = new String[args.length-opti];
15904        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15905
15906        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15907        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15908        long nativePss = 0;
15909        long nativeSwapPss = 0;
15910        long dalvikPss = 0;
15911        long dalvikSwapPss = 0;
15912        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15913                EmptyArray.LONG;
15914        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15915                EmptyArray.LONG;
15916        long otherPss = 0;
15917        long otherSwapPss = 0;
15918        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15919        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15920
15921        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15922        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15923        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15924                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15925
15926        long totalPss = 0;
15927        long totalSwapPss = 0;
15928        long cachedPss = 0;
15929        long cachedSwapPss = 0;
15930        boolean hasSwapPss = false;
15931
15932        Debug.MemoryInfo mi = null;
15933        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15934            final ProcessRecord r = procs.get(i);
15935            final IApplicationThread thread;
15936            final int pid;
15937            final int oomAdj;
15938            final boolean hasActivities;
15939            synchronized (this) {
15940                thread = r.thread;
15941                pid = r.pid;
15942                oomAdj = r.getSetAdjWithServices();
15943                hasActivities = r.activities.size() > 0;
15944            }
15945            if (thread != null) {
15946                if (!isCheckinRequest && dumpDetails) {
15947                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15948                }
15949                if (mi == null) {
15950                    mi = new Debug.MemoryInfo();
15951                }
15952                if (dumpDetails || (!brief && !oomOnly)) {
15953                    Debug.getMemoryInfo(pid, mi);
15954                    hasSwapPss = mi.hasSwappedOutPss;
15955                } else {
15956                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15957                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15958                }
15959                if (dumpDetails) {
15960                    if (localOnly) {
15961                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15962                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15963                        if (isCheckinRequest) {
15964                            pw.println();
15965                        }
15966                    } else {
15967                        try {
15968                            pw.flush();
15969                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15970                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15971                        } catch (RemoteException e) {
15972                            if (!isCheckinRequest) {
15973                                pw.println("Got RemoteException!");
15974                                pw.flush();
15975                            }
15976                        }
15977                    }
15978                }
15979
15980                final long myTotalPss = mi.getTotalPss();
15981                final long myTotalUss = mi.getTotalUss();
15982                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15983
15984                synchronized (this) {
15985                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15986                        // Record this for posterity if the process has been stable.
15987                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15988                    }
15989                }
15990
15991                if (!isCheckinRequest && mi != null) {
15992                    totalPss += myTotalPss;
15993                    totalSwapPss += myTotalSwapPss;
15994                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15995                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15996                            myTotalSwapPss, pid, hasActivities);
15997                    procMems.add(pssItem);
15998                    procMemsMap.put(pid, pssItem);
15999
16000                    nativePss += mi.nativePss;
16001                    nativeSwapPss += mi.nativeSwappedOutPss;
16002                    dalvikPss += mi.dalvikPss;
16003                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16004                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16005                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16006                        dalvikSubitemSwapPss[j] +=
16007                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16008                    }
16009                    otherPss += mi.otherPss;
16010                    otherSwapPss += mi.otherSwappedOutPss;
16011                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16012                        long mem = mi.getOtherPss(j);
16013                        miscPss[j] += mem;
16014                        otherPss -= mem;
16015                        mem = mi.getOtherSwappedOutPss(j);
16016                        miscSwapPss[j] += mem;
16017                        otherSwapPss -= mem;
16018                    }
16019
16020                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16021                        cachedPss += myTotalPss;
16022                        cachedSwapPss += myTotalSwapPss;
16023                    }
16024
16025                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16026                        if (oomIndex == (oomPss.length - 1)
16027                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16028                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16029                            oomPss[oomIndex] += myTotalPss;
16030                            oomSwapPss[oomIndex] += myTotalSwapPss;
16031                            if (oomProcs[oomIndex] == null) {
16032                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16033                            }
16034                            oomProcs[oomIndex].add(pssItem);
16035                            break;
16036                        }
16037                    }
16038                }
16039            }
16040        }
16041
16042        long nativeProcTotalPss = 0;
16043
16044        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16045            // If we are showing aggregations, also look for native processes to
16046            // include so that our aggregations are more accurate.
16047            updateCpuStatsNow();
16048            mi = null;
16049            synchronized (mProcessCpuTracker) {
16050                final int N = mProcessCpuTracker.countStats();
16051                for (int i=0; i<N; i++) {
16052                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16053                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16054                        if (mi == null) {
16055                            mi = new Debug.MemoryInfo();
16056                        }
16057                        if (!brief && !oomOnly) {
16058                            Debug.getMemoryInfo(st.pid, mi);
16059                        } else {
16060                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16061                            mi.nativePrivateDirty = (int)tmpLong[0];
16062                        }
16063
16064                        final long myTotalPss = mi.getTotalPss();
16065                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16066                        totalPss += myTotalPss;
16067                        nativeProcTotalPss += myTotalPss;
16068
16069                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16070                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16071                        procMems.add(pssItem);
16072
16073                        nativePss += mi.nativePss;
16074                        nativeSwapPss += mi.nativeSwappedOutPss;
16075                        dalvikPss += mi.dalvikPss;
16076                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16077                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16078                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16079                            dalvikSubitemSwapPss[j] +=
16080                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16081                        }
16082                        otherPss += mi.otherPss;
16083                        otherSwapPss += mi.otherSwappedOutPss;
16084                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16085                            long mem = mi.getOtherPss(j);
16086                            miscPss[j] += mem;
16087                            otherPss -= mem;
16088                            mem = mi.getOtherSwappedOutPss(j);
16089                            miscSwapPss[j] += mem;
16090                            otherSwapPss -= mem;
16091                        }
16092                        oomPss[0] += myTotalPss;
16093                        oomSwapPss[0] += myTotalSwapPss;
16094                        if (oomProcs[0] == null) {
16095                            oomProcs[0] = new ArrayList<MemItem>();
16096                        }
16097                        oomProcs[0].add(pssItem);
16098                    }
16099                }
16100            }
16101
16102            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16103
16104            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16105            final MemItem dalvikItem =
16106                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16107            if (dalvikSubitemPss.length > 0) {
16108                dalvikItem.subitems = new ArrayList<MemItem>();
16109                for (int j=0; j<dalvikSubitemPss.length; j++) {
16110                    final String name = Debug.MemoryInfo.getOtherLabel(
16111                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16112                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16113                                    dalvikSubitemSwapPss[j], j));
16114                }
16115            }
16116            catMems.add(dalvikItem);
16117            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16118            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16119                String label = Debug.MemoryInfo.getOtherLabel(j);
16120                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16121            }
16122
16123            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16124            for (int j=0; j<oomPss.length; j++) {
16125                if (oomPss[j] != 0) {
16126                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16127                            : DUMP_MEM_OOM_LABEL[j];
16128                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16129                            DUMP_MEM_OOM_ADJ[j]);
16130                    item.subitems = oomProcs[j];
16131                    oomMems.add(item);
16132                }
16133            }
16134
16135            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16136            if (!brief && !oomOnly && !isCompact) {
16137                pw.println();
16138                pw.println("Total PSS by process:");
16139                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16140                pw.println();
16141            }
16142            if (!isCompact) {
16143                pw.println("Total PSS by OOM adjustment:");
16144            }
16145            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16146            if (!brief && !oomOnly) {
16147                PrintWriter out = categoryPw != null ? categoryPw : pw;
16148                if (!isCompact) {
16149                    out.println();
16150                    out.println("Total PSS by category:");
16151                }
16152                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16153            }
16154            if (!isCompact) {
16155                pw.println();
16156            }
16157            MemInfoReader memInfo = new MemInfoReader();
16158            memInfo.readMemInfo();
16159            if (nativeProcTotalPss > 0) {
16160                synchronized (this) {
16161                    final long cachedKb = memInfo.getCachedSizeKb();
16162                    final long freeKb = memInfo.getFreeSizeKb();
16163                    final long zramKb = memInfo.getZramTotalSizeKb();
16164                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16165                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16166                            kernelKb*1024, nativeProcTotalPss*1024);
16167                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16168                            nativeProcTotalPss);
16169                }
16170            }
16171            if (!brief) {
16172                if (!isCompact) {
16173                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16174                    pw.print(" (status ");
16175                    switch (mLastMemoryLevel) {
16176                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16177                            pw.println("normal)");
16178                            break;
16179                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16180                            pw.println("moderate)");
16181                            break;
16182                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16183                            pw.println("low)");
16184                            break;
16185                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16186                            pw.println("critical)");
16187                            break;
16188                        default:
16189                            pw.print(mLastMemoryLevel);
16190                            pw.println(")");
16191                            break;
16192                    }
16193                    pw.print(" Free RAM: ");
16194                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16195                            + memInfo.getFreeSizeKb()));
16196                    pw.print(" (");
16197                    pw.print(stringifyKBSize(cachedPss));
16198                    pw.print(" cached pss + ");
16199                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16200                    pw.print(" cached kernel + ");
16201                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16202                    pw.println(" free)");
16203                } else {
16204                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16205                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16206                            + memInfo.getFreeSizeKb()); pw.print(",");
16207                    pw.println(totalPss - cachedPss);
16208                }
16209            }
16210            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16211                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16212                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16213            if (!isCompact) {
16214                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16215                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16216                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16217                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16218                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16219            } else {
16220                pw.print("lostram,"); pw.println(lostRAM);
16221            }
16222            if (!brief) {
16223                if (memInfo.getZramTotalSizeKb() != 0) {
16224                    if (!isCompact) {
16225                        pw.print("     ZRAM: ");
16226                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16227                                pw.print(" physical used for ");
16228                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16229                                        - memInfo.getSwapFreeSizeKb()));
16230                                pw.print(" in swap (");
16231                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16232                                pw.println(" total swap)");
16233                    } else {
16234                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16235                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16236                                pw.println(memInfo.getSwapFreeSizeKb());
16237                    }
16238                }
16239                final long[] ksm = getKsmInfo();
16240                if (!isCompact) {
16241                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16242                            || ksm[KSM_VOLATILE] != 0) {
16243                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16244                                pw.print(" saved from shared ");
16245                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16246                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16247                                pw.print(" unshared; ");
16248                                pw.print(stringifyKBSize(
16249                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16250                    }
16251                    pw.print("   Tuning: ");
16252                    pw.print(ActivityManager.staticGetMemoryClass());
16253                    pw.print(" (large ");
16254                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16255                    pw.print("), oom ");
16256                    pw.print(stringifySize(
16257                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16258                    pw.print(", restore limit ");
16259                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16260                    if (ActivityManager.isLowRamDeviceStatic()) {
16261                        pw.print(" (low-ram)");
16262                    }
16263                    if (ActivityManager.isHighEndGfx()) {
16264                        pw.print(" (high-end-gfx)");
16265                    }
16266                    pw.println();
16267                } else {
16268                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16269                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16270                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16271                    pw.print("tuning,");
16272                    pw.print(ActivityManager.staticGetMemoryClass());
16273                    pw.print(',');
16274                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16275                    pw.print(',');
16276                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16277                    if (ActivityManager.isLowRamDeviceStatic()) {
16278                        pw.print(",low-ram");
16279                    }
16280                    if (ActivityManager.isHighEndGfx()) {
16281                        pw.print(",high-end-gfx");
16282                    }
16283                    pw.println();
16284                }
16285            }
16286        }
16287    }
16288
16289    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16290            long memtrack, String name) {
16291        sb.append("  ");
16292        sb.append(ProcessList.makeOomAdjString(oomAdj));
16293        sb.append(' ');
16294        sb.append(ProcessList.makeProcStateString(procState));
16295        sb.append(' ');
16296        ProcessList.appendRamKb(sb, pss);
16297        sb.append(": ");
16298        sb.append(name);
16299        if (memtrack > 0) {
16300            sb.append(" (");
16301            sb.append(stringifyKBSize(memtrack));
16302            sb.append(" memtrack)");
16303        }
16304    }
16305
16306    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16307        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16308        sb.append(" (pid ");
16309        sb.append(mi.pid);
16310        sb.append(") ");
16311        sb.append(mi.adjType);
16312        sb.append('\n');
16313        if (mi.adjReason != null) {
16314            sb.append("                      ");
16315            sb.append(mi.adjReason);
16316            sb.append('\n');
16317        }
16318    }
16319
16320    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16321        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16322        for (int i=0, N=memInfos.size(); i<N; i++) {
16323            ProcessMemInfo mi = memInfos.get(i);
16324            infoMap.put(mi.pid, mi);
16325        }
16326        updateCpuStatsNow();
16327        long[] memtrackTmp = new long[1];
16328        synchronized (mProcessCpuTracker) {
16329            final int N = mProcessCpuTracker.countStats();
16330            for (int i=0; i<N; i++) {
16331                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16332                if (st.vsize > 0) {
16333                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16334                    if (pss > 0) {
16335                        if (infoMap.indexOfKey(st.pid) < 0) {
16336                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16337                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16338                            mi.pss = pss;
16339                            mi.memtrack = memtrackTmp[0];
16340                            memInfos.add(mi);
16341                        }
16342                    }
16343                }
16344            }
16345        }
16346
16347        long totalPss = 0;
16348        long totalMemtrack = 0;
16349        for (int i=0, N=memInfos.size(); i<N; i++) {
16350            ProcessMemInfo mi = memInfos.get(i);
16351            if (mi.pss == 0) {
16352                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16353                mi.memtrack = memtrackTmp[0];
16354            }
16355            totalPss += mi.pss;
16356            totalMemtrack += mi.memtrack;
16357        }
16358        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16359            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16360                if (lhs.oomAdj != rhs.oomAdj) {
16361                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16362                }
16363                if (lhs.pss != rhs.pss) {
16364                    return lhs.pss < rhs.pss ? 1 : -1;
16365                }
16366                return 0;
16367            }
16368        });
16369
16370        StringBuilder tag = new StringBuilder(128);
16371        StringBuilder stack = new StringBuilder(128);
16372        tag.append("Low on memory -- ");
16373        appendMemBucket(tag, totalPss, "total", false);
16374        appendMemBucket(stack, totalPss, "total", true);
16375
16376        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16377        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16378        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16379
16380        boolean firstLine = true;
16381        int lastOomAdj = Integer.MIN_VALUE;
16382        long extraNativeRam = 0;
16383        long extraNativeMemtrack = 0;
16384        long cachedPss = 0;
16385        for (int i=0, N=memInfos.size(); i<N; i++) {
16386            ProcessMemInfo mi = memInfos.get(i);
16387
16388            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16389                cachedPss += mi.pss;
16390            }
16391
16392            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16393                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16394                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16395                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16396                if (lastOomAdj != mi.oomAdj) {
16397                    lastOomAdj = mi.oomAdj;
16398                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16399                        tag.append(" / ");
16400                    }
16401                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16402                        if (firstLine) {
16403                            stack.append(":");
16404                            firstLine = false;
16405                        }
16406                        stack.append("\n\t at ");
16407                    } else {
16408                        stack.append("$");
16409                    }
16410                } else {
16411                    tag.append(" ");
16412                    stack.append("$");
16413                }
16414                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16415                    appendMemBucket(tag, mi.pss, mi.name, false);
16416                }
16417                appendMemBucket(stack, mi.pss, mi.name, true);
16418                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16419                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16420                    stack.append("(");
16421                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16422                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16423                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16424                            stack.append(":");
16425                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16426                        }
16427                    }
16428                    stack.append(")");
16429                }
16430            }
16431
16432            appendMemInfo(fullNativeBuilder, mi);
16433            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16434                // The short form only has native processes that are >= 512K.
16435                if (mi.pss >= 512) {
16436                    appendMemInfo(shortNativeBuilder, mi);
16437                } else {
16438                    extraNativeRam += mi.pss;
16439                    extraNativeMemtrack += mi.memtrack;
16440                }
16441            } else {
16442                // Short form has all other details, but if we have collected RAM
16443                // from smaller native processes let's dump a summary of that.
16444                if (extraNativeRam > 0) {
16445                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16446                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16447                    shortNativeBuilder.append('\n');
16448                    extraNativeRam = 0;
16449                }
16450                appendMemInfo(fullJavaBuilder, mi);
16451            }
16452        }
16453
16454        fullJavaBuilder.append("           ");
16455        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16456        fullJavaBuilder.append(": TOTAL");
16457        if (totalMemtrack > 0) {
16458            fullJavaBuilder.append(" (");
16459            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16460            fullJavaBuilder.append(" memtrack)");
16461        } else {
16462        }
16463        fullJavaBuilder.append("\n");
16464
16465        MemInfoReader memInfo = new MemInfoReader();
16466        memInfo.readMemInfo();
16467        final long[] infos = memInfo.getRawInfo();
16468
16469        StringBuilder memInfoBuilder = new StringBuilder(1024);
16470        Debug.getMemInfo(infos);
16471        memInfoBuilder.append("  MemInfo: ");
16472        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16473        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16474        memInfoBuilder.append(stringifyKBSize(
16475                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16476        memInfoBuilder.append(stringifyKBSize(
16477                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16478        memInfoBuilder.append(stringifyKBSize(
16479                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16480        memInfoBuilder.append("           ");
16481        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16482        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16483        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16484        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16485        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16486            memInfoBuilder.append("  ZRAM: ");
16487            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16488            memInfoBuilder.append(" RAM, ");
16489            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16490            memInfoBuilder.append(" swap total, ");
16491            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16492            memInfoBuilder.append(" swap free\n");
16493        }
16494        final long[] ksm = getKsmInfo();
16495        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16496                || ksm[KSM_VOLATILE] != 0) {
16497            memInfoBuilder.append("  KSM: ");
16498            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16499            memInfoBuilder.append(" saved from shared ");
16500            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16501            memInfoBuilder.append("\n       ");
16502            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16503            memInfoBuilder.append(" unshared; ");
16504            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16505            memInfoBuilder.append(" volatile\n");
16506        }
16507        memInfoBuilder.append("  Free RAM: ");
16508        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16509                + memInfo.getFreeSizeKb()));
16510        memInfoBuilder.append("\n");
16511        memInfoBuilder.append("  Used RAM: ");
16512        memInfoBuilder.append(stringifyKBSize(
16513                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16514        memInfoBuilder.append("\n");
16515        memInfoBuilder.append("  Lost RAM: ");
16516        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16517                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16518                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16519        memInfoBuilder.append("\n");
16520        Slog.i(TAG, "Low on memory:");
16521        Slog.i(TAG, shortNativeBuilder.toString());
16522        Slog.i(TAG, fullJavaBuilder.toString());
16523        Slog.i(TAG, memInfoBuilder.toString());
16524
16525        StringBuilder dropBuilder = new StringBuilder(1024);
16526        /*
16527        StringWriter oomSw = new StringWriter();
16528        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16529        StringWriter catSw = new StringWriter();
16530        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16531        String[] emptyArgs = new String[] { };
16532        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16533        oomPw.flush();
16534        String oomString = oomSw.toString();
16535        */
16536        dropBuilder.append("Low on memory:");
16537        dropBuilder.append(stack);
16538        dropBuilder.append('\n');
16539        dropBuilder.append(fullNativeBuilder);
16540        dropBuilder.append(fullJavaBuilder);
16541        dropBuilder.append('\n');
16542        dropBuilder.append(memInfoBuilder);
16543        dropBuilder.append('\n');
16544        /*
16545        dropBuilder.append(oomString);
16546        dropBuilder.append('\n');
16547        */
16548        StringWriter catSw = new StringWriter();
16549        synchronized (ActivityManagerService.this) {
16550            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16551            String[] emptyArgs = new String[] { };
16552            catPw.println();
16553            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16554            catPw.println();
16555            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16556                    false, null).dumpLocked();
16557            catPw.println();
16558            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16559            catPw.flush();
16560        }
16561        dropBuilder.append(catSw.toString());
16562        addErrorToDropBox("lowmem", null, "system_server", null,
16563                null, tag.toString(), dropBuilder.toString(), null, null);
16564        //Slog.i(TAG, "Sent to dropbox:");
16565        //Slog.i(TAG, dropBuilder.toString());
16566        synchronized (ActivityManagerService.this) {
16567            long now = SystemClock.uptimeMillis();
16568            if (mLastMemUsageReportTime < now) {
16569                mLastMemUsageReportTime = now;
16570            }
16571        }
16572    }
16573
16574    /**
16575     * Searches array of arguments for the specified string
16576     * @param args array of argument strings
16577     * @param value value to search for
16578     * @return true if the value is contained in the array
16579     */
16580    private static boolean scanArgs(String[] args, String value) {
16581        if (args != null) {
16582            for (String arg : args) {
16583                if (value.equals(arg)) {
16584                    return true;
16585                }
16586            }
16587        }
16588        return false;
16589    }
16590
16591    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16592            ContentProviderRecord cpr, boolean always) {
16593        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16594
16595        if (!inLaunching || always) {
16596            synchronized (cpr) {
16597                cpr.launchingApp = null;
16598                cpr.notifyAll();
16599            }
16600            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16601            String names[] = cpr.info.authority.split(";");
16602            for (int j = 0; j < names.length; j++) {
16603                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16604            }
16605        }
16606
16607        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16608            ContentProviderConnection conn = cpr.connections.get(i);
16609            if (conn.waiting) {
16610                // If this connection is waiting for the provider, then we don't
16611                // need to mess with its process unless we are always removing
16612                // or for some reason the provider is not currently launching.
16613                if (inLaunching && !always) {
16614                    continue;
16615                }
16616            }
16617            ProcessRecord capp = conn.client;
16618            conn.dead = true;
16619            if (conn.stableCount > 0) {
16620                if (!capp.persistent && capp.thread != null
16621                        && capp.pid != 0
16622                        && capp.pid != MY_PID) {
16623                    capp.kill("depends on provider "
16624                            + cpr.name.flattenToShortString()
16625                            + " in dying proc " + (proc != null ? proc.processName : "??")
16626                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16627                }
16628            } else if (capp.thread != null && conn.provider.provider != null) {
16629                try {
16630                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16631                } catch (RemoteException e) {
16632                }
16633                // In the protocol here, we don't expect the client to correctly
16634                // clean up this connection, we'll just remove it.
16635                cpr.connections.remove(i);
16636                if (conn.client.conProviders.remove(conn)) {
16637                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16638                }
16639            }
16640        }
16641
16642        if (inLaunching && always) {
16643            mLaunchingProviders.remove(cpr);
16644        }
16645        return inLaunching;
16646    }
16647
16648    /**
16649     * Main code for cleaning up a process when it has gone away.  This is
16650     * called both as a result of the process dying, or directly when stopping
16651     * a process when running in single process mode.
16652     *
16653     * @return Returns true if the given process has been restarted, so the
16654     * app that was passed in must remain on the process lists.
16655     */
16656    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16657            boolean restarting, boolean allowRestart, int index) {
16658        if (index >= 0) {
16659            removeLruProcessLocked(app);
16660            ProcessList.remove(app.pid);
16661        }
16662
16663        mProcessesToGc.remove(app);
16664        mPendingPssProcesses.remove(app);
16665
16666        // Dismiss any open dialogs.
16667        if (app.crashDialog != null && !app.forceCrashReport) {
16668            app.crashDialog.dismiss();
16669            app.crashDialog = null;
16670        }
16671        if (app.anrDialog != null) {
16672            app.anrDialog.dismiss();
16673            app.anrDialog = null;
16674        }
16675        if (app.waitDialog != null) {
16676            app.waitDialog.dismiss();
16677            app.waitDialog = null;
16678        }
16679
16680        app.crashing = false;
16681        app.notResponding = false;
16682
16683        app.resetPackageList(mProcessStats);
16684        app.unlinkDeathRecipient();
16685        app.makeInactive(mProcessStats);
16686        app.waitingToKill = null;
16687        app.forcingToForeground = null;
16688        updateProcessForegroundLocked(app, false, false);
16689        app.foregroundActivities = false;
16690        app.hasShownUi = false;
16691        app.treatLikeActivity = false;
16692        app.hasAboveClient = false;
16693        app.hasClientActivities = false;
16694
16695        mServices.killServicesLocked(app, allowRestart);
16696
16697        boolean restart = false;
16698
16699        // Remove published content providers.
16700        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16701            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16702            final boolean always = app.bad || !allowRestart;
16703            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16704            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16705                // We left the provider in the launching list, need to
16706                // restart it.
16707                restart = true;
16708            }
16709
16710            cpr.provider = null;
16711            cpr.proc = null;
16712        }
16713        app.pubProviders.clear();
16714
16715        // Take care of any launching providers waiting for this process.
16716        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16717            restart = true;
16718        }
16719
16720        // Unregister from connected content providers.
16721        if (!app.conProviders.isEmpty()) {
16722            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16723                ContentProviderConnection conn = app.conProviders.get(i);
16724                conn.provider.connections.remove(conn);
16725                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16726                        conn.provider.name);
16727            }
16728            app.conProviders.clear();
16729        }
16730
16731        // At this point there may be remaining entries in mLaunchingProviders
16732        // where we were the only one waiting, so they are no longer of use.
16733        // Look for these and clean up if found.
16734        // XXX Commented out for now.  Trying to figure out a way to reproduce
16735        // the actual situation to identify what is actually going on.
16736        if (false) {
16737            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16738                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16739                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16740                    synchronized (cpr) {
16741                        cpr.launchingApp = null;
16742                        cpr.notifyAll();
16743                    }
16744                }
16745            }
16746        }
16747
16748        skipCurrentReceiverLocked(app);
16749
16750        // Unregister any receivers.
16751        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16752            removeReceiverLocked(app.receivers.valueAt(i));
16753        }
16754        app.receivers.clear();
16755
16756        // If the app is undergoing backup, tell the backup manager about it
16757        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16758            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16759                    + mBackupTarget.appInfo + " died during backup");
16760            try {
16761                IBackupManager bm = IBackupManager.Stub.asInterface(
16762                        ServiceManager.getService(Context.BACKUP_SERVICE));
16763                bm.agentDisconnected(app.info.packageName);
16764            } catch (RemoteException e) {
16765                // can't happen; backup manager is local
16766            }
16767        }
16768
16769        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16770            ProcessChangeItem item = mPendingProcessChanges.get(i);
16771            if (item.pid == app.pid) {
16772                mPendingProcessChanges.remove(i);
16773                mAvailProcessChanges.add(item);
16774            }
16775        }
16776        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16777                null).sendToTarget();
16778
16779        // If the caller is restarting this app, then leave it in its
16780        // current lists and let the caller take care of it.
16781        if (restarting) {
16782            return false;
16783        }
16784
16785        if (!app.persistent || app.isolated) {
16786            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16787                    "Removing non-persistent process during cleanup: " + app);
16788            removeProcessNameLocked(app.processName, app.uid);
16789            if (mHeavyWeightProcess == app) {
16790                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16791                        mHeavyWeightProcess.userId, 0));
16792                mHeavyWeightProcess = null;
16793            }
16794        } else if (!app.removed) {
16795            // This app is persistent, so we need to keep its record around.
16796            // If it is not already on the pending app list, add it there
16797            // and start a new process for it.
16798            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16799                mPersistentStartingProcesses.add(app);
16800                restart = true;
16801            }
16802        }
16803        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16804                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16805        mProcessesOnHold.remove(app);
16806
16807        if (app == mHomeProcess) {
16808            mHomeProcess = null;
16809        }
16810        if (app == mPreviousProcess) {
16811            mPreviousProcess = null;
16812        }
16813
16814        if (restart && !app.isolated) {
16815            // We have components that still need to be running in the
16816            // process, so re-launch it.
16817            if (index < 0) {
16818                ProcessList.remove(app.pid);
16819            }
16820            addProcessNameLocked(app);
16821            startProcessLocked(app, "restart", app.processName);
16822            return true;
16823        } else if (app.pid > 0 && app.pid != MY_PID) {
16824            // Goodbye!
16825            boolean removed;
16826            synchronized (mPidsSelfLocked) {
16827                mPidsSelfLocked.remove(app.pid);
16828                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16829            }
16830            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16831            if (app.isolated) {
16832                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16833            }
16834            app.setPid(0);
16835        }
16836        return false;
16837    }
16838
16839    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16840        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16841            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16842            if (cpr.launchingApp == app) {
16843                return true;
16844            }
16845        }
16846        return false;
16847    }
16848
16849    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16850        // Look through the content providers we are waiting to have launched,
16851        // and if any run in this process then either schedule a restart of
16852        // the process or kill the client waiting for it if this process has
16853        // gone bad.
16854        boolean restart = false;
16855        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16856            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16857            if (cpr.launchingApp == app) {
16858                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16859                    restart = true;
16860                } else {
16861                    removeDyingProviderLocked(app, cpr, true);
16862                }
16863            }
16864        }
16865        return restart;
16866    }
16867
16868    // =========================================================
16869    // SERVICES
16870    // =========================================================
16871
16872    @Override
16873    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16874            int flags) {
16875        enforceNotIsolatedCaller("getServices");
16876        synchronized (this) {
16877            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16878        }
16879    }
16880
16881    @Override
16882    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16883        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16884        synchronized (this) {
16885            return mServices.getRunningServiceControlPanelLocked(name);
16886        }
16887    }
16888
16889    @Override
16890    public ComponentName startService(IApplicationThread caller, Intent service,
16891            String resolvedType, String callingPackage, int userId)
16892            throws TransactionTooLargeException {
16893        enforceNotIsolatedCaller("startService");
16894        // Refuse possible leaked file descriptors
16895        if (service != null && service.hasFileDescriptors() == true) {
16896            throw new IllegalArgumentException("File descriptors passed in Intent");
16897        }
16898
16899        if (callingPackage == null) {
16900            throw new IllegalArgumentException("callingPackage cannot be null");
16901        }
16902
16903        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16904                "startService: " + service + " type=" + resolvedType);
16905        synchronized(this) {
16906            final int callingPid = Binder.getCallingPid();
16907            final int callingUid = Binder.getCallingUid();
16908            final long origId = Binder.clearCallingIdentity();
16909            ComponentName res = mServices.startServiceLocked(caller, service,
16910                    resolvedType, callingPid, callingUid, callingPackage, userId);
16911            Binder.restoreCallingIdentity(origId);
16912            return res;
16913        }
16914    }
16915
16916    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16917            String callingPackage, int userId)
16918            throws TransactionTooLargeException {
16919        synchronized(this) {
16920            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16921                    "startServiceInPackage: " + service + " type=" + resolvedType);
16922            final long origId = Binder.clearCallingIdentity();
16923            ComponentName res = mServices.startServiceLocked(null, service,
16924                    resolvedType, -1, uid, callingPackage, userId);
16925            Binder.restoreCallingIdentity(origId);
16926            return res;
16927        }
16928    }
16929
16930    @Override
16931    public int stopService(IApplicationThread caller, Intent service,
16932            String resolvedType, int userId) {
16933        enforceNotIsolatedCaller("stopService");
16934        // Refuse possible leaked file descriptors
16935        if (service != null && service.hasFileDescriptors() == true) {
16936            throw new IllegalArgumentException("File descriptors passed in Intent");
16937        }
16938
16939        synchronized(this) {
16940            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16941        }
16942    }
16943
16944    @Override
16945    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16946        enforceNotIsolatedCaller("peekService");
16947        // Refuse possible leaked file descriptors
16948        if (service != null && service.hasFileDescriptors() == true) {
16949            throw new IllegalArgumentException("File descriptors passed in Intent");
16950        }
16951
16952        if (callingPackage == null) {
16953            throw new IllegalArgumentException("callingPackage cannot be null");
16954        }
16955
16956        synchronized(this) {
16957            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16958        }
16959    }
16960
16961    @Override
16962    public boolean stopServiceToken(ComponentName className, IBinder token,
16963            int startId) {
16964        synchronized(this) {
16965            return mServices.stopServiceTokenLocked(className, token, startId);
16966        }
16967    }
16968
16969    @Override
16970    public void setServiceForeground(ComponentName className, IBinder token,
16971            int id, Notification notification, int flags) {
16972        synchronized(this) {
16973            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16974        }
16975    }
16976
16977    @Override
16978    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16979            boolean requireFull, String name, String callerPackage) {
16980        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16981                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16982    }
16983
16984    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16985            String className, int flags) {
16986        boolean result = false;
16987        // For apps that don't have pre-defined UIDs, check for permission
16988        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16989            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16990                if (ActivityManager.checkUidPermission(
16991                        INTERACT_ACROSS_USERS,
16992                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16993                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16994                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16995                            + " requests FLAG_SINGLE_USER, but app does not hold "
16996                            + INTERACT_ACROSS_USERS;
16997                    Slog.w(TAG, msg);
16998                    throw new SecurityException(msg);
16999                }
17000                // Permission passed
17001                result = true;
17002            }
17003        } else if ("system".equals(componentProcessName)) {
17004            result = true;
17005        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17006            // Phone app and persistent apps are allowed to export singleuser providers.
17007            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17008                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17009        }
17010        if (DEBUG_MU) Slog.v(TAG_MU,
17011                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17012                + Integer.toHexString(flags) + ") = " + result);
17013        return result;
17014    }
17015
17016    /**
17017     * Checks to see if the caller is in the same app as the singleton
17018     * component, or the component is in a special app. It allows special apps
17019     * to export singleton components but prevents exporting singleton
17020     * components for regular apps.
17021     */
17022    boolean isValidSingletonCall(int callingUid, int componentUid) {
17023        int componentAppId = UserHandle.getAppId(componentUid);
17024        return UserHandle.isSameApp(callingUid, componentUid)
17025                || componentAppId == Process.SYSTEM_UID
17026                || componentAppId == Process.PHONE_UID
17027                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17028                        == PackageManager.PERMISSION_GRANTED;
17029    }
17030
17031    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17032            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17033            int userId) throws TransactionTooLargeException {
17034        enforceNotIsolatedCaller("bindService");
17035
17036        // Refuse possible leaked file descriptors
17037        if (service != null && service.hasFileDescriptors() == true) {
17038            throw new IllegalArgumentException("File descriptors passed in Intent");
17039        }
17040
17041        if (callingPackage == null) {
17042            throw new IllegalArgumentException("callingPackage cannot be null");
17043        }
17044
17045        synchronized(this) {
17046            return mServices.bindServiceLocked(caller, token, service,
17047                    resolvedType, connection, flags, callingPackage, userId);
17048        }
17049    }
17050
17051    public boolean unbindService(IServiceConnection connection) {
17052        synchronized (this) {
17053            return mServices.unbindServiceLocked(connection);
17054        }
17055    }
17056
17057    public void publishService(IBinder token, Intent intent, IBinder service) {
17058        // Refuse possible leaked file descriptors
17059        if (intent != null && intent.hasFileDescriptors() == true) {
17060            throw new IllegalArgumentException("File descriptors passed in Intent");
17061        }
17062
17063        synchronized(this) {
17064            if (!(token instanceof ServiceRecord)) {
17065                throw new IllegalArgumentException("Invalid service token");
17066            }
17067            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17068        }
17069    }
17070
17071    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17072        // Refuse possible leaked file descriptors
17073        if (intent != null && intent.hasFileDescriptors() == true) {
17074            throw new IllegalArgumentException("File descriptors passed in Intent");
17075        }
17076
17077        synchronized(this) {
17078            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17079        }
17080    }
17081
17082    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17083        synchronized(this) {
17084            if (!(token instanceof ServiceRecord)) {
17085                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17086                throw new IllegalArgumentException("Invalid service token");
17087            }
17088            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17089        }
17090    }
17091
17092    // =========================================================
17093    // BACKUP AND RESTORE
17094    // =========================================================
17095
17096    // Cause the target app to be launched if necessary and its backup agent
17097    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17098    // activity manager to announce its creation.
17099    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17100        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17101        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17102
17103        IPackageManager pm = AppGlobals.getPackageManager();
17104        ApplicationInfo app = null;
17105        try {
17106            app = pm.getApplicationInfo(packageName, 0, userId);
17107        } catch (RemoteException e) {
17108            // can't happen; package manager is process-local
17109        }
17110        if (app == null) {
17111            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17112            return false;
17113        }
17114
17115        synchronized(this) {
17116            // !!! TODO: currently no check here that we're already bound
17117            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17118            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17119            synchronized (stats) {
17120                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17121            }
17122
17123            // Backup agent is now in use, its package can't be stopped.
17124            try {
17125                AppGlobals.getPackageManager().setPackageStoppedState(
17126                        app.packageName, false, UserHandle.getUserId(app.uid));
17127            } catch (RemoteException e) {
17128            } catch (IllegalArgumentException e) {
17129                Slog.w(TAG, "Failed trying to unstop package "
17130                        + app.packageName + ": " + e);
17131            }
17132
17133            BackupRecord r = new BackupRecord(ss, app, backupMode);
17134            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17135                    ? new ComponentName(app.packageName, app.backupAgentName)
17136                    : new ComponentName("android", "FullBackupAgent");
17137            // startProcessLocked() returns existing proc's record if it's already running
17138            ProcessRecord proc = startProcessLocked(app.processName, app,
17139                    false, 0, "backup", hostingName, false, false, false);
17140            if (proc == null) {
17141                Slog.e(TAG, "Unable to start backup agent process " + r);
17142                return false;
17143            }
17144
17145            // If the app is a regular app (uid >= 10000) and not the system server or phone
17146            // process, etc, then mark it as being in full backup so that certain calls to the
17147            // process can be blocked. This is not reset to false anywhere because we kill the
17148            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17149            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17150                proc.inFullBackup = true;
17151            }
17152            r.app = proc;
17153            mBackupTarget = r;
17154            mBackupAppName = app.packageName;
17155
17156            // Try not to kill the process during backup
17157            updateOomAdjLocked(proc);
17158
17159            // If the process is already attached, schedule the creation of the backup agent now.
17160            // If it is not yet live, this will be done when it attaches to the framework.
17161            if (proc.thread != null) {
17162                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17163                try {
17164                    proc.thread.scheduleCreateBackupAgent(app,
17165                            compatibilityInfoForPackageLocked(app), backupMode);
17166                } catch (RemoteException e) {
17167                    // Will time out on the backup manager side
17168                }
17169            } else {
17170                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17171            }
17172            // Invariants: at this point, the target app process exists and the application
17173            // is either already running or in the process of coming up.  mBackupTarget and
17174            // mBackupAppName describe the app, so that when it binds back to the AM we
17175            // know that it's scheduled for a backup-agent operation.
17176        }
17177
17178        return true;
17179    }
17180
17181    @Override
17182    public void clearPendingBackup() {
17183        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17184        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17185
17186        synchronized (this) {
17187            mBackupTarget = null;
17188            mBackupAppName = null;
17189        }
17190    }
17191
17192    // A backup agent has just come up
17193    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17194        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17195                + " = " + agent);
17196
17197        synchronized(this) {
17198            if (!agentPackageName.equals(mBackupAppName)) {
17199                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17200                return;
17201            }
17202        }
17203
17204        long oldIdent = Binder.clearCallingIdentity();
17205        try {
17206            IBackupManager bm = IBackupManager.Stub.asInterface(
17207                    ServiceManager.getService(Context.BACKUP_SERVICE));
17208            bm.agentConnected(agentPackageName, agent);
17209        } catch (RemoteException e) {
17210            // can't happen; the backup manager service is local
17211        } catch (Exception e) {
17212            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17213            e.printStackTrace();
17214        } finally {
17215            Binder.restoreCallingIdentity(oldIdent);
17216        }
17217    }
17218
17219    // done with this agent
17220    public void unbindBackupAgent(ApplicationInfo appInfo) {
17221        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17222        if (appInfo == null) {
17223            Slog.w(TAG, "unbind backup agent for null app");
17224            return;
17225        }
17226
17227        synchronized(this) {
17228            try {
17229                if (mBackupAppName == null) {
17230                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17231                    return;
17232                }
17233
17234                if (!mBackupAppName.equals(appInfo.packageName)) {
17235                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17236                    return;
17237                }
17238
17239                // Not backing this app up any more; reset its OOM adjustment
17240                final ProcessRecord proc = mBackupTarget.app;
17241                updateOomAdjLocked(proc);
17242
17243                // If the app crashed during backup, 'thread' will be null here
17244                if (proc.thread != null) {
17245                    try {
17246                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17247                                compatibilityInfoForPackageLocked(appInfo));
17248                    } catch (Exception e) {
17249                        Slog.e(TAG, "Exception when unbinding backup agent:");
17250                        e.printStackTrace();
17251                    }
17252                }
17253            } finally {
17254                mBackupTarget = null;
17255                mBackupAppName = null;
17256            }
17257        }
17258    }
17259    // =========================================================
17260    // BROADCASTS
17261    // =========================================================
17262
17263    boolean isPendingBroadcastProcessLocked(int pid) {
17264        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17265                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17266    }
17267
17268    void skipPendingBroadcastLocked(int pid) {
17269            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17270            for (BroadcastQueue queue : mBroadcastQueues) {
17271                queue.skipPendingBroadcastLocked(pid);
17272            }
17273    }
17274
17275    // The app just attached; send any pending broadcasts that it should receive
17276    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17277        boolean didSomething = false;
17278        for (BroadcastQueue queue : mBroadcastQueues) {
17279            didSomething |= queue.sendPendingBroadcastsLocked(app);
17280        }
17281        return didSomething;
17282    }
17283
17284    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17285            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17286        enforceNotIsolatedCaller("registerReceiver");
17287        ArrayList<Intent> stickyIntents = null;
17288        ProcessRecord callerApp = null;
17289        int callingUid;
17290        int callingPid;
17291        synchronized(this) {
17292            if (caller != null) {
17293                callerApp = getRecordForAppLocked(caller);
17294                if (callerApp == null) {
17295                    throw new SecurityException(
17296                            "Unable to find app for caller " + caller
17297                            + " (pid=" + Binder.getCallingPid()
17298                            + ") when registering receiver " + receiver);
17299                }
17300                if (callerApp.info.uid != Process.SYSTEM_UID &&
17301                        !callerApp.pkgList.containsKey(callerPackage) &&
17302                        !"android".equals(callerPackage)) {
17303                    throw new SecurityException("Given caller package " + callerPackage
17304                            + " is not running in process " + callerApp);
17305                }
17306                callingUid = callerApp.info.uid;
17307                callingPid = callerApp.pid;
17308            } else {
17309                callerPackage = null;
17310                callingUid = Binder.getCallingUid();
17311                callingPid = Binder.getCallingPid();
17312            }
17313
17314            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17315                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17316
17317            Iterator<String> actions = filter.actionsIterator();
17318            if (actions == null) {
17319                ArrayList<String> noAction = new ArrayList<String>(1);
17320                noAction.add(null);
17321                actions = noAction.iterator();
17322            }
17323
17324            // Collect stickies of users
17325            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17326            while (actions.hasNext()) {
17327                String action = actions.next();
17328                for (int id : userIds) {
17329                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17330                    if (stickies != null) {
17331                        ArrayList<Intent> intents = stickies.get(action);
17332                        if (intents != null) {
17333                            if (stickyIntents == null) {
17334                                stickyIntents = new ArrayList<Intent>();
17335                            }
17336                            stickyIntents.addAll(intents);
17337                        }
17338                    }
17339                }
17340            }
17341        }
17342
17343        ArrayList<Intent> allSticky = null;
17344        if (stickyIntents != null) {
17345            final ContentResolver resolver = mContext.getContentResolver();
17346            // Look for any matching sticky broadcasts...
17347            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17348                Intent intent = stickyIntents.get(i);
17349                // If intent has scheme "content", it will need to acccess
17350                // provider that needs to lock mProviderMap in ActivityThread
17351                // and also it may need to wait application response, so we
17352                // cannot lock ActivityManagerService here.
17353                if (filter.match(resolver, intent, true, TAG) >= 0) {
17354                    if (allSticky == null) {
17355                        allSticky = new ArrayList<Intent>();
17356                    }
17357                    allSticky.add(intent);
17358                }
17359            }
17360        }
17361
17362        // The first sticky in the list is returned directly back to the client.
17363        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17364        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17365        if (receiver == null) {
17366            return sticky;
17367        }
17368
17369        synchronized (this) {
17370            if (callerApp != null && (callerApp.thread == null
17371                    || callerApp.thread.asBinder() != caller.asBinder())) {
17372                // Original caller already died
17373                return null;
17374            }
17375            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17376            if (rl == null) {
17377                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17378                        userId, receiver);
17379                if (rl.app != null) {
17380                    rl.app.receivers.add(rl);
17381                } else {
17382                    try {
17383                        receiver.asBinder().linkToDeath(rl, 0);
17384                    } catch (RemoteException e) {
17385                        return sticky;
17386                    }
17387                    rl.linkedToDeath = true;
17388                }
17389                mRegisteredReceivers.put(receiver.asBinder(), rl);
17390            } else if (rl.uid != callingUid) {
17391                throw new IllegalArgumentException(
17392                        "Receiver requested to register for uid " + callingUid
17393                        + " was previously registered for uid " + rl.uid);
17394            } else if (rl.pid != callingPid) {
17395                throw new IllegalArgumentException(
17396                        "Receiver requested to register for pid " + callingPid
17397                        + " was previously registered for pid " + rl.pid);
17398            } else if (rl.userId != userId) {
17399                throw new IllegalArgumentException(
17400                        "Receiver requested to register for user " + userId
17401                        + " was previously registered for user " + rl.userId);
17402            }
17403            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17404                    permission, callingUid, userId);
17405            rl.add(bf);
17406            if (!bf.debugCheck()) {
17407                Slog.w(TAG, "==> For Dynamic broadcast");
17408            }
17409            mReceiverResolver.addFilter(bf);
17410
17411            // Enqueue broadcasts for all existing stickies that match
17412            // this filter.
17413            if (allSticky != null) {
17414                ArrayList receivers = new ArrayList();
17415                receivers.add(bf);
17416
17417                final int stickyCount = allSticky.size();
17418                for (int i = 0; i < stickyCount; i++) {
17419                    Intent intent = allSticky.get(i);
17420                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17421                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17422                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17423                            null, 0, null, null, false, true, true, -1);
17424                    queue.enqueueParallelBroadcastLocked(r);
17425                    queue.scheduleBroadcastsLocked();
17426                }
17427            }
17428
17429            return sticky;
17430        }
17431    }
17432
17433    public void unregisterReceiver(IIntentReceiver receiver) {
17434        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17435
17436        final long origId = Binder.clearCallingIdentity();
17437        try {
17438            boolean doTrim = false;
17439
17440            synchronized(this) {
17441                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17442                if (rl != null) {
17443                    final BroadcastRecord r = rl.curBroadcast;
17444                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17445                        final boolean doNext = r.queue.finishReceiverLocked(
17446                                r, r.resultCode, r.resultData, r.resultExtras,
17447                                r.resultAbort, false);
17448                        if (doNext) {
17449                            doTrim = true;
17450                            r.queue.processNextBroadcast(false);
17451                        }
17452                    }
17453
17454                    if (rl.app != null) {
17455                        rl.app.receivers.remove(rl);
17456                    }
17457                    removeReceiverLocked(rl);
17458                    if (rl.linkedToDeath) {
17459                        rl.linkedToDeath = false;
17460                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17461                    }
17462                }
17463            }
17464
17465            // If we actually concluded any broadcasts, we might now be able
17466            // to trim the recipients' apps from our working set
17467            if (doTrim) {
17468                trimApplications();
17469                return;
17470            }
17471
17472        } finally {
17473            Binder.restoreCallingIdentity(origId);
17474        }
17475    }
17476
17477    void removeReceiverLocked(ReceiverList rl) {
17478        mRegisteredReceivers.remove(rl.receiver.asBinder());
17479        for (int i = rl.size() - 1; i >= 0; i--) {
17480            mReceiverResolver.removeFilter(rl.get(i));
17481        }
17482    }
17483
17484    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17485        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17486            ProcessRecord r = mLruProcesses.get(i);
17487            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17488                try {
17489                    r.thread.dispatchPackageBroadcast(cmd, packages);
17490                } catch (RemoteException ex) {
17491                }
17492            }
17493        }
17494    }
17495
17496    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17497            int callingUid, int[] users) {
17498        // TODO: come back and remove this assumption to triage all broadcasts
17499        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17500
17501        List<ResolveInfo> receivers = null;
17502        try {
17503            HashSet<ComponentName> singleUserReceivers = null;
17504            boolean scannedFirstReceivers = false;
17505            for (int user : users) {
17506                // Skip users that have Shell restrictions, with exception of always permitted
17507                // Shell broadcasts
17508                if (callingUid == Process.SHELL_UID
17509                        && mUserController.hasUserRestriction(
17510                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17511                        && !isPermittedShellBroadcast(intent)) {
17512                    continue;
17513                }
17514                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17515                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17516                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17517                    // If this is not the system user, we need to check for
17518                    // any receivers that should be filtered out.
17519                    for (int i=0; i<newReceivers.size(); i++) {
17520                        ResolveInfo ri = newReceivers.get(i);
17521                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17522                            newReceivers.remove(i);
17523                            i--;
17524                        }
17525                    }
17526                }
17527                if (newReceivers != null && newReceivers.size() == 0) {
17528                    newReceivers = null;
17529                }
17530                if (receivers == null) {
17531                    receivers = newReceivers;
17532                } else if (newReceivers != null) {
17533                    // We need to concatenate the additional receivers
17534                    // found with what we have do far.  This would be easy,
17535                    // but we also need to de-dup any receivers that are
17536                    // singleUser.
17537                    if (!scannedFirstReceivers) {
17538                        // Collect any single user receivers we had already retrieved.
17539                        scannedFirstReceivers = true;
17540                        for (int i=0; i<receivers.size(); i++) {
17541                            ResolveInfo ri = receivers.get(i);
17542                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17543                                ComponentName cn = new ComponentName(
17544                                        ri.activityInfo.packageName, ri.activityInfo.name);
17545                                if (singleUserReceivers == null) {
17546                                    singleUserReceivers = new HashSet<ComponentName>();
17547                                }
17548                                singleUserReceivers.add(cn);
17549                            }
17550                        }
17551                    }
17552                    // Add the new results to the existing results, tracking
17553                    // and de-dupping single user receivers.
17554                    for (int i=0; i<newReceivers.size(); i++) {
17555                        ResolveInfo ri = newReceivers.get(i);
17556                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17557                            ComponentName cn = new ComponentName(
17558                                    ri.activityInfo.packageName, ri.activityInfo.name);
17559                            if (singleUserReceivers == null) {
17560                                singleUserReceivers = new HashSet<ComponentName>();
17561                            }
17562                            if (!singleUserReceivers.contains(cn)) {
17563                                singleUserReceivers.add(cn);
17564                                receivers.add(ri);
17565                            }
17566                        } else {
17567                            receivers.add(ri);
17568                        }
17569                    }
17570                }
17571            }
17572        } catch (RemoteException ex) {
17573            // pm is in same process, this will never happen.
17574        }
17575        return receivers;
17576    }
17577
17578    private boolean isPermittedShellBroadcast(Intent intent) {
17579        // remote bugreport should always be allowed to be taken
17580        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17581    }
17582
17583    final int broadcastIntentLocked(ProcessRecord callerApp,
17584            String callerPackage, Intent intent, String resolvedType,
17585            IIntentReceiver resultTo, int resultCode, String resultData,
17586            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17587            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17588        intent = new Intent(intent);
17589
17590        // By default broadcasts do not go to stopped apps.
17591        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17592
17593        // If we have not finished booting, don't allow this to launch new processes.
17594        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17595            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17596        }
17597
17598        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17599                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17600                + " ordered=" + ordered + " userid=" + userId);
17601        if ((resultTo != null) && !ordered) {
17602            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17603        }
17604
17605        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17606                ALLOW_NON_FULL, "broadcast", callerPackage);
17607
17608        // Make sure that the user who is receiving this broadcast is running.
17609        // If not, we will just skip it. Make an exception for shutdown broadcasts
17610        // and upgrade steps.
17611
17612        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17613            if ((callingUid != Process.SYSTEM_UID
17614                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17615                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17616                Slog.w(TAG, "Skipping broadcast of " + intent
17617                        + ": user " + userId + " is stopped");
17618                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17619            }
17620        }
17621
17622        BroadcastOptions brOptions = null;
17623        if (bOptions != null) {
17624            brOptions = new BroadcastOptions(bOptions);
17625            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17626                // See if the caller is allowed to do this.  Note we are checking against
17627                // the actual real caller (not whoever provided the operation as say a
17628                // PendingIntent), because that who is actually supplied the arguments.
17629                if (checkComponentPermission(
17630                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17631                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17632                        != PackageManager.PERMISSION_GRANTED) {
17633                    String msg = "Permission Denial: " + intent.getAction()
17634                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17635                            + ", uid=" + callingUid + ")"
17636                            + " requires "
17637                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17638                    Slog.w(TAG, msg);
17639                    throw new SecurityException(msg);
17640                }
17641            }
17642        }
17643
17644        // Verify that protected broadcasts are only being sent by system code,
17645        // and that system code is only sending protected broadcasts.
17646        final String action = intent.getAction();
17647        final boolean isProtectedBroadcast;
17648        try {
17649            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17650        } catch (RemoteException e) {
17651            Slog.w(TAG, "Remote exception", e);
17652            return ActivityManager.BROADCAST_SUCCESS;
17653        }
17654
17655        final boolean isCallerSystem;
17656        switch (UserHandle.getAppId(callingUid)) {
17657            case Process.ROOT_UID:
17658            case Process.SYSTEM_UID:
17659            case Process.PHONE_UID:
17660            case Process.BLUETOOTH_UID:
17661            case Process.NFC_UID:
17662                isCallerSystem = true;
17663                break;
17664            default:
17665                isCallerSystem = (callerApp != null) && callerApp.persistent;
17666                break;
17667        }
17668
17669        if (isCallerSystem) {
17670            if (isProtectedBroadcast
17671                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17672                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17673                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17674                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17675                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17676                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17677                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17678                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17679                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17680                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17681                // Broadcast is either protected, or it's a public action that
17682                // we've relaxed, so it's fine for system internals to send.
17683            } else {
17684                // The vast majority of broadcasts sent from system internals
17685                // should be protected to avoid security holes, so yell loudly
17686                // to ensure we examine these cases.
17687                if (callerApp != null) {
17688                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17689                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17690                            new Throwable());
17691                } else {
17692                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17693                            + " from system uid " + UserHandle.formatUid(callingUid)
17694                            + " pkg " + callerPackage,
17695                            new Throwable());
17696                }
17697            }
17698
17699        } else {
17700            if (isProtectedBroadcast) {
17701                String msg = "Permission Denial: not allowed to send broadcast "
17702                        + action + " from pid="
17703                        + callingPid + ", uid=" + callingUid;
17704                Slog.w(TAG, msg);
17705                throw new SecurityException(msg);
17706
17707            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17708                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17709                // Special case for compatibility: we don't want apps to send this,
17710                // but historically it has not been protected and apps may be using it
17711                // to poke their own app widget.  So, instead of making it protected,
17712                // just limit it to the caller.
17713                if (callerPackage == null) {
17714                    String msg = "Permission Denial: not allowed to send broadcast "
17715                            + action + " from unknown caller.";
17716                    Slog.w(TAG, msg);
17717                    throw new SecurityException(msg);
17718                } else if (intent.getComponent() != null) {
17719                    // They are good enough to send to an explicit component...  verify
17720                    // it is being sent to the calling app.
17721                    if (!intent.getComponent().getPackageName().equals(
17722                            callerPackage)) {
17723                        String msg = "Permission Denial: not allowed to send broadcast "
17724                                + action + " to "
17725                                + intent.getComponent().getPackageName() + " from "
17726                                + callerPackage;
17727                        Slog.w(TAG, msg);
17728                        throw new SecurityException(msg);
17729                    }
17730                } else {
17731                    // Limit broadcast to their own package.
17732                    intent.setPackage(callerPackage);
17733                }
17734            }
17735        }
17736
17737        if (action != null) {
17738            switch (action) {
17739                case Intent.ACTION_UID_REMOVED:
17740                case Intent.ACTION_PACKAGE_REMOVED:
17741                case Intent.ACTION_PACKAGE_CHANGED:
17742                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17743                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17744                case Intent.ACTION_PACKAGES_SUSPENDED:
17745                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17746                    // Handle special intents: if this broadcast is from the package
17747                    // manager about a package being removed, we need to remove all of
17748                    // its activities from the history stack.
17749                    if (checkComponentPermission(
17750                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17751                            callingPid, callingUid, -1, true)
17752                            != PackageManager.PERMISSION_GRANTED) {
17753                        String msg = "Permission Denial: " + intent.getAction()
17754                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17755                                + ", uid=" + callingUid + ")"
17756                                + " requires "
17757                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17758                        Slog.w(TAG, msg);
17759                        throw new SecurityException(msg);
17760                    }
17761                    switch (action) {
17762                        case Intent.ACTION_UID_REMOVED:
17763                            final Bundle intentExtras = intent.getExtras();
17764                            final int uid = intentExtras != null
17765                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17766                            if (uid >= 0) {
17767                                mBatteryStatsService.removeUid(uid);
17768                                mAppOpsService.uidRemoved(uid);
17769                            }
17770                            break;
17771                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17772                            // If resources are unavailable just force stop all those packages
17773                            // and flush the attribute cache as well.
17774                            String list[] =
17775                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17776                            if (list != null && list.length > 0) {
17777                                for (int i = 0; i < list.length; i++) {
17778                                    forceStopPackageLocked(list[i], -1, false, true, true,
17779                                            false, false, userId, "storage unmount");
17780                                }
17781                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17782                                sendPackageBroadcastLocked(
17783                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17784                                        userId);
17785                            }
17786                            break;
17787                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17788                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17789                            break;
17790                        case Intent.ACTION_PACKAGE_REMOVED:
17791                        case Intent.ACTION_PACKAGE_CHANGED:
17792                            Uri data = intent.getData();
17793                            String ssp;
17794                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17795                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17796                                final boolean replacing =
17797                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17798                                final boolean killProcess =
17799                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17800                                final boolean fullUninstall = removed && !replacing;
17801                                if (removed) {
17802                                    if (killProcess) {
17803                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17804                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17805                                                false, true, true, false, fullUninstall, userId,
17806                                                removed ? "pkg removed" : "pkg changed");
17807                                    }
17808                                    final int cmd = killProcess
17809                                            ? IApplicationThread.PACKAGE_REMOVED
17810                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17811                                    sendPackageBroadcastLocked(cmd,
17812                                            new String[] {ssp}, userId);
17813                                    if (fullUninstall) {
17814                                        mAppOpsService.packageRemoved(
17815                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17816
17817                                        // Remove all permissions granted from/to this package
17818                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17819
17820                                        removeTasksByPackageNameLocked(ssp, userId);
17821
17822                                        // Hide the "unsupported display" dialog if necessary.
17823                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17824                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17825                                            mUnsupportedDisplaySizeDialog.dismiss();
17826                                            mUnsupportedDisplaySizeDialog = null;
17827                                        }
17828                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17829                                        mBatteryStatsService.notePackageUninstalled(ssp);
17830                                    }
17831                                } else {
17832                                    if (killProcess) {
17833                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17834                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17835                                                userId, ProcessList.INVALID_ADJ,
17836                                                false, true, true, false, "change " + ssp);
17837                                    }
17838                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17839                                            intent.getStringArrayExtra(
17840                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17841                                }
17842                            }
17843                            break;
17844                        case Intent.ACTION_PACKAGES_SUSPENDED:
17845                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17846                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17847                                    intent.getAction());
17848                            final String[] packageNames = intent.getStringArrayExtra(
17849                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17850                            final int userHandle = intent.getIntExtra(
17851                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17852
17853                            synchronized(ActivityManagerService.this) {
17854                                mRecentTasks.onPackagesSuspendedChanged(
17855                                        packageNames, suspended, userHandle);
17856                            }
17857                            break;
17858                    }
17859                    break;
17860                case Intent.ACTION_PACKAGE_REPLACED:
17861                {
17862                    final Uri data = intent.getData();
17863                    final String ssp;
17864                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17865                        final ApplicationInfo aInfo =
17866                                getPackageManagerInternalLocked().getApplicationInfo(
17867                                        ssp,
17868                                        userId);
17869                        if (aInfo == null) {
17870                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17871                                    + " ssp=" + ssp + " data=" + data);
17872                            return ActivityManager.BROADCAST_SUCCESS;
17873                        }
17874                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17875                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17876                                new String[] {ssp}, userId);
17877                    }
17878                    break;
17879                }
17880                case Intent.ACTION_PACKAGE_ADDED:
17881                {
17882                    // Special case for adding a package: by default turn on compatibility mode.
17883                    Uri data = intent.getData();
17884                    String ssp;
17885                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17886                        final boolean replacing =
17887                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17888                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17889
17890                        try {
17891                            ApplicationInfo ai = AppGlobals.getPackageManager().
17892                                    getApplicationInfo(ssp, 0, 0);
17893                            mBatteryStatsService.notePackageInstalled(ssp,
17894                                    ai != null ? ai.versionCode : 0);
17895                        } catch (RemoteException e) {
17896                        }
17897                    }
17898                    break;
17899                }
17900                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17901                {
17902                    Uri data = intent.getData();
17903                    String ssp;
17904                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17905                        // Hide the "unsupported display" dialog if necessary.
17906                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17907                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17908                            mUnsupportedDisplaySizeDialog.dismiss();
17909                            mUnsupportedDisplaySizeDialog = null;
17910                        }
17911                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
17912                    }
17913                    break;
17914                }
17915                case Intent.ACTION_TIMEZONE_CHANGED:
17916                    // If this is the time zone changed action, queue up a message that will reset
17917                    // the timezone of all currently running processes. This message will get
17918                    // queued up before the broadcast happens.
17919                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17920                    break;
17921                case Intent.ACTION_TIME_CHANGED:
17922                    // If the user set the time, let all running processes know.
17923                    final int is24Hour =
17924                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17925                                    : 0;
17926                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17927                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17928                    synchronized (stats) {
17929                        stats.noteCurrentTimeChangedLocked();
17930                    }
17931                    break;
17932                case Intent.ACTION_CLEAR_DNS_CACHE:
17933                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17934                    break;
17935                case Proxy.PROXY_CHANGE_ACTION:
17936                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17937                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17938                    break;
17939                case android.hardware.Camera.ACTION_NEW_PICTURE:
17940                case android.hardware.Camera.ACTION_NEW_VIDEO:
17941                    // These broadcasts are no longer allowed by the system, since they can
17942                    // cause significant thrashing at a crictical point (using the camera).
17943                    // Apps should use JobScehduler to monitor for media provider changes.
17944                    Slog.w(TAG, action + " no longer allowed; dropping from "
17945                            + UserHandle.formatUid(callingUid));
17946                    if (resultTo != null) {
17947                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
17948                        try {
17949                            queue.performReceiveLocked(callerApp, resultTo, intent,
17950                                    Activity.RESULT_CANCELED, null, null,
17951                                    false, false, userId);
17952                        } catch (RemoteException e) {
17953                            Slog.w(TAG, "Failure ["
17954                                    + queue.mQueueName + "] sending broadcast result of "
17955                                    + intent, e);
17956
17957                        }
17958                    }
17959                    // Lie; we don't want to crash the app.
17960                    return ActivityManager.BROADCAST_SUCCESS;
17961            }
17962        }
17963
17964        // Add to the sticky list if requested.
17965        if (sticky) {
17966            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17967                    callingPid, callingUid)
17968                    != PackageManager.PERMISSION_GRANTED) {
17969                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17970                        + callingPid + ", uid=" + callingUid
17971                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17972                Slog.w(TAG, msg);
17973                throw new SecurityException(msg);
17974            }
17975            if (requiredPermissions != null && requiredPermissions.length > 0) {
17976                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17977                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17978                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17979            }
17980            if (intent.getComponent() != null) {
17981                throw new SecurityException(
17982                        "Sticky broadcasts can't target a specific component");
17983            }
17984            // We use userId directly here, since the "all" target is maintained
17985            // as a separate set of sticky broadcasts.
17986            if (userId != UserHandle.USER_ALL) {
17987                // But first, if this is not a broadcast to all users, then
17988                // make sure it doesn't conflict with an existing broadcast to
17989                // all users.
17990                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17991                        UserHandle.USER_ALL);
17992                if (stickies != null) {
17993                    ArrayList<Intent> list = stickies.get(intent.getAction());
17994                    if (list != null) {
17995                        int N = list.size();
17996                        int i;
17997                        for (i=0; i<N; i++) {
17998                            if (intent.filterEquals(list.get(i))) {
17999                                throw new IllegalArgumentException(
18000                                        "Sticky broadcast " + intent + " for user "
18001                                        + userId + " conflicts with existing global broadcast");
18002                            }
18003                        }
18004                    }
18005                }
18006            }
18007            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18008            if (stickies == null) {
18009                stickies = new ArrayMap<>();
18010                mStickyBroadcasts.put(userId, stickies);
18011            }
18012            ArrayList<Intent> list = stickies.get(intent.getAction());
18013            if (list == null) {
18014                list = new ArrayList<>();
18015                stickies.put(intent.getAction(), list);
18016            }
18017            final int stickiesCount = list.size();
18018            int i;
18019            for (i = 0; i < stickiesCount; i++) {
18020                if (intent.filterEquals(list.get(i))) {
18021                    // This sticky already exists, replace it.
18022                    list.set(i, new Intent(intent));
18023                    break;
18024                }
18025            }
18026            if (i >= stickiesCount) {
18027                list.add(new Intent(intent));
18028            }
18029        }
18030
18031        int[] users;
18032        if (userId == UserHandle.USER_ALL) {
18033            // Caller wants broadcast to go to all started users.
18034            users = mUserController.getStartedUserArrayLocked();
18035        } else {
18036            // Caller wants broadcast to go to one specific user.
18037            users = new int[] {userId};
18038        }
18039
18040        // Figure out who all will receive this broadcast.
18041        List receivers = null;
18042        List<BroadcastFilter> registeredReceivers = null;
18043        // Need to resolve the intent to interested receivers...
18044        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18045                 == 0) {
18046            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18047        }
18048        if (intent.getComponent() == null) {
18049            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18050                // Query one target user at a time, excluding shell-restricted users
18051                for (int i = 0; i < users.length; i++) {
18052                    if (mUserController.hasUserRestriction(
18053                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18054                        continue;
18055                    }
18056                    List<BroadcastFilter> registeredReceiversForUser =
18057                            mReceiverResolver.queryIntent(intent,
18058                                    resolvedType, false, users[i]);
18059                    if (registeredReceivers == null) {
18060                        registeredReceivers = registeredReceiversForUser;
18061                    } else if (registeredReceiversForUser != null) {
18062                        registeredReceivers.addAll(registeredReceiversForUser);
18063                    }
18064                }
18065            } else {
18066                registeredReceivers = mReceiverResolver.queryIntent(intent,
18067                        resolvedType, false, userId);
18068            }
18069        }
18070
18071        final boolean replacePending =
18072                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18073
18074        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18075                + " replacePending=" + replacePending);
18076
18077        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18078        if (!ordered && NR > 0) {
18079            // If we are not serializing this broadcast, then send the
18080            // registered receivers separately so they don't wait for the
18081            // components to be launched.
18082            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18083            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18084                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18085                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18086                    resultExtras, ordered, sticky, false, userId);
18087            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18088            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18089            if (!replaced) {
18090                queue.enqueueParallelBroadcastLocked(r);
18091                queue.scheduleBroadcastsLocked();
18092            }
18093            registeredReceivers = null;
18094            NR = 0;
18095        }
18096
18097        // Merge into one list.
18098        int ir = 0;
18099        if (receivers != null) {
18100            // A special case for PACKAGE_ADDED: do not allow the package
18101            // being added to see this broadcast.  This prevents them from
18102            // using this as a back door to get run as soon as they are
18103            // installed.  Maybe in the future we want to have a special install
18104            // broadcast or such for apps, but we'd like to deliberately make
18105            // this decision.
18106            String skipPackages[] = null;
18107            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18108                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18109                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18110                Uri data = intent.getData();
18111                if (data != null) {
18112                    String pkgName = data.getSchemeSpecificPart();
18113                    if (pkgName != null) {
18114                        skipPackages = new String[] { pkgName };
18115                    }
18116                }
18117            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18118                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18119            }
18120            if (skipPackages != null && (skipPackages.length > 0)) {
18121                for (String skipPackage : skipPackages) {
18122                    if (skipPackage != null) {
18123                        int NT = receivers.size();
18124                        for (int it=0; it<NT; it++) {
18125                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18126                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18127                                receivers.remove(it);
18128                                it--;
18129                                NT--;
18130                            }
18131                        }
18132                    }
18133                }
18134            }
18135
18136            int NT = receivers != null ? receivers.size() : 0;
18137            int it = 0;
18138            ResolveInfo curt = null;
18139            BroadcastFilter curr = null;
18140            while (it < NT && ir < NR) {
18141                if (curt == null) {
18142                    curt = (ResolveInfo)receivers.get(it);
18143                }
18144                if (curr == null) {
18145                    curr = registeredReceivers.get(ir);
18146                }
18147                if (curr.getPriority() >= curt.priority) {
18148                    // Insert this broadcast record into the final list.
18149                    receivers.add(it, curr);
18150                    ir++;
18151                    curr = null;
18152                    it++;
18153                    NT++;
18154                } else {
18155                    // Skip to the next ResolveInfo in the final list.
18156                    it++;
18157                    curt = null;
18158                }
18159            }
18160        }
18161        while (ir < NR) {
18162            if (receivers == null) {
18163                receivers = new ArrayList();
18164            }
18165            receivers.add(registeredReceivers.get(ir));
18166            ir++;
18167        }
18168
18169        if ((receivers != null && receivers.size() > 0)
18170                || resultTo != null) {
18171            BroadcastQueue queue = broadcastQueueForIntent(intent);
18172            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18173                    callerPackage, callingPid, callingUid, resolvedType,
18174                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18175                    resultData, resultExtras, ordered, sticky, false, userId);
18176
18177            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18178                    + ": prev had " + queue.mOrderedBroadcasts.size());
18179            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18180                    "Enqueueing broadcast " + r.intent.getAction());
18181
18182            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18183            if (!replaced) {
18184                queue.enqueueOrderedBroadcastLocked(r);
18185                queue.scheduleBroadcastsLocked();
18186            }
18187        } else {
18188            // There was nobody interested in the broadcast, but we still want to record
18189            // that it happened.
18190            if (intent.getComponent() == null && intent.getPackage() == null
18191                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18192                // This was an implicit broadcast... let's record it for posterity.
18193                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18194            }
18195        }
18196
18197        return ActivityManager.BROADCAST_SUCCESS;
18198    }
18199
18200    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18201            int skipCount, long dispatchTime) {
18202        final long now = SystemClock.elapsedRealtime();
18203        if (mCurBroadcastStats == null ||
18204                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18205            mLastBroadcastStats = mCurBroadcastStats;
18206            if (mLastBroadcastStats != null) {
18207                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18208                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18209            }
18210            mCurBroadcastStats = new BroadcastStats();
18211        }
18212        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18213    }
18214
18215    final Intent verifyBroadcastLocked(Intent intent) {
18216        // Refuse possible leaked file descriptors
18217        if (intent != null && intent.hasFileDescriptors() == true) {
18218            throw new IllegalArgumentException("File descriptors passed in Intent");
18219        }
18220
18221        int flags = intent.getFlags();
18222
18223        if (!mProcessesReady) {
18224            // if the caller really truly claims to know what they're doing, go
18225            // ahead and allow the broadcast without launching any receivers
18226            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18227                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18228            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18229                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18230                        + " before boot completion");
18231                throw new IllegalStateException("Cannot broadcast before boot completed");
18232            }
18233        }
18234
18235        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18236            throw new IllegalArgumentException(
18237                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18238        }
18239
18240        return intent;
18241    }
18242
18243    public final int broadcastIntent(IApplicationThread caller,
18244            Intent intent, String resolvedType, IIntentReceiver resultTo,
18245            int resultCode, String resultData, Bundle resultExtras,
18246            String[] requiredPermissions, int appOp, Bundle bOptions,
18247            boolean serialized, boolean sticky, int userId) {
18248        enforceNotIsolatedCaller("broadcastIntent");
18249        synchronized(this) {
18250            intent = verifyBroadcastLocked(intent);
18251
18252            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18253            final int callingPid = Binder.getCallingPid();
18254            final int callingUid = Binder.getCallingUid();
18255            final long origId = Binder.clearCallingIdentity();
18256            int res = broadcastIntentLocked(callerApp,
18257                    callerApp != null ? callerApp.info.packageName : null,
18258                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18259                    requiredPermissions, appOp, bOptions, serialized, sticky,
18260                    callingPid, callingUid, userId);
18261            Binder.restoreCallingIdentity(origId);
18262            return res;
18263        }
18264    }
18265
18266
18267    int broadcastIntentInPackage(String packageName, int uid,
18268            Intent intent, String resolvedType, IIntentReceiver resultTo,
18269            int resultCode, String resultData, Bundle resultExtras,
18270            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18271            int userId) {
18272        synchronized(this) {
18273            intent = verifyBroadcastLocked(intent);
18274
18275            final long origId = Binder.clearCallingIdentity();
18276            String[] requiredPermissions = requiredPermission == null ? null
18277                    : new String[] {requiredPermission};
18278            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18279                    resultTo, resultCode, resultData, resultExtras,
18280                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18281                    sticky, -1, uid, userId);
18282            Binder.restoreCallingIdentity(origId);
18283            return res;
18284        }
18285    }
18286
18287    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18288        // Refuse possible leaked file descriptors
18289        if (intent != null && intent.hasFileDescriptors() == true) {
18290            throw new IllegalArgumentException("File descriptors passed in Intent");
18291        }
18292
18293        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18294                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18295
18296        synchronized(this) {
18297            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18298                    != PackageManager.PERMISSION_GRANTED) {
18299                String msg = "Permission Denial: unbroadcastIntent() from pid="
18300                        + Binder.getCallingPid()
18301                        + ", uid=" + Binder.getCallingUid()
18302                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18303                Slog.w(TAG, msg);
18304                throw new SecurityException(msg);
18305            }
18306            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18307            if (stickies != null) {
18308                ArrayList<Intent> list = stickies.get(intent.getAction());
18309                if (list != null) {
18310                    int N = list.size();
18311                    int i;
18312                    for (i=0; i<N; i++) {
18313                        if (intent.filterEquals(list.get(i))) {
18314                            list.remove(i);
18315                            break;
18316                        }
18317                    }
18318                    if (list.size() <= 0) {
18319                        stickies.remove(intent.getAction());
18320                    }
18321                }
18322                if (stickies.size() <= 0) {
18323                    mStickyBroadcasts.remove(userId);
18324                }
18325            }
18326        }
18327    }
18328
18329    void backgroundServicesFinishedLocked(int userId) {
18330        for (BroadcastQueue queue : mBroadcastQueues) {
18331            queue.backgroundServicesFinishedLocked(userId);
18332        }
18333    }
18334
18335    public void finishReceiver(IBinder who, int resultCode, String resultData,
18336            Bundle resultExtras, boolean resultAbort, int flags) {
18337        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18338
18339        // Refuse possible leaked file descriptors
18340        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18341            throw new IllegalArgumentException("File descriptors passed in Bundle");
18342        }
18343
18344        final long origId = Binder.clearCallingIdentity();
18345        try {
18346            boolean doNext = false;
18347            BroadcastRecord r;
18348
18349            synchronized(this) {
18350                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18351                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18352                r = queue.getMatchingOrderedReceiver(who);
18353                if (r != null) {
18354                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18355                        resultData, resultExtras, resultAbort, true);
18356                }
18357            }
18358
18359            if (doNext) {
18360                r.queue.processNextBroadcast(false);
18361            }
18362            trimApplications();
18363        } finally {
18364            Binder.restoreCallingIdentity(origId);
18365        }
18366    }
18367
18368    // =========================================================
18369    // INSTRUMENTATION
18370    // =========================================================
18371
18372    public boolean startInstrumentation(ComponentName className,
18373            String profileFile, int flags, Bundle arguments,
18374            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18375            int userId, String abiOverride) {
18376        enforceNotIsolatedCaller("startInstrumentation");
18377        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18378                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18379        // Refuse possible leaked file descriptors
18380        if (arguments != null && arguments.hasFileDescriptors()) {
18381            throw new IllegalArgumentException("File descriptors passed in Bundle");
18382        }
18383
18384        synchronized(this) {
18385            InstrumentationInfo ii = null;
18386            ApplicationInfo ai = null;
18387            try {
18388                ii = mContext.getPackageManager().getInstrumentationInfo(
18389                    className, STOCK_PM_FLAGS);
18390                ai = AppGlobals.getPackageManager().getApplicationInfo(
18391                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18392            } catch (PackageManager.NameNotFoundException e) {
18393            } catch (RemoteException e) {
18394            }
18395            if (ii == null) {
18396                reportStartInstrumentationFailureLocked(watcher, className,
18397                        "Unable to find instrumentation info for: " + className);
18398                return false;
18399            }
18400            if (ai == null) {
18401                reportStartInstrumentationFailureLocked(watcher, className,
18402                        "Unable to find instrumentation target package: " + ii.targetPackage);
18403                return false;
18404            }
18405            if (!ai.hasCode()) {
18406                reportStartInstrumentationFailureLocked(watcher, className,
18407                        "Instrumentation target has no code: " + ii.targetPackage);
18408                return false;
18409            }
18410
18411            int match = mContext.getPackageManager().checkSignatures(
18412                    ii.targetPackage, ii.packageName);
18413            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18414                String msg = "Permission Denial: starting instrumentation "
18415                        + className + " from pid="
18416                        + Binder.getCallingPid()
18417                        + ", uid=" + Binder.getCallingPid()
18418                        + " not allowed because package " + ii.packageName
18419                        + " does not have a signature matching the target "
18420                        + ii.targetPackage;
18421                reportStartInstrumentationFailureLocked(watcher, className, msg);
18422                throw new SecurityException(msg);
18423            }
18424
18425            final long origId = Binder.clearCallingIdentity();
18426            // Instrumentation can kill and relaunch even persistent processes
18427            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18428                    "start instr");
18429            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18430            app.instrumentationClass = className;
18431            app.instrumentationInfo = ai;
18432            app.instrumentationProfileFile = profileFile;
18433            app.instrumentationArguments = arguments;
18434            app.instrumentationWatcher = watcher;
18435            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18436            app.instrumentationResultClass = className;
18437            Binder.restoreCallingIdentity(origId);
18438        }
18439
18440        return true;
18441    }
18442
18443    /**
18444     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18445     * error to the logs, but if somebody is watching, send the report there too.  This enables
18446     * the "am" command to report errors with more information.
18447     *
18448     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18449     * @param cn The component name of the instrumentation.
18450     * @param report The error report.
18451     */
18452    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18453            ComponentName cn, String report) {
18454        Slog.w(TAG, report);
18455        if (watcher != null) {
18456            Bundle results = new Bundle();
18457            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18458            results.putString("Error", report);
18459            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18460        }
18461    }
18462
18463    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18464        if (app.instrumentationWatcher != null) {
18465            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18466                    app.instrumentationClass, resultCode, results);
18467        }
18468
18469        // Can't call out of the system process with a lock held, so post a message.
18470        if (app.instrumentationUiAutomationConnection != null) {
18471            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18472                    app.instrumentationUiAutomationConnection).sendToTarget();
18473        }
18474
18475        app.instrumentationWatcher = null;
18476        app.instrumentationUiAutomationConnection = null;
18477        app.instrumentationClass = null;
18478        app.instrumentationInfo = null;
18479        app.instrumentationProfileFile = null;
18480        app.instrumentationArguments = null;
18481
18482        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18483                "finished inst");
18484    }
18485
18486    public void finishInstrumentation(IApplicationThread target,
18487            int resultCode, Bundle results) {
18488        int userId = UserHandle.getCallingUserId();
18489        // Refuse possible leaked file descriptors
18490        if (results != null && results.hasFileDescriptors()) {
18491            throw new IllegalArgumentException("File descriptors passed in Intent");
18492        }
18493
18494        synchronized(this) {
18495            ProcessRecord app = getRecordForAppLocked(target);
18496            if (app == null) {
18497                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18498                return;
18499            }
18500            final long origId = Binder.clearCallingIdentity();
18501            finishInstrumentationLocked(app, resultCode, results);
18502            Binder.restoreCallingIdentity(origId);
18503        }
18504    }
18505
18506    // =========================================================
18507    // CONFIGURATION
18508    // =========================================================
18509
18510    public ConfigurationInfo getDeviceConfigurationInfo() {
18511        ConfigurationInfo config = new ConfigurationInfo();
18512        synchronized (this) {
18513            config.reqTouchScreen = mConfiguration.touchscreen;
18514            config.reqKeyboardType = mConfiguration.keyboard;
18515            config.reqNavigation = mConfiguration.navigation;
18516            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18517                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18518                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18519            }
18520            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18521                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18522                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18523            }
18524            config.reqGlEsVersion = GL_ES_VERSION;
18525        }
18526        return config;
18527    }
18528
18529    ActivityStack getFocusedStack() {
18530        return mStackSupervisor.getFocusedStack();
18531    }
18532
18533    @Override
18534    public int getFocusedStackId() throws RemoteException {
18535        ActivityStack focusedStack = getFocusedStack();
18536        if (focusedStack != null) {
18537            return focusedStack.getStackId();
18538        }
18539        return -1;
18540    }
18541
18542    public Configuration getConfiguration() {
18543        Configuration ci;
18544        synchronized(this) {
18545            ci = new Configuration(mConfiguration);
18546            ci.userSetLocale = false;
18547        }
18548        return ci;
18549    }
18550
18551    @Override
18552    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18553        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18554        synchronized (this) {
18555            mSuppressResizeConfigChanges = suppress;
18556        }
18557    }
18558
18559    @Override
18560    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18561        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18562        if (fromStackId == HOME_STACK_ID) {
18563            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18564        }
18565        synchronized (this) {
18566            final long origId = Binder.clearCallingIdentity();
18567            try {
18568                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18569            } finally {
18570                Binder.restoreCallingIdentity(origId);
18571            }
18572        }
18573    }
18574
18575    @Override
18576    public void updatePersistentConfiguration(Configuration values) {
18577        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18578                "updateConfiguration()");
18579        enforceWriteSettingsPermission("updateConfiguration()");
18580        if (values == null) {
18581            throw new NullPointerException("Configuration must not be null");
18582        }
18583
18584        int userId = UserHandle.getCallingUserId();
18585
18586        synchronized(this) {
18587            final long origId = Binder.clearCallingIdentity();
18588            updateConfigurationLocked(values, null, false, true, userId);
18589            Binder.restoreCallingIdentity(origId);
18590        }
18591    }
18592
18593    private void updateFontScaleIfNeeded() {
18594        final int currentUserId;
18595        synchronized(this) {
18596            currentUserId = mUserController.getCurrentUserIdLocked();
18597        }
18598        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18599                FONT_SCALE, 1.0f, currentUserId);
18600        if (mConfiguration.fontScale != scaleFactor) {
18601            final Configuration configuration = mWindowManager.computeNewConfiguration();
18602            configuration.fontScale = scaleFactor;
18603            updatePersistentConfiguration(configuration);
18604        }
18605    }
18606
18607    private void enforceWriteSettingsPermission(String func) {
18608        int uid = Binder.getCallingUid();
18609        if (uid == Process.ROOT_UID) {
18610            return;
18611        }
18612
18613        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18614                Settings.getPackageNameForUid(mContext, uid), false)) {
18615            return;
18616        }
18617
18618        String msg = "Permission Denial: " + func + " from pid="
18619                + Binder.getCallingPid()
18620                + ", uid=" + uid
18621                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18622        Slog.w(TAG, msg);
18623        throw new SecurityException(msg);
18624    }
18625
18626    public void updateConfiguration(Configuration values) {
18627        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18628                "updateConfiguration()");
18629
18630        synchronized(this) {
18631            if (values == null && mWindowManager != null) {
18632                // sentinel: fetch the current configuration from the window manager
18633                values = mWindowManager.computeNewConfiguration();
18634            }
18635
18636            if (mWindowManager != null) {
18637                mProcessList.applyDisplaySize(mWindowManager);
18638            }
18639
18640            final long origId = Binder.clearCallingIdentity();
18641            if (values != null) {
18642                Settings.System.clearConfiguration(values);
18643            }
18644            updateConfigurationLocked(values, null, false);
18645            Binder.restoreCallingIdentity(origId);
18646        }
18647    }
18648
18649    void updateUserConfigurationLocked() {
18650        Configuration configuration = new Configuration(mConfiguration);
18651        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18652                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18653        updateConfigurationLocked(configuration, null, false);
18654    }
18655
18656    boolean updateConfigurationLocked(Configuration values,
18657            ActivityRecord starting, boolean initLocale) {
18658        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18659        return updateConfigurationLocked(values, starting, initLocale, false,
18660                UserHandle.USER_NULL);
18661    }
18662
18663    // To cache the list of supported system locales
18664    private String[] mSupportedSystemLocales = null;
18665
18666    /**
18667     * Do either or both things: (1) change the current configuration, and (2)
18668     * make sure the given activity is running with the (now) current
18669     * configuration.  Returns true if the activity has been left running, or
18670     * false if <var>starting</var> is being destroyed to match the new
18671     * configuration.
18672     *
18673     * @param userId is only used when persistent parameter is set to true to persist configuration
18674     *               for that particular user
18675     */
18676    private boolean updateConfigurationLocked(Configuration values,
18677            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18678        int changes = 0;
18679
18680        if (mWindowManager != null) {
18681            mWindowManager.deferSurfaceLayout();
18682        }
18683        if (values != null) {
18684            Configuration newConfig = new Configuration(mConfiguration);
18685            changes = newConfig.updateFrom(values);
18686            if (changes != 0) {
18687                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18688                        "Updating configuration to: " + values);
18689
18690                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18691
18692                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18693                    final LocaleList locales = values.getLocales();
18694                    int bestLocaleIndex = 0;
18695                    if (locales.size() > 1) {
18696                        if (mSupportedSystemLocales == null) {
18697                            mSupportedSystemLocales =
18698                                    Resources.getSystem().getAssets().getLocales();
18699                        }
18700                        bestLocaleIndex = Math.max(0,
18701                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18702                    }
18703                    SystemProperties.set("persist.sys.locale",
18704                            locales.get(bestLocaleIndex).toLanguageTag());
18705                    LocaleList.setDefault(locales, bestLocaleIndex);
18706                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18707                            locales.get(bestLocaleIndex)));
18708                }
18709
18710                mConfigurationSeq++;
18711                if (mConfigurationSeq <= 0) {
18712                    mConfigurationSeq = 1;
18713                }
18714                newConfig.seq = mConfigurationSeq;
18715                mConfiguration = newConfig;
18716                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18717                mUsageStatsService.reportConfigurationChange(newConfig,
18718                        mUserController.getCurrentUserIdLocked());
18719                //mUsageStatsService.noteStartConfig(newConfig);
18720
18721                final Configuration configCopy = new Configuration(mConfiguration);
18722
18723                // TODO: If our config changes, should we auto dismiss any currently
18724                // showing dialogs?
18725                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18726
18727                AttributeCache ac = AttributeCache.instance();
18728                if (ac != null) {
18729                    ac.updateConfiguration(configCopy);
18730                }
18731
18732                // Make sure all resources in our process are updated
18733                // right now, so that anyone who is going to retrieve
18734                // resource values after we return will be sure to get
18735                // the new ones.  This is especially important during
18736                // boot, where the first config change needs to guarantee
18737                // all resources have that config before following boot
18738                // code is executed.
18739                mSystemThread.applyConfigurationToResources(configCopy);
18740
18741                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18742                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18743                    msg.obj = new Configuration(configCopy);
18744                    msg.arg1 = userId;
18745                    mHandler.sendMessage(msg);
18746                }
18747
18748                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18749                if (isDensityChange) {
18750                    // Reset the unsupported display size dialog.
18751                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18752
18753                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18754                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18755                }
18756
18757                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18758                    ProcessRecord app = mLruProcesses.get(i);
18759                    try {
18760                        if (app.thread != null) {
18761                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18762                                    + app.processName + " new config " + mConfiguration);
18763                            app.thread.scheduleConfigurationChanged(configCopy);
18764                        }
18765                    } catch (Exception e) {
18766                    }
18767                }
18768                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18769                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18770                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18771                        | Intent.FLAG_RECEIVER_FOREGROUND);
18772                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18773                        null, AppOpsManager.OP_NONE, null, false, false,
18774                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18775                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18776                    // Tell the shortcut manager that the system locale changed.  It needs to know
18777                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18778                    // we "push" from here, rather than having the service listen to the broadcast.
18779                    final ShortcutServiceInternal shortcutService =
18780                            LocalServices.getService(ShortcutServiceInternal.class);
18781                    if (shortcutService != null) {
18782                        shortcutService.onSystemLocaleChangedNoLock();
18783                    }
18784
18785                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18786                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18787                    if (!mProcessesReady) {
18788                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18789                    }
18790                    broadcastIntentLocked(null, null, intent,
18791                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18792                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18793                }
18794            }
18795            // Update the configuration with WM first and check if any of the stacks need to be
18796            // resized due to the configuration change. If so, resize the stacks now and do any
18797            // relaunches if necessary. This way we don't need to relaunch again below in
18798            // ensureActivityConfigurationLocked().
18799            if (mWindowManager != null) {
18800                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18801                if (resizedStacks != null) {
18802                    for (int stackId : resizedStacks) {
18803                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18804                        mStackSupervisor.resizeStackLocked(
18805                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18806                    }
18807                }
18808            }
18809        }
18810
18811        boolean kept = true;
18812        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18813        // mainStack is null during startup.
18814        if (mainStack != null) {
18815            if (changes != 0 && starting == null) {
18816                // If the configuration changed, and the caller is not already
18817                // in the process of starting an activity, then find the top
18818                // activity to check if its configuration needs to change.
18819                starting = mainStack.topRunningActivityLocked();
18820            }
18821
18822            if (starting != null) {
18823                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18824                // And we need to make sure at this point that all other activities
18825                // are made visible with the correct configuration.
18826                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18827                        !PRESERVE_WINDOWS);
18828            }
18829        }
18830        if (mWindowManager != null) {
18831            mWindowManager.continueSurfaceLayout();
18832        }
18833        return kept;
18834    }
18835
18836    /**
18837     * Decide based on the configuration whether we should shouw the ANR,
18838     * crash, etc dialogs.  The idea is that if there is no affordnace to
18839     * press the on-screen buttons, we shouldn't show the dialog.
18840     *
18841     * A thought: SystemUI might also want to get told about this, the Power
18842     * dialog / global actions also might want different behaviors.
18843     */
18844    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18845        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18846                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18847                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18848        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18849                                    == Configuration.UI_MODE_TYPE_CAR);
18850        return inputMethodExists && uiIsNotCarType && !inVrMode;
18851    }
18852
18853    @Override
18854    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18855        synchronized (this) {
18856            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18857            if (srec != null) {
18858                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18859            }
18860        }
18861        return false;
18862    }
18863
18864    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18865            Intent resultData) {
18866
18867        synchronized (this) {
18868            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18869            if (r != null) {
18870                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18871            }
18872            return false;
18873        }
18874    }
18875
18876    public int getLaunchedFromUid(IBinder activityToken) {
18877        ActivityRecord srec;
18878        synchronized (this) {
18879            srec = ActivityRecord.forTokenLocked(activityToken);
18880        }
18881        if (srec == null) {
18882            return -1;
18883        }
18884        return srec.launchedFromUid;
18885    }
18886
18887    public String getLaunchedFromPackage(IBinder activityToken) {
18888        ActivityRecord srec;
18889        synchronized (this) {
18890            srec = ActivityRecord.forTokenLocked(activityToken);
18891        }
18892        if (srec == null) {
18893            return null;
18894        }
18895        return srec.launchedFromPackage;
18896    }
18897
18898    // =========================================================
18899    // LIFETIME MANAGEMENT
18900    // =========================================================
18901
18902    // Returns which broadcast queue the app is the current [or imminent] receiver
18903    // on, or 'null' if the app is not an active broadcast recipient.
18904    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18905        BroadcastRecord r = app.curReceiver;
18906        if (r != null) {
18907            return r.queue;
18908        }
18909
18910        // It's not the current receiver, but it might be starting up to become one
18911        synchronized (this) {
18912            for (BroadcastQueue queue : mBroadcastQueues) {
18913                r = queue.mPendingBroadcast;
18914                if (r != null && r.curApp == app) {
18915                    // found it; report which queue it's in
18916                    return queue;
18917                }
18918            }
18919        }
18920
18921        return null;
18922    }
18923
18924    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18925            int targetUid, ComponentName targetComponent, String targetProcess) {
18926        if (!mTrackingAssociations) {
18927            return null;
18928        }
18929        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18930                = mAssociations.get(targetUid);
18931        if (components == null) {
18932            components = new ArrayMap<>();
18933            mAssociations.put(targetUid, components);
18934        }
18935        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18936        if (sourceUids == null) {
18937            sourceUids = new SparseArray<>();
18938            components.put(targetComponent, sourceUids);
18939        }
18940        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18941        if (sourceProcesses == null) {
18942            sourceProcesses = new ArrayMap<>();
18943            sourceUids.put(sourceUid, sourceProcesses);
18944        }
18945        Association ass = sourceProcesses.get(sourceProcess);
18946        if (ass == null) {
18947            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18948                    targetProcess);
18949            sourceProcesses.put(sourceProcess, ass);
18950        }
18951        ass.mCount++;
18952        ass.mNesting++;
18953        if (ass.mNesting == 1) {
18954            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18955            ass.mLastState = sourceState;
18956        }
18957        return ass;
18958    }
18959
18960    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18961            ComponentName targetComponent) {
18962        if (!mTrackingAssociations) {
18963            return;
18964        }
18965        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18966                = mAssociations.get(targetUid);
18967        if (components == null) {
18968            return;
18969        }
18970        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18971        if (sourceUids == null) {
18972            return;
18973        }
18974        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18975        if (sourceProcesses == null) {
18976            return;
18977        }
18978        Association ass = sourceProcesses.get(sourceProcess);
18979        if (ass == null || ass.mNesting <= 0) {
18980            return;
18981        }
18982        ass.mNesting--;
18983        if (ass.mNesting == 0) {
18984            long uptime = SystemClock.uptimeMillis();
18985            ass.mTime += uptime - ass.mStartTime;
18986            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18987                    += uptime - ass.mLastStateUptime;
18988            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18989        }
18990    }
18991
18992    private void noteUidProcessState(final int uid, final int state) {
18993        mBatteryStatsService.noteUidProcessState(uid, state);
18994        if (mTrackingAssociations) {
18995            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18996                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18997                        = mAssociations.valueAt(i1);
18998                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18999                    SparseArray<ArrayMap<String, Association>> sourceUids
19000                            = targetComponents.valueAt(i2);
19001                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19002                    if (sourceProcesses != null) {
19003                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19004                            Association ass = sourceProcesses.valueAt(i4);
19005                            if (ass.mNesting >= 1) {
19006                                // currently associated
19007                                long uptime = SystemClock.uptimeMillis();
19008                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19009                                        += uptime - ass.mLastStateUptime;
19010                                ass.mLastState = state;
19011                                ass.mLastStateUptime = uptime;
19012                            }
19013                        }
19014                    }
19015                }
19016            }
19017        }
19018    }
19019
19020    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19021            boolean doingAll, long now) {
19022        if (mAdjSeq == app.adjSeq) {
19023            // This adjustment has already been computed.
19024            return app.curRawAdj;
19025        }
19026
19027        if (app.thread == null) {
19028            app.adjSeq = mAdjSeq;
19029            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19030            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19031            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19032        }
19033
19034        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19035        app.adjSource = null;
19036        app.adjTarget = null;
19037        app.empty = false;
19038        app.cached = false;
19039
19040        final int activitiesSize = app.activities.size();
19041
19042        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19043            // The max adjustment doesn't allow this app to be anything
19044            // below foreground, so it is not worth doing work for it.
19045            app.adjType = "fixed";
19046            app.adjSeq = mAdjSeq;
19047            app.curRawAdj = app.maxAdj;
19048            app.foregroundActivities = false;
19049            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19050            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19051            // System processes can do UI, and when they do we want to have
19052            // them trim their memory after the user leaves the UI.  To
19053            // facilitate this, here we need to determine whether or not it
19054            // is currently showing UI.
19055            app.systemNoUi = true;
19056            if (app == TOP_APP) {
19057                app.systemNoUi = false;
19058                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19059                app.adjType = "pers-top-activity";
19060            } else if (activitiesSize > 0) {
19061                for (int j = 0; j < activitiesSize; j++) {
19062                    final ActivityRecord r = app.activities.get(j);
19063                    if (r.visible) {
19064                        app.systemNoUi = false;
19065                    }
19066                }
19067            }
19068            if (!app.systemNoUi) {
19069                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19070            }
19071            return (app.curAdj=app.maxAdj);
19072        }
19073
19074        app.systemNoUi = false;
19075
19076        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19077
19078        // Determine the importance of the process, starting with most
19079        // important to least, and assign an appropriate OOM adjustment.
19080        int adj;
19081        int schedGroup;
19082        int procState;
19083        boolean foregroundActivities = false;
19084        BroadcastQueue queue;
19085        if (app == TOP_APP) {
19086            // The last app on the list is the foreground app.
19087            adj = ProcessList.FOREGROUND_APP_ADJ;
19088            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19089            app.adjType = "top-activity";
19090            foregroundActivities = true;
19091            procState = PROCESS_STATE_CUR_TOP;
19092        } else if (app.instrumentationClass != null) {
19093            // Don't want to kill running instrumentation.
19094            adj = ProcessList.FOREGROUND_APP_ADJ;
19095            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19096            app.adjType = "instrumentation";
19097            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19098        } else if ((queue = isReceivingBroadcast(app)) != null) {
19099            // An app that is currently receiving a broadcast also
19100            // counts as being in the foreground for OOM killer purposes.
19101            // It's placed in a sched group based on the nature of the
19102            // broadcast as reflected by which queue it's active in.
19103            adj = ProcessList.FOREGROUND_APP_ADJ;
19104            schedGroup = (queue == mFgBroadcastQueue)
19105                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19106            app.adjType = "broadcast";
19107            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19108        } else if (app.executingServices.size() > 0) {
19109            // An app that is currently executing a service callback also
19110            // counts as being in the foreground.
19111            adj = ProcessList.FOREGROUND_APP_ADJ;
19112            schedGroup = app.execServicesFg ?
19113                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19114            app.adjType = "exec-service";
19115            procState = ActivityManager.PROCESS_STATE_SERVICE;
19116            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19117        } else {
19118            // As far as we know the process is empty.  We may change our mind later.
19119            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19120            // At this point we don't actually know the adjustment.  Use the cached adj
19121            // value that the caller wants us to.
19122            adj = cachedAdj;
19123            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19124            app.cached = true;
19125            app.empty = true;
19126            app.adjType = "cch-empty";
19127        }
19128
19129        // Examine all activities if not already foreground.
19130        if (!foregroundActivities && activitiesSize > 0) {
19131            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19132            for (int j = 0; j < activitiesSize; j++) {
19133                final ActivityRecord r = app.activities.get(j);
19134                if (r.app != app) {
19135                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19136                            + " instead of expected " + app);
19137                    if (r.app == null || (r.app.uid == app.uid)) {
19138                        // Only fix things up when they look sane
19139                        r.app = app;
19140                    } else {
19141                        continue;
19142                    }
19143                }
19144                if (r.visible) {
19145                    // App has a visible activity; only upgrade adjustment.
19146                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19147                        adj = ProcessList.VISIBLE_APP_ADJ;
19148                        app.adjType = "visible";
19149                    }
19150                    if (procState > PROCESS_STATE_CUR_TOP) {
19151                        procState = PROCESS_STATE_CUR_TOP;
19152                    }
19153                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19154                    app.cached = false;
19155                    app.empty = false;
19156                    foregroundActivities = true;
19157                    if (r.task != null && minLayer > 0) {
19158                        final int layer = r.task.mLayerRank;
19159                        if (layer >= 0 && minLayer > layer) {
19160                            minLayer = layer;
19161                        }
19162                    }
19163                    break;
19164                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19165                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19166                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19167                        app.adjType = "pausing";
19168                    }
19169                    if (procState > PROCESS_STATE_CUR_TOP) {
19170                        procState = PROCESS_STATE_CUR_TOP;
19171                    }
19172                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19173                    app.cached = false;
19174                    app.empty = false;
19175                    foregroundActivities = true;
19176                } else if (r.state == ActivityState.STOPPING) {
19177                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19178                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19179                        app.adjType = "stopping";
19180                    }
19181                    // For the process state, we will at this point consider the
19182                    // process to be cached.  It will be cached either as an activity
19183                    // or empty depending on whether the activity is finishing.  We do
19184                    // this so that we can treat the process as cached for purposes of
19185                    // memory trimming (determing current memory level, trim command to
19186                    // send to process) since there can be an arbitrary number of stopping
19187                    // processes and they should soon all go into the cached state.
19188                    if (!r.finishing) {
19189                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19190                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19191                        }
19192                    }
19193                    app.cached = false;
19194                    app.empty = false;
19195                    foregroundActivities = true;
19196                } else {
19197                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19198                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19199                        app.adjType = "cch-act";
19200                    }
19201                }
19202            }
19203            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19204                adj += minLayer;
19205            }
19206        }
19207
19208        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19209                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19210            if (app.foregroundServices) {
19211                // The user is aware of this app, so make it visible.
19212                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19213                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19214                app.cached = false;
19215                app.adjType = "fg-service";
19216                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19217            } else if (app.forcingToForeground != null) {
19218                // The user is aware of this app, so make it visible.
19219                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19220                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19221                app.cached = false;
19222                app.adjType = "force-fg";
19223                app.adjSource = app.forcingToForeground;
19224                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19225            }
19226        }
19227
19228        if (app == mHeavyWeightProcess) {
19229            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19230                // We don't want to kill the current heavy-weight process.
19231                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19232                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19233                app.cached = false;
19234                app.adjType = "heavy";
19235            }
19236            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19237                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19238            }
19239        }
19240
19241        if (app == mHomeProcess) {
19242            if (adj > ProcessList.HOME_APP_ADJ) {
19243                // This process is hosting what we currently consider to be the
19244                // home app, so we don't want to let it go into the background.
19245                adj = ProcessList.HOME_APP_ADJ;
19246                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19247                app.cached = false;
19248                app.adjType = "home";
19249            }
19250            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19251                procState = ActivityManager.PROCESS_STATE_HOME;
19252            }
19253        }
19254
19255        if (app == mPreviousProcess && app.activities.size() > 0) {
19256            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19257                // This was the previous process that showed UI to the user.
19258                // We want to try to keep it around more aggressively, to give
19259                // a good experience around switching between two apps.
19260                adj = ProcessList.PREVIOUS_APP_ADJ;
19261                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19262                app.cached = false;
19263                app.adjType = "previous";
19264            }
19265            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19266                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19267            }
19268        }
19269
19270        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19271                + " reason=" + app.adjType);
19272
19273        // By default, we use the computed adjustment.  It may be changed if
19274        // there are applications dependent on our services or providers, but
19275        // this gives us a baseline and makes sure we don't get into an
19276        // infinite recursion.
19277        app.adjSeq = mAdjSeq;
19278        app.curRawAdj = adj;
19279        app.hasStartedServices = false;
19280
19281        if (mBackupTarget != null && app == mBackupTarget.app) {
19282            // If possible we want to avoid killing apps while they're being backed up
19283            if (adj > ProcessList.BACKUP_APP_ADJ) {
19284                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19285                adj = ProcessList.BACKUP_APP_ADJ;
19286                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19287                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19288                }
19289                app.adjType = "backup";
19290                app.cached = false;
19291            }
19292            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19293                procState = ActivityManager.PROCESS_STATE_BACKUP;
19294            }
19295        }
19296
19297        boolean mayBeTop = false;
19298
19299        for (int is = app.services.size()-1;
19300                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19301                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19302                        || procState > ActivityManager.PROCESS_STATE_TOP);
19303                is--) {
19304            ServiceRecord s = app.services.valueAt(is);
19305            if (s.startRequested) {
19306                app.hasStartedServices = true;
19307                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19308                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19309                }
19310                if (app.hasShownUi && app != mHomeProcess) {
19311                    // If this process has shown some UI, let it immediately
19312                    // go to the LRU list because it may be pretty heavy with
19313                    // UI stuff.  We'll tag it with a label just to help
19314                    // debug and understand what is going on.
19315                    if (adj > ProcessList.SERVICE_ADJ) {
19316                        app.adjType = "cch-started-ui-services";
19317                    }
19318                } else {
19319                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19320                        // This service has seen some activity within
19321                        // recent memory, so we will keep its process ahead
19322                        // of the background processes.
19323                        if (adj > ProcessList.SERVICE_ADJ) {
19324                            adj = ProcessList.SERVICE_ADJ;
19325                            app.adjType = "started-services";
19326                            app.cached = false;
19327                        }
19328                    }
19329                    // If we have let the service slide into the background
19330                    // state, still have some text describing what it is doing
19331                    // even though the service no longer has an impact.
19332                    if (adj > ProcessList.SERVICE_ADJ) {
19333                        app.adjType = "cch-started-services";
19334                    }
19335                }
19336            }
19337
19338            for (int conni = s.connections.size()-1;
19339                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19340                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19341                            || procState > ActivityManager.PROCESS_STATE_TOP);
19342                    conni--) {
19343                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19344                for (int i = 0;
19345                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19346                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19347                                || procState > ActivityManager.PROCESS_STATE_TOP);
19348                        i++) {
19349                    // XXX should compute this based on the max of
19350                    // all connected clients.
19351                    ConnectionRecord cr = clist.get(i);
19352                    if (cr.binding.client == app) {
19353                        // Binding to ourself is not interesting.
19354                        continue;
19355                    }
19356
19357                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19358                        ProcessRecord client = cr.binding.client;
19359                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19360                                TOP_APP, doingAll, now);
19361                        int clientProcState = client.curProcState;
19362                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19363                            // If the other app is cached for any reason, for purposes here
19364                            // we are going to consider it empty.  The specific cached state
19365                            // doesn't propagate except under certain conditions.
19366                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19367                        }
19368                        String adjType = null;
19369                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19370                            // Not doing bind OOM management, so treat
19371                            // this guy more like a started service.
19372                            if (app.hasShownUi && app != mHomeProcess) {
19373                                // If this process has shown some UI, let it immediately
19374                                // go to the LRU list because it may be pretty heavy with
19375                                // UI stuff.  We'll tag it with a label just to help
19376                                // debug and understand what is going on.
19377                                if (adj > clientAdj) {
19378                                    adjType = "cch-bound-ui-services";
19379                                }
19380                                app.cached = false;
19381                                clientAdj = adj;
19382                                clientProcState = procState;
19383                            } else {
19384                                if (now >= (s.lastActivity
19385                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19386                                    // This service has not seen activity within
19387                                    // recent memory, so allow it to drop to the
19388                                    // LRU list if there is no other reason to keep
19389                                    // it around.  We'll also tag it with a label just
19390                                    // to help debug and undertand what is going on.
19391                                    if (adj > clientAdj) {
19392                                        adjType = "cch-bound-services";
19393                                    }
19394                                    clientAdj = adj;
19395                                }
19396                            }
19397                        }
19398                        if (adj > clientAdj) {
19399                            // If this process has recently shown UI, and
19400                            // the process that is binding to it is less
19401                            // important than being visible, then we don't
19402                            // care about the binding as much as we care
19403                            // about letting this process get into the LRU
19404                            // list to be killed and restarted if needed for
19405                            // memory.
19406                            if (app.hasShownUi && app != mHomeProcess
19407                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19408                                adjType = "cch-bound-ui-services";
19409                            } else {
19410                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19411                                        |Context.BIND_IMPORTANT)) != 0) {
19412                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19413                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19414                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19415                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19416                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19417                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19418                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19419                                    adj = clientAdj;
19420                                } else {
19421                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19422                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19423                                    }
19424                                }
19425                                if (!client.cached) {
19426                                    app.cached = false;
19427                                }
19428                                adjType = "service";
19429                            }
19430                        }
19431                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19432                            // This will treat important bound services identically to
19433                            // the top app, which may behave differently than generic
19434                            // foreground work.
19435                            if (client.curSchedGroup > schedGroup) {
19436                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19437                                    schedGroup = client.curSchedGroup;
19438                                } else {
19439                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19440                                }
19441                            }
19442                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19443                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19444                                    // Special handling of clients who are in the top state.
19445                                    // We *may* want to consider this process to be in the
19446                                    // top state as well, but only if there is not another
19447                                    // reason for it to be running.  Being on the top is a
19448                                    // special state, meaning you are specifically running
19449                                    // for the current top app.  If the process is already
19450                                    // running in the background for some other reason, it
19451                                    // is more important to continue considering it to be
19452                                    // in the background state.
19453                                    mayBeTop = true;
19454                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19455                                } else {
19456                                    // Special handling for above-top states (persistent
19457                                    // processes).  These should not bring the current process
19458                                    // into the top state, since they are not on top.  Instead
19459                                    // give them the best state after that.
19460                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19461                                        clientProcState =
19462                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19463                                    } else if (mWakefulness
19464                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19465                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19466                                                    != 0) {
19467                                        clientProcState =
19468                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19469                                    } else {
19470                                        clientProcState =
19471                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19472                                    }
19473                                }
19474                            }
19475                        } else {
19476                            if (clientProcState <
19477                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19478                                clientProcState =
19479                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19480                            }
19481                        }
19482                        if (procState > clientProcState) {
19483                            procState = clientProcState;
19484                        }
19485                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19486                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19487                            app.pendingUiClean = true;
19488                        }
19489                        if (adjType != null) {
19490                            app.adjType = adjType;
19491                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19492                                    .REASON_SERVICE_IN_USE;
19493                            app.adjSource = cr.binding.client;
19494                            app.adjSourceProcState = clientProcState;
19495                            app.adjTarget = s.name;
19496                        }
19497                    }
19498                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19499                        app.treatLikeActivity = true;
19500                    }
19501                    final ActivityRecord a = cr.activity;
19502                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19503                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19504                            (a.visible || a.state == ActivityState.RESUMED ||
19505                             a.state == ActivityState.PAUSING)) {
19506                            adj = ProcessList.FOREGROUND_APP_ADJ;
19507                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19508                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19509                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19510                                } else {
19511                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19512                                }
19513                            }
19514                            app.cached = false;
19515                            app.adjType = "service";
19516                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19517                                    .REASON_SERVICE_IN_USE;
19518                            app.adjSource = a;
19519                            app.adjSourceProcState = procState;
19520                            app.adjTarget = s.name;
19521                        }
19522                    }
19523                }
19524            }
19525        }
19526
19527        for (int provi = app.pubProviders.size()-1;
19528                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19529                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19530                        || procState > ActivityManager.PROCESS_STATE_TOP);
19531                provi--) {
19532            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19533            for (int i = cpr.connections.size()-1;
19534                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19535                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19536                            || procState > ActivityManager.PROCESS_STATE_TOP);
19537                    i--) {
19538                ContentProviderConnection conn = cpr.connections.get(i);
19539                ProcessRecord client = conn.client;
19540                if (client == app) {
19541                    // Being our own client is not interesting.
19542                    continue;
19543                }
19544                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19545                int clientProcState = client.curProcState;
19546                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19547                    // If the other app is cached for any reason, for purposes here
19548                    // we are going to consider it empty.
19549                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19550                }
19551                if (adj > clientAdj) {
19552                    if (app.hasShownUi && app != mHomeProcess
19553                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19554                        app.adjType = "cch-ui-provider";
19555                    } else {
19556                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19557                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19558                        app.adjType = "provider";
19559                    }
19560                    app.cached &= client.cached;
19561                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19562                            .REASON_PROVIDER_IN_USE;
19563                    app.adjSource = client;
19564                    app.adjSourceProcState = clientProcState;
19565                    app.adjTarget = cpr.name;
19566                }
19567                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19568                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19569                        // Special handling of clients who are in the top state.
19570                        // We *may* want to consider this process to be in the
19571                        // top state as well, but only if there is not another
19572                        // reason for it to be running.  Being on the top is a
19573                        // special state, meaning you are specifically running
19574                        // for the current top app.  If the process is already
19575                        // running in the background for some other reason, it
19576                        // is more important to continue considering it to be
19577                        // in the background state.
19578                        mayBeTop = true;
19579                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19580                    } else {
19581                        // Special handling for above-top states (persistent
19582                        // processes).  These should not bring the current process
19583                        // into the top state, since they are not on top.  Instead
19584                        // give them the best state after that.
19585                        clientProcState =
19586                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19587                    }
19588                }
19589                if (procState > clientProcState) {
19590                    procState = clientProcState;
19591                }
19592                if (client.curSchedGroup > schedGroup) {
19593                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19594                }
19595            }
19596            // If the provider has external (non-framework) process
19597            // dependencies, ensure that its adjustment is at least
19598            // FOREGROUND_APP_ADJ.
19599            if (cpr.hasExternalProcessHandles()) {
19600                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19601                    adj = ProcessList.FOREGROUND_APP_ADJ;
19602                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19603                    app.cached = false;
19604                    app.adjType = "provider";
19605                    app.adjTarget = cpr.name;
19606                }
19607                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19608                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19609                }
19610            }
19611        }
19612
19613        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19614            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19615                adj = ProcessList.PREVIOUS_APP_ADJ;
19616                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19617                app.cached = false;
19618                app.adjType = "provider";
19619            }
19620            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19621                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19622            }
19623        }
19624
19625        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19626            // A client of one of our services or providers is in the top state.  We
19627            // *may* want to be in the top state, but not if we are already running in
19628            // the background for some other reason.  For the decision here, we are going
19629            // to pick out a few specific states that we want to remain in when a client
19630            // is top (states that tend to be longer-term) and otherwise allow it to go
19631            // to the top state.
19632            switch (procState) {
19633                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19634                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19635                case ActivityManager.PROCESS_STATE_SERVICE:
19636                    // These all are longer-term states, so pull them up to the top
19637                    // of the background states, but not all the way to the top state.
19638                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19639                    break;
19640                default:
19641                    // Otherwise, top is a better choice, so take it.
19642                    procState = ActivityManager.PROCESS_STATE_TOP;
19643                    break;
19644            }
19645        }
19646
19647        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19648            if (app.hasClientActivities) {
19649                // This is a cached process, but with client activities.  Mark it so.
19650                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19651                app.adjType = "cch-client-act";
19652            } else if (app.treatLikeActivity) {
19653                // This is a cached process, but somebody wants us to treat it like it has
19654                // an activity, okay!
19655                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19656                app.adjType = "cch-as-act";
19657            }
19658        }
19659
19660        if (adj == ProcessList.SERVICE_ADJ) {
19661            if (doingAll) {
19662                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19663                mNewNumServiceProcs++;
19664                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19665                if (!app.serviceb) {
19666                    // This service isn't far enough down on the LRU list to
19667                    // normally be a B service, but if we are low on RAM and it
19668                    // is large we want to force it down since we would prefer to
19669                    // keep launcher over it.
19670                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19671                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19672                        app.serviceHighRam = true;
19673                        app.serviceb = true;
19674                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19675                    } else {
19676                        mNewNumAServiceProcs++;
19677                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19678                    }
19679                } else {
19680                    app.serviceHighRam = false;
19681                }
19682            }
19683            if (app.serviceb) {
19684                adj = ProcessList.SERVICE_B_ADJ;
19685            }
19686        }
19687
19688        app.curRawAdj = adj;
19689
19690        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19691        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19692        if (adj > app.maxAdj) {
19693            adj = app.maxAdj;
19694            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19695                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19696            }
19697        }
19698
19699        // Do final modification to adj.  Everything we do between here and applying
19700        // the final setAdj must be done in this function, because we will also use
19701        // it when computing the final cached adj later.  Note that we don't need to
19702        // worry about this for max adj above, since max adj will always be used to
19703        // keep it out of the cached vaues.
19704        app.curAdj = app.modifyRawOomAdj(adj);
19705        app.curSchedGroup = schedGroup;
19706        app.curProcState = procState;
19707        app.foregroundActivities = foregroundActivities;
19708
19709        return app.curRawAdj;
19710    }
19711
19712    /**
19713     * Record new PSS sample for a process.
19714     */
19715    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19716            long now) {
19717        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19718                swapPss * 1024);
19719        proc.lastPssTime = now;
19720        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19721        if (DEBUG_PSS) Slog.d(TAG_PSS,
19722                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19723                + " state=" + ProcessList.makeProcStateString(procState));
19724        if (proc.initialIdlePss == 0) {
19725            proc.initialIdlePss = pss;
19726        }
19727        proc.lastPss = pss;
19728        proc.lastSwapPss = swapPss;
19729        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19730            proc.lastCachedPss = pss;
19731            proc.lastCachedSwapPss = swapPss;
19732        }
19733
19734        final SparseArray<Pair<Long, String>> watchUids
19735                = mMemWatchProcesses.getMap().get(proc.processName);
19736        Long check = null;
19737        if (watchUids != null) {
19738            Pair<Long, String> val = watchUids.get(proc.uid);
19739            if (val == null) {
19740                val = watchUids.get(0);
19741            }
19742            if (val != null) {
19743                check = val.first;
19744            }
19745        }
19746        if (check != null) {
19747            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19748                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19749                if (!isDebuggable) {
19750                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19751                        isDebuggable = true;
19752                    }
19753                }
19754                if (isDebuggable) {
19755                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19756                    final ProcessRecord myProc = proc;
19757                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19758                    mMemWatchDumpProcName = proc.processName;
19759                    mMemWatchDumpFile = heapdumpFile.toString();
19760                    mMemWatchDumpPid = proc.pid;
19761                    mMemWatchDumpUid = proc.uid;
19762                    BackgroundThread.getHandler().post(new Runnable() {
19763                        @Override
19764                        public void run() {
19765                            revokeUriPermission(ActivityThread.currentActivityThread()
19766                                            .getApplicationThread(),
19767                                    DumpHeapActivity.JAVA_URI,
19768                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19769                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19770                                    UserHandle.myUserId());
19771                            ParcelFileDescriptor fd = null;
19772                            try {
19773                                heapdumpFile.delete();
19774                                fd = ParcelFileDescriptor.open(heapdumpFile,
19775                                        ParcelFileDescriptor.MODE_CREATE |
19776                                                ParcelFileDescriptor.MODE_TRUNCATE |
19777                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19778                                                ParcelFileDescriptor.MODE_APPEND);
19779                                IApplicationThread thread = myProc.thread;
19780                                if (thread != null) {
19781                                    try {
19782                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19783                                                "Requesting dump heap from "
19784                                                + myProc + " to " + heapdumpFile);
19785                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19786                                    } catch (RemoteException e) {
19787                                    }
19788                                }
19789                            } catch (FileNotFoundException e) {
19790                                e.printStackTrace();
19791                            } finally {
19792                                if (fd != null) {
19793                                    try {
19794                                        fd.close();
19795                                    } catch (IOException e) {
19796                                    }
19797                                }
19798                            }
19799                        }
19800                    });
19801                } else {
19802                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19803                            + ", but debugging not enabled");
19804                }
19805            }
19806        }
19807    }
19808
19809    /**
19810     * Schedule PSS collection of a process.
19811     */
19812    void requestPssLocked(ProcessRecord proc, int procState) {
19813        if (mPendingPssProcesses.contains(proc)) {
19814            return;
19815        }
19816        if (mPendingPssProcesses.size() == 0) {
19817            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19818        }
19819        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19820        proc.pssProcState = procState;
19821        mPendingPssProcesses.add(proc);
19822    }
19823
19824    /**
19825     * Schedule PSS collection of all processes.
19826     */
19827    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19828        if (!always) {
19829            if (now < (mLastFullPssTime +
19830                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19831                return;
19832            }
19833        }
19834        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19835        mLastFullPssTime = now;
19836        mFullPssPending = true;
19837        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19838        mPendingPssProcesses.clear();
19839        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19840            ProcessRecord app = mLruProcesses.get(i);
19841            if (app.thread == null
19842                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19843                continue;
19844            }
19845            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19846                app.pssProcState = app.setProcState;
19847                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19848                        mTestPssMode, isSleepingLocked(), now);
19849                mPendingPssProcesses.add(app);
19850            }
19851        }
19852        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19853    }
19854
19855    public void setTestPssMode(boolean enabled) {
19856        synchronized (this) {
19857            mTestPssMode = enabled;
19858            if (enabled) {
19859                // Whenever we enable the mode, we want to take a snapshot all of current
19860                // process mem use.
19861                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19862            }
19863        }
19864    }
19865
19866    /**
19867     * Ask a given process to GC right now.
19868     */
19869    final void performAppGcLocked(ProcessRecord app) {
19870        try {
19871            app.lastRequestedGc = SystemClock.uptimeMillis();
19872            if (app.thread != null) {
19873                if (app.reportLowMemory) {
19874                    app.reportLowMemory = false;
19875                    app.thread.scheduleLowMemory();
19876                } else {
19877                    app.thread.processInBackground();
19878                }
19879            }
19880        } catch (Exception e) {
19881            // whatever.
19882        }
19883    }
19884
19885    /**
19886     * Returns true if things are idle enough to perform GCs.
19887     */
19888    private final boolean canGcNowLocked() {
19889        boolean processingBroadcasts = false;
19890        for (BroadcastQueue q : mBroadcastQueues) {
19891            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19892                processingBroadcasts = true;
19893            }
19894        }
19895        return !processingBroadcasts
19896                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19897    }
19898
19899    /**
19900     * Perform GCs on all processes that are waiting for it, but only
19901     * if things are idle.
19902     */
19903    final void performAppGcsLocked() {
19904        final int N = mProcessesToGc.size();
19905        if (N <= 0) {
19906            return;
19907        }
19908        if (canGcNowLocked()) {
19909            while (mProcessesToGc.size() > 0) {
19910                ProcessRecord proc = mProcessesToGc.remove(0);
19911                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19912                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19913                            <= SystemClock.uptimeMillis()) {
19914                        // To avoid spamming the system, we will GC processes one
19915                        // at a time, waiting a few seconds between each.
19916                        performAppGcLocked(proc);
19917                        scheduleAppGcsLocked();
19918                        return;
19919                    } else {
19920                        // It hasn't been long enough since we last GCed this
19921                        // process...  put it in the list to wait for its time.
19922                        addProcessToGcListLocked(proc);
19923                        break;
19924                    }
19925                }
19926            }
19927
19928            scheduleAppGcsLocked();
19929        }
19930    }
19931
19932    /**
19933     * If all looks good, perform GCs on all processes waiting for them.
19934     */
19935    final void performAppGcsIfAppropriateLocked() {
19936        if (canGcNowLocked()) {
19937            performAppGcsLocked();
19938            return;
19939        }
19940        // Still not idle, wait some more.
19941        scheduleAppGcsLocked();
19942    }
19943
19944    /**
19945     * Schedule the execution of all pending app GCs.
19946     */
19947    final void scheduleAppGcsLocked() {
19948        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19949
19950        if (mProcessesToGc.size() > 0) {
19951            // Schedule a GC for the time to the next process.
19952            ProcessRecord proc = mProcessesToGc.get(0);
19953            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19954
19955            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19956            long now = SystemClock.uptimeMillis();
19957            if (when < (now+GC_TIMEOUT)) {
19958                when = now + GC_TIMEOUT;
19959            }
19960            mHandler.sendMessageAtTime(msg, when);
19961        }
19962    }
19963
19964    /**
19965     * Add a process to the array of processes waiting to be GCed.  Keeps the
19966     * list in sorted order by the last GC time.  The process can't already be
19967     * on the list.
19968     */
19969    final void addProcessToGcListLocked(ProcessRecord proc) {
19970        boolean added = false;
19971        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19972            if (mProcessesToGc.get(i).lastRequestedGc <
19973                    proc.lastRequestedGc) {
19974                added = true;
19975                mProcessesToGc.add(i+1, proc);
19976                break;
19977            }
19978        }
19979        if (!added) {
19980            mProcessesToGc.add(0, proc);
19981        }
19982    }
19983
19984    /**
19985     * Set up to ask a process to GC itself.  This will either do it
19986     * immediately, or put it on the list of processes to gc the next
19987     * time things are idle.
19988     */
19989    final void scheduleAppGcLocked(ProcessRecord app) {
19990        long now = SystemClock.uptimeMillis();
19991        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19992            return;
19993        }
19994        if (!mProcessesToGc.contains(app)) {
19995            addProcessToGcListLocked(app);
19996            scheduleAppGcsLocked();
19997        }
19998    }
19999
20000    final void checkExcessivePowerUsageLocked(boolean doKills) {
20001        updateCpuStatsNow();
20002
20003        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20004        boolean doWakeKills = doKills;
20005        boolean doCpuKills = doKills;
20006        if (mLastPowerCheckRealtime == 0) {
20007            doWakeKills = false;
20008        }
20009        if (mLastPowerCheckUptime == 0) {
20010            doCpuKills = false;
20011        }
20012        if (stats.isScreenOn()) {
20013            doWakeKills = false;
20014        }
20015        final long curRealtime = SystemClock.elapsedRealtime();
20016        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20017        final long curUptime = SystemClock.uptimeMillis();
20018        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20019        mLastPowerCheckRealtime = curRealtime;
20020        mLastPowerCheckUptime = curUptime;
20021        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20022            doWakeKills = false;
20023        }
20024        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20025            doCpuKills = false;
20026        }
20027        int i = mLruProcesses.size();
20028        while (i > 0) {
20029            i--;
20030            ProcessRecord app = mLruProcesses.get(i);
20031            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20032                long wtime;
20033                synchronized (stats) {
20034                    wtime = stats.getProcessWakeTime(app.info.uid,
20035                            app.pid, curRealtime);
20036                }
20037                long wtimeUsed = wtime - app.lastWakeTime;
20038                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20039                if (DEBUG_POWER) {
20040                    StringBuilder sb = new StringBuilder(128);
20041                    sb.append("Wake for ");
20042                    app.toShortString(sb);
20043                    sb.append(": over ");
20044                    TimeUtils.formatDuration(realtimeSince, sb);
20045                    sb.append(" used ");
20046                    TimeUtils.formatDuration(wtimeUsed, sb);
20047                    sb.append(" (");
20048                    sb.append((wtimeUsed*100)/realtimeSince);
20049                    sb.append("%)");
20050                    Slog.i(TAG_POWER, sb.toString());
20051                    sb.setLength(0);
20052                    sb.append("CPU for ");
20053                    app.toShortString(sb);
20054                    sb.append(": over ");
20055                    TimeUtils.formatDuration(uptimeSince, sb);
20056                    sb.append(" used ");
20057                    TimeUtils.formatDuration(cputimeUsed, sb);
20058                    sb.append(" (");
20059                    sb.append((cputimeUsed*100)/uptimeSince);
20060                    sb.append("%)");
20061                    Slog.i(TAG_POWER, sb.toString());
20062                }
20063                // If a process has held a wake lock for more
20064                // than 50% of the time during this period,
20065                // that sounds bad.  Kill!
20066                if (doWakeKills && realtimeSince > 0
20067                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20068                    synchronized (stats) {
20069                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20070                                realtimeSince, wtimeUsed);
20071                    }
20072                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20073                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20074                } else if (doCpuKills && uptimeSince > 0
20075                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20076                    synchronized (stats) {
20077                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20078                                uptimeSince, cputimeUsed);
20079                    }
20080                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20081                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20082                } else {
20083                    app.lastWakeTime = wtime;
20084                    app.lastCpuTime = app.curCpuTime;
20085                }
20086            }
20087        }
20088    }
20089
20090    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20091            long nowElapsed) {
20092        boolean success = true;
20093
20094        if (app.curRawAdj != app.setRawAdj) {
20095            app.setRawAdj = app.curRawAdj;
20096        }
20097
20098        int changes = 0;
20099
20100        if (app.curAdj != app.setAdj) {
20101            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20102            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20103                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20104                    + app.adjType);
20105            app.setAdj = app.curAdj;
20106            app.verifiedAdj = ProcessList.INVALID_ADJ;
20107        }
20108
20109        if (app.setSchedGroup != app.curSchedGroup) {
20110            app.setSchedGroup = app.curSchedGroup;
20111            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20112                    "Setting sched group of " + app.processName
20113                    + " to " + app.curSchedGroup);
20114            if (app.waitingToKill != null && app.curReceiver == null
20115                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20116                app.kill(app.waitingToKill, true);
20117                success = false;
20118            } else {
20119                int processGroup;
20120                switch (app.curSchedGroup) {
20121                    case ProcessList.SCHED_GROUP_BACKGROUND:
20122                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20123                        break;
20124                    case ProcessList.SCHED_GROUP_TOP_APP:
20125                        processGroup = Process.THREAD_GROUP_TOP_APP;
20126                        break;
20127                    default:
20128                        processGroup = Process.THREAD_GROUP_DEFAULT;
20129                        break;
20130                }
20131                if (true) {
20132                    long oldId = Binder.clearCallingIdentity();
20133                    try {
20134                        Process.setProcessGroup(app.pid, processGroup);
20135                    } catch (Exception e) {
20136                        Slog.w(TAG, "Failed setting process group of " + app.pid
20137                                + " to " + app.curSchedGroup);
20138                        e.printStackTrace();
20139                    } finally {
20140                        Binder.restoreCallingIdentity(oldId);
20141                    }
20142                } else {
20143                    if (app.thread != null) {
20144                        try {
20145                            app.thread.setSchedulingGroup(processGroup);
20146                        } catch (RemoteException e) {
20147                        }
20148                    }
20149                }
20150            }
20151        }
20152        if (app.repForegroundActivities != app.foregroundActivities) {
20153            app.repForegroundActivities = app.foregroundActivities;
20154            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20155        }
20156        if (app.repProcState != app.curProcState) {
20157            app.repProcState = app.curProcState;
20158            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20159            if (app.thread != null) {
20160                try {
20161                    if (false) {
20162                        //RuntimeException h = new RuntimeException("here");
20163                        Slog.i(TAG, "Sending new process state " + app.repProcState
20164                                + " to " + app /*, h*/);
20165                    }
20166                    app.thread.setProcessState(app.repProcState);
20167                } catch (RemoteException e) {
20168                }
20169            }
20170        }
20171        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20172                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20173            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20174                // Experimental code to more aggressively collect pss while
20175                // running test...  the problem is that this tends to collect
20176                // the data right when a process is transitioning between process
20177                // states, which well tend to give noisy data.
20178                long start = SystemClock.uptimeMillis();
20179                long pss = Debug.getPss(app.pid, mTmpLong, null);
20180                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20181                mPendingPssProcesses.remove(app);
20182                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20183                        + " to " + app.curProcState + ": "
20184                        + (SystemClock.uptimeMillis()-start) + "ms");
20185            }
20186            app.lastStateTime = now;
20187            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20188                    mTestPssMode, isSleepingLocked(), now);
20189            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20190                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20191                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20192                    + (app.nextPssTime-now) + ": " + app);
20193        } else {
20194            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20195                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20196                    mTestPssMode)))) {
20197                requestPssLocked(app, app.setProcState);
20198                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20199                        mTestPssMode, isSleepingLocked(), now);
20200            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20201                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20202        }
20203        if (app.setProcState != app.curProcState) {
20204            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20205                    "Proc state change of " + app.processName
20206                            + " to " + app.curProcState);
20207            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20208            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20209            if (setImportant && !curImportant) {
20210                // This app is no longer something we consider important enough to allow to
20211                // use arbitrary amounts of battery power.  Note
20212                // its current wake lock time to later know to kill it if
20213                // it is not behaving well.
20214                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20215                synchronized (stats) {
20216                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20217                            app.pid, nowElapsed);
20218                }
20219                app.lastCpuTime = app.curCpuTime;
20220
20221            }
20222            // Inform UsageStats of important process state change
20223            // Must be called before updating setProcState
20224            maybeUpdateUsageStatsLocked(app, nowElapsed);
20225
20226            app.setProcState = app.curProcState;
20227            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20228                app.notCachedSinceIdle = false;
20229            }
20230            if (!doingAll) {
20231                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20232            } else {
20233                app.procStateChanged = true;
20234            }
20235        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20236                > USAGE_STATS_INTERACTION_INTERVAL) {
20237            // For apps that sit around for a long time in the interactive state, we need
20238            // to report this at least once a day so they don't go idle.
20239            maybeUpdateUsageStatsLocked(app, nowElapsed);
20240        }
20241
20242        if (changes != 0) {
20243            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20244                    "Changes in " + app + ": " + changes);
20245            int i = mPendingProcessChanges.size()-1;
20246            ProcessChangeItem item = null;
20247            while (i >= 0) {
20248                item = mPendingProcessChanges.get(i);
20249                if (item.pid == app.pid) {
20250                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20251                            "Re-using existing item: " + item);
20252                    break;
20253                }
20254                i--;
20255            }
20256            if (i < 0) {
20257                // No existing item in pending changes; need a new one.
20258                final int NA = mAvailProcessChanges.size();
20259                if (NA > 0) {
20260                    item = mAvailProcessChanges.remove(NA-1);
20261                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20262                            "Retrieving available item: " + item);
20263                } else {
20264                    item = new ProcessChangeItem();
20265                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20266                            "Allocating new item: " + item);
20267                }
20268                item.changes = 0;
20269                item.pid = app.pid;
20270                item.uid = app.info.uid;
20271                if (mPendingProcessChanges.size() == 0) {
20272                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20273                            "*** Enqueueing dispatch processes changed!");
20274                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20275                }
20276                mPendingProcessChanges.add(item);
20277            }
20278            item.changes |= changes;
20279            item.processState = app.repProcState;
20280            item.foregroundActivities = app.repForegroundActivities;
20281            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20282                    "Item " + Integer.toHexString(System.identityHashCode(item))
20283                    + " " + app.toShortString() + ": changes=" + item.changes
20284                    + " procState=" + item.processState
20285                    + " foreground=" + item.foregroundActivities
20286                    + " type=" + app.adjType + " source=" + app.adjSource
20287                    + " target=" + app.adjTarget);
20288        }
20289
20290        return success;
20291    }
20292
20293    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20294        final UidRecord.ChangeItem pendingChange;
20295        if (uidRec == null || uidRec.pendingChange == null) {
20296            if (mPendingUidChanges.size() == 0) {
20297                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20298                        "*** Enqueueing dispatch uid changed!");
20299                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20300            }
20301            final int NA = mAvailUidChanges.size();
20302            if (NA > 0) {
20303                pendingChange = mAvailUidChanges.remove(NA-1);
20304                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20305                        "Retrieving available item: " + pendingChange);
20306            } else {
20307                pendingChange = new UidRecord.ChangeItem();
20308                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20309                        "Allocating new item: " + pendingChange);
20310            }
20311            if (uidRec != null) {
20312                uidRec.pendingChange = pendingChange;
20313                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20314                    // If this uid is going away, and we haven't yet reported it is gone,
20315                    // then do so now.
20316                    change = UidRecord.CHANGE_GONE_IDLE;
20317                }
20318            } else if (uid < 0) {
20319                throw new IllegalArgumentException("No UidRecord or uid");
20320            }
20321            pendingChange.uidRecord = uidRec;
20322            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20323            mPendingUidChanges.add(pendingChange);
20324        } else {
20325            pendingChange = uidRec.pendingChange;
20326            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20327                change = UidRecord.CHANGE_GONE_IDLE;
20328            }
20329        }
20330        pendingChange.change = change;
20331        pendingChange.processState = uidRec != null
20332                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20333    }
20334
20335    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20336            String authority) {
20337        if (app == null) return;
20338        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20339            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20340            if (userState == null) return;
20341            final long now = SystemClock.elapsedRealtime();
20342            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20343            if (lastReported == null || lastReported < now - 60 * 1000L) {
20344                mUsageStatsService.reportContentProviderUsage(
20345                        authority, providerPkgName, app.userId);
20346                userState.mProviderLastReportedFg.put(authority, now);
20347            }
20348        }
20349    }
20350
20351    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20352        if (DEBUG_USAGE_STATS) {
20353            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20354                    + "] state changes: old = " + app.setProcState + ", new = "
20355                    + app.curProcState);
20356        }
20357        if (mUsageStatsService == null) {
20358            return;
20359        }
20360        boolean isInteraction;
20361        // To avoid some abuse patterns, we are going to be careful about what we consider
20362        // to be an app interaction.  Being the top activity doesn't count while the display
20363        // is sleeping, nor do short foreground services.
20364        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20365            isInteraction = true;
20366            app.fgInteractionTime = 0;
20367        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20368            if (app.fgInteractionTime == 0) {
20369                app.fgInteractionTime = nowElapsed;
20370                isInteraction = false;
20371            } else {
20372                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20373            }
20374        } else {
20375            isInteraction = app.curProcState
20376                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20377            app.fgInteractionTime = 0;
20378        }
20379        if (isInteraction && (!app.reportedInteraction
20380                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20381            app.interactionEventTime = nowElapsed;
20382            String[] packages = app.getPackageList();
20383            if (packages != null) {
20384                for (int i = 0; i < packages.length; i++) {
20385                    mUsageStatsService.reportEvent(packages[i], app.userId,
20386                            UsageEvents.Event.SYSTEM_INTERACTION);
20387                }
20388            }
20389        }
20390        app.reportedInteraction = isInteraction;
20391        if (!isInteraction) {
20392            app.interactionEventTime = 0;
20393        }
20394    }
20395
20396    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20397        if (proc.thread != null) {
20398            if (proc.baseProcessTracker != null) {
20399                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20400            }
20401        }
20402    }
20403
20404    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20405            ProcessRecord TOP_APP, boolean doingAll, long now) {
20406        if (app.thread == null) {
20407            return false;
20408        }
20409
20410        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20411
20412        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20413    }
20414
20415    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20416            boolean oomAdj) {
20417        if (isForeground != proc.foregroundServices) {
20418            proc.foregroundServices = isForeground;
20419            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20420                    proc.info.uid);
20421            if (isForeground) {
20422                if (curProcs == null) {
20423                    curProcs = new ArrayList<ProcessRecord>();
20424                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20425                }
20426                if (!curProcs.contains(proc)) {
20427                    curProcs.add(proc);
20428                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20429                            proc.info.packageName, proc.info.uid);
20430                }
20431            } else {
20432                if (curProcs != null) {
20433                    if (curProcs.remove(proc)) {
20434                        mBatteryStatsService.noteEvent(
20435                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20436                                proc.info.packageName, proc.info.uid);
20437                        if (curProcs.size() <= 0) {
20438                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20439                        }
20440                    }
20441                }
20442            }
20443            if (oomAdj) {
20444                updateOomAdjLocked();
20445            }
20446        }
20447    }
20448
20449    private final ActivityRecord resumedAppLocked() {
20450        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20451        String pkg;
20452        int uid;
20453        if (act != null) {
20454            pkg = act.packageName;
20455            uid = act.info.applicationInfo.uid;
20456        } else {
20457            pkg = null;
20458            uid = -1;
20459        }
20460        // Has the UID or resumed package name changed?
20461        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20462                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20463            if (mCurResumedPackage != null) {
20464                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20465                        mCurResumedPackage, mCurResumedUid);
20466            }
20467            mCurResumedPackage = pkg;
20468            mCurResumedUid = uid;
20469            if (mCurResumedPackage != null) {
20470                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20471                        mCurResumedPackage, mCurResumedUid);
20472            }
20473        }
20474        return act;
20475    }
20476
20477    final boolean updateOomAdjLocked(ProcessRecord app) {
20478        final ActivityRecord TOP_ACT = resumedAppLocked();
20479        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20480        final boolean wasCached = app.cached;
20481
20482        mAdjSeq++;
20483
20484        // This is the desired cached adjusment we want to tell it to use.
20485        // If our app is currently cached, we know it, and that is it.  Otherwise,
20486        // we don't know it yet, and it needs to now be cached we will then
20487        // need to do a complete oom adj.
20488        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20489                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20490        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20491                SystemClock.uptimeMillis());
20492        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20493            // Changed to/from cached state, so apps after it in the LRU
20494            // list may also be changed.
20495            updateOomAdjLocked();
20496        }
20497        return success;
20498    }
20499
20500    final void updateOomAdjLocked() {
20501        final ActivityRecord TOP_ACT = resumedAppLocked();
20502        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20503        final long now = SystemClock.uptimeMillis();
20504        final long nowElapsed = SystemClock.elapsedRealtime();
20505        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20506        final int N = mLruProcesses.size();
20507
20508        if (false) {
20509            RuntimeException e = new RuntimeException();
20510            e.fillInStackTrace();
20511            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20512        }
20513
20514        // Reset state in all uid records.
20515        for (int i=mActiveUids.size()-1; i>=0; i--) {
20516            final UidRecord uidRec = mActiveUids.valueAt(i);
20517            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20518                    "Starting update of " + uidRec);
20519            uidRec.reset();
20520        }
20521
20522        mStackSupervisor.rankTaskLayersIfNeeded();
20523
20524        mAdjSeq++;
20525        mNewNumServiceProcs = 0;
20526        mNewNumAServiceProcs = 0;
20527
20528        final int emptyProcessLimit;
20529        final int cachedProcessLimit;
20530        if (mProcessLimit <= 0) {
20531            emptyProcessLimit = cachedProcessLimit = 0;
20532        } else if (mProcessLimit == 1) {
20533            emptyProcessLimit = 1;
20534            cachedProcessLimit = 0;
20535        } else {
20536            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20537            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20538        }
20539
20540        // Let's determine how many processes we have running vs.
20541        // how many slots we have for background processes; we may want
20542        // to put multiple processes in a slot of there are enough of
20543        // them.
20544        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20545                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20546        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20547        if (numEmptyProcs > cachedProcessLimit) {
20548            // If there are more empty processes than our limit on cached
20549            // processes, then use the cached process limit for the factor.
20550            // This ensures that the really old empty processes get pushed
20551            // down to the bottom, so if we are running low on memory we will
20552            // have a better chance at keeping around more cached processes
20553            // instead of a gazillion empty processes.
20554            numEmptyProcs = cachedProcessLimit;
20555        }
20556        int emptyFactor = numEmptyProcs/numSlots;
20557        if (emptyFactor < 1) emptyFactor = 1;
20558        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20559        if (cachedFactor < 1) cachedFactor = 1;
20560        int stepCached = 0;
20561        int stepEmpty = 0;
20562        int numCached = 0;
20563        int numEmpty = 0;
20564        int numTrimming = 0;
20565
20566        mNumNonCachedProcs = 0;
20567        mNumCachedHiddenProcs = 0;
20568
20569        // First update the OOM adjustment for each of the
20570        // application processes based on their current state.
20571        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20572        int nextCachedAdj = curCachedAdj+1;
20573        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20574        int nextEmptyAdj = curEmptyAdj+2;
20575        for (int i=N-1; i>=0; i--) {
20576            ProcessRecord app = mLruProcesses.get(i);
20577            if (!app.killedByAm && app.thread != null) {
20578                app.procStateChanged = false;
20579                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20580
20581                // If we haven't yet assigned the final cached adj
20582                // to the process, do that now.
20583                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20584                    switch (app.curProcState) {
20585                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20586                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20587                            // This process is a cached process holding activities...
20588                            // assign it the next cached value for that type, and then
20589                            // step that cached level.
20590                            app.curRawAdj = curCachedAdj;
20591                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20592                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20593                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20594                                    + ")");
20595                            if (curCachedAdj != nextCachedAdj) {
20596                                stepCached++;
20597                                if (stepCached >= cachedFactor) {
20598                                    stepCached = 0;
20599                                    curCachedAdj = nextCachedAdj;
20600                                    nextCachedAdj += 2;
20601                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20602                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20603                                    }
20604                                }
20605                            }
20606                            break;
20607                        default:
20608                            // For everything else, assign next empty cached process
20609                            // level and bump that up.  Note that this means that
20610                            // long-running services that have dropped down to the
20611                            // cached level will be treated as empty (since their process
20612                            // state is still as a service), which is what we want.
20613                            app.curRawAdj = curEmptyAdj;
20614                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20615                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20616                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20617                                    + ")");
20618                            if (curEmptyAdj != nextEmptyAdj) {
20619                                stepEmpty++;
20620                                if (stepEmpty >= emptyFactor) {
20621                                    stepEmpty = 0;
20622                                    curEmptyAdj = nextEmptyAdj;
20623                                    nextEmptyAdj += 2;
20624                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20625                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20626                                    }
20627                                }
20628                            }
20629                            break;
20630                    }
20631                }
20632
20633                applyOomAdjLocked(app, true, now, nowElapsed);
20634
20635                // Count the number of process types.
20636                switch (app.curProcState) {
20637                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20638                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20639                        mNumCachedHiddenProcs++;
20640                        numCached++;
20641                        if (numCached > cachedProcessLimit) {
20642                            app.kill("cached #" + numCached, true);
20643                        }
20644                        break;
20645                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20646                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20647                                && app.lastActivityTime < oldTime) {
20648                            app.kill("empty for "
20649                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20650                                    / 1000) + "s", true);
20651                        } else {
20652                            numEmpty++;
20653                            if (numEmpty > emptyProcessLimit) {
20654                                app.kill("empty #" + numEmpty, true);
20655                            }
20656                        }
20657                        break;
20658                    default:
20659                        mNumNonCachedProcs++;
20660                        break;
20661                }
20662
20663                if (app.isolated && app.services.size() <= 0) {
20664                    // If this is an isolated process, and there are no
20665                    // services running in it, then the process is no longer
20666                    // needed.  We agressively kill these because we can by
20667                    // definition not re-use the same process again, and it is
20668                    // good to avoid having whatever code was running in them
20669                    // left sitting around after no longer needed.
20670                    app.kill("isolated not needed", true);
20671                } else {
20672                    // Keeping this process, update its uid.
20673                    final UidRecord uidRec = app.uidRecord;
20674                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20675                        uidRec.curProcState = app.curProcState;
20676                    }
20677                }
20678
20679                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20680                        && !app.killedByAm) {
20681                    numTrimming++;
20682                }
20683            }
20684        }
20685
20686        mNumServiceProcs = mNewNumServiceProcs;
20687
20688        // Now determine the memory trimming level of background processes.
20689        // Unfortunately we need to start at the back of the list to do this
20690        // properly.  We only do this if the number of background apps we
20691        // are managing to keep around is less than half the maximum we desire;
20692        // if we are keeping a good number around, we'll let them use whatever
20693        // memory they want.
20694        final int numCachedAndEmpty = numCached + numEmpty;
20695        int memFactor;
20696        if (numCached <= ProcessList.TRIM_CACHED_APPS
20697                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20698            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20699                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20700            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20701                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20702            } else {
20703                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20704            }
20705        } else {
20706            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20707        }
20708        // We always allow the memory level to go up (better).  We only allow it to go
20709        // down if we are in a state where that is allowed, *and* the total number of processes
20710        // has gone down since last time.
20711        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20712                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20713                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20714        if (memFactor > mLastMemoryLevel) {
20715            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20716                memFactor = mLastMemoryLevel;
20717                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20718            }
20719        }
20720        if (memFactor != mLastMemoryLevel) {
20721            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20722        }
20723        mLastMemoryLevel = memFactor;
20724        mLastNumProcesses = mLruProcesses.size();
20725        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20726        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20727        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20728            if (mLowRamStartTime == 0) {
20729                mLowRamStartTime = now;
20730            }
20731            int step = 0;
20732            int fgTrimLevel;
20733            switch (memFactor) {
20734                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20735                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20736                    break;
20737                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20738                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20739                    break;
20740                default:
20741                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20742                    break;
20743            }
20744            int factor = numTrimming/3;
20745            int minFactor = 2;
20746            if (mHomeProcess != null) minFactor++;
20747            if (mPreviousProcess != null) minFactor++;
20748            if (factor < minFactor) factor = minFactor;
20749            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20750            for (int i=N-1; i>=0; i--) {
20751                ProcessRecord app = mLruProcesses.get(i);
20752                if (allChanged || app.procStateChanged) {
20753                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20754                    app.procStateChanged = false;
20755                }
20756                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20757                        && !app.killedByAm) {
20758                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20759                        try {
20760                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20761                                    "Trimming memory of " + app.processName + " to " + curLevel);
20762                            app.thread.scheduleTrimMemory(curLevel);
20763                        } catch (RemoteException e) {
20764                        }
20765                        if (false) {
20766                            // For now we won't do this; our memory trimming seems
20767                            // to be good enough at this point that destroying
20768                            // activities causes more harm than good.
20769                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20770                                    && app != mHomeProcess && app != mPreviousProcess) {
20771                                // Need to do this on its own message because the stack may not
20772                                // be in a consistent state at this point.
20773                                // For these apps we will also finish their activities
20774                                // to help them free memory.
20775                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20776                            }
20777                        }
20778                    }
20779                    app.trimMemoryLevel = curLevel;
20780                    step++;
20781                    if (step >= factor) {
20782                        step = 0;
20783                        switch (curLevel) {
20784                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20785                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20786                                break;
20787                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20788                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20789                                break;
20790                        }
20791                    }
20792                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20793                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20794                            && app.thread != null) {
20795                        try {
20796                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20797                                    "Trimming memory of heavy-weight " + app.processName
20798                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20799                            app.thread.scheduleTrimMemory(
20800                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20801                        } catch (RemoteException e) {
20802                        }
20803                    }
20804                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20805                } else {
20806                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20807                            || app.systemNoUi) && app.pendingUiClean) {
20808                        // If this application is now in the background and it
20809                        // had done UI, then give it the special trim level to
20810                        // have it free UI resources.
20811                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20812                        if (app.trimMemoryLevel < level && app.thread != null) {
20813                            try {
20814                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20815                                        "Trimming memory of bg-ui " + app.processName
20816                                        + " to " + level);
20817                                app.thread.scheduleTrimMemory(level);
20818                            } catch (RemoteException e) {
20819                            }
20820                        }
20821                        app.pendingUiClean = false;
20822                    }
20823                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20824                        try {
20825                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20826                                    "Trimming memory of fg " + app.processName
20827                                    + " to " + fgTrimLevel);
20828                            app.thread.scheduleTrimMemory(fgTrimLevel);
20829                        } catch (RemoteException e) {
20830                        }
20831                    }
20832                    app.trimMemoryLevel = fgTrimLevel;
20833                }
20834            }
20835        } else {
20836            if (mLowRamStartTime != 0) {
20837                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20838                mLowRamStartTime = 0;
20839            }
20840            for (int i=N-1; i>=0; i--) {
20841                ProcessRecord app = mLruProcesses.get(i);
20842                if (allChanged || app.procStateChanged) {
20843                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20844                    app.procStateChanged = false;
20845                }
20846                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20847                        || app.systemNoUi) && app.pendingUiClean) {
20848                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20849                            && app.thread != null) {
20850                        try {
20851                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20852                                    "Trimming memory of ui hidden " + app.processName
20853                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20854                            app.thread.scheduleTrimMemory(
20855                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20856                        } catch (RemoteException e) {
20857                        }
20858                    }
20859                    app.pendingUiClean = false;
20860                }
20861                app.trimMemoryLevel = 0;
20862            }
20863        }
20864
20865        if (mAlwaysFinishActivities) {
20866            // Need to do this on its own message because the stack may not
20867            // be in a consistent state at this point.
20868            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20869        }
20870
20871        if (allChanged) {
20872            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20873        }
20874
20875        // Update from any uid changes.
20876        for (int i=mActiveUids.size()-1; i>=0; i--) {
20877            final UidRecord uidRec = mActiveUids.valueAt(i);
20878            int uidChange = UidRecord.CHANGE_PROCSTATE;
20879            if (uidRec.setProcState != uidRec.curProcState) {
20880                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20881                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20882                        + " to " + uidRec.curProcState);
20883                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20884                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20885                        uidRec.lastBackgroundTime = nowElapsed;
20886                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20887                            // Note: the background settle time is in elapsed realtime, while
20888                            // the handler time base is uptime.  All this means is that we may
20889                            // stop background uids later than we had intended, but that only
20890                            // happens because the device was sleeping so we are okay anyway.
20891                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20892                        }
20893                    }
20894                } else {
20895                    if (uidRec.idle) {
20896                        uidChange = UidRecord.CHANGE_ACTIVE;
20897                        uidRec.idle = false;
20898                    }
20899                    uidRec.lastBackgroundTime = 0;
20900                }
20901                uidRec.setProcState = uidRec.curProcState;
20902                enqueueUidChangeLocked(uidRec, -1, uidChange);
20903                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20904            }
20905        }
20906
20907        if (mProcessStats.shouldWriteNowLocked(now)) {
20908            mHandler.post(new Runnable() {
20909                @Override public void run() {
20910                    synchronized (ActivityManagerService.this) {
20911                        mProcessStats.writeStateAsyncLocked();
20912                    }
20913                }
20914            });
20915        }
20916
20917        if (DEBUG_OOM_ADJ) {
20918            final long duration = SystemClock.uptimeMillis() - now;
20919            if (false) {
20920                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20921                        new RuntimeException("here").fillInStackTrace());
20922            } else {
20923                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20924            }
20925        }
20926    }
20927
20928    final void idleUids() {
20929        synchronized (this) {
20930            final long nowElapsed = SystemClock.elapsedRealtime();
20931            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20932            long nextTime = 0;
20933            for (int i=mActiveUids.size()-1; i>=0; i--) {
20934                final UidRecord uidRec = mActiveUids.valueAt(i);
20935                final long bgTime = uidRec.lastBackgroundTime;
20936                if (bgTime > 0 && !uidRec.idle) {
20937                    if (bgTime <= maxBgTime) {
20938                        uidRec.idle = true;
20939                        doStopUidLocked(uidRec.uid, uidRec);
20940                    } else {
20941                        if (nextTime == 0 || nextTime > bgTime) {
20942                            nextTime = bgTime;
20943                        }
20944                    }
20945                }
20946            }
20947            if (nextTime > 0) {
20948                mHandler.removeMessages(IDLE_UIDS_MSG);
20949                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20950                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20951            }
20952        }
20953    }
20954
20955    final void runInBackgroundDisabled(int uid) {
20956        synchronized (this) {
20957            UidRecord uidRec = mActiveUids.get(uid);
20958            if (uidRec != null) {
20959                // This uid is actually running...  should it be considered background now?
20960                if (uidRec.idle) {
20961                    doStopUidLocked(uidRec.uid, uidRec);
20962                }
20963            } else {
20964                // This uid isn't actually running...  still send a report about it being "stopped".
20965                doStopUidLocked(uid, null);
20966            }
20967        }
20968    }
20969
20970    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20971        mServices.stopInBackgroundLocked(uid);
20972        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20973    }
20974
20975    final void trimApplications() {
20976        synchronized (this) {
20977            int i;
20978
20979            // First remove any unused application processes whose package
20980            // has been removed.
20981            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20982                final ProcessRecord app = mRemovedProcesses.get(i);
20983                if (app.activities.size() == 0
20984                        && app.curReceiver == null && app.services.size() == 0) {
20985                    Slog.i(
20986                        TAG, "Exiting empty application process "
20987                        + app.toShortString() + " ("
20988                        + (app.thread != null ? app.thread.asBinder() : null)
20989                        + ")\n");
20990                    if (app.pid > 0 && app.pid != MY_PID) {
20991                        app.kill("empty", false);
20992                    } else {
20993                        try {
20994                            app.thread.scheduleExit();
20995                        } catch (Exception e) {
20996                            // Ignore exceptions.
20997                        }
20998                    }
20999                    cleanUpApplicationRecordLocked(app, false, true, -1);
21000                    mRemovedProcesses.remove(i);
21001
21002                    if (app.persistent) {
21003                        addAppLocked(app.info, false, null /* ABI override */);
21004                    }
21005                }
21006            }
21007
21008            // Now update the oom adj for all processes.
21009            updateOomAdjLocked();
21010        }
21011    }
21012
21013    /** This method sends the specified signal to each of the persistent apps */
21014    public void signalPersistentProcesses(int sig) throws RemoteException {
21015        if (sig != Process.SIGNAL_USR1) {
21016            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21017        }
21018
21019        synchronized (this) {
21020            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21021                    != PackageManager.PERMISSION_GRANTED) {
21022                throw new SecurityException("Requires permission "
21023                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21024            }
21025
21026            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21027                ProcessRecord r = mLruProcesses.get(i);
21028                if (r.thread != null && r.persistent) {
21029                    Process.sendSignal(r.pid, sig);
21030                }
21031            }
21032        }
21033    }
21034
21035    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21036        if (proc == null || proc == mProfileProc) {
21037            proc = mProfileProc;
21038            profileType = mProfileType;
21039            clearProfilerLocked();
21040        }
21041        if (proc == null) {
21042            return;
21043        }
21044        try {
21045            proc.thread.profilerControl(false, null, profileType);
21046        } catch (RemoteException e) {
21047            throw new IllegalStateException("Process disappeared");
21048        }
21049    }
21050
21051    private void clearProfilerLocked() {
21052        if (mProfileFd != null) {
21053            try {
21054                mProfileFd.close();
21055            } catch (IOException e) {
21056            }
21057        }
21058        mProfileApp = null;
21059        mProfileProc = null;
21060        mProfileFile = null;
21061        mProfileType = 0;
21062        mAutoStopProfiler = false;
21063        mSamplingInterval = 0;
21064    }
21065
21066    public boolean profileControl(String process, int userId, boolean start,
21067            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21068
21069        try {
21070            synchronized (this) {
21071                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21072                // its own permission.
21073                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21074                        != PackageManager.PERMISSION_GRANTED) {
21075                    throw new SecurityException("Requires permission "
21076                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21077                }
21078
21079                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21080                    throw new IllegalArgumentException("null profile info or fd");
21081                }
21082
21083                ProcessRecord proc = null;
21084                if (process != null) {
21085                    proc = findProcessLocked(process, userId, "profileControl");
21086                }
21087
21088                if (start && (proc == null || proc.thread == null)) {
21089                    throw new IllegalArgumentException("Unknown process: " + process);
21090                }
21091
21092                if (start) {
21093                    stopProfilerLocked(null, 0);
21094                    setProfileApp(proc.info, proc.processName, profilerInfo);
21095                    mProfileProc = proc;
21096                    mProfileType = profileType;
21097                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21098                    try {
21099                        fd = fd.dup();
21100                    } catch (IOException e) {
21101                        fd = null;
21102                    }
21103                    profilerInfo.profileFd = fd;
21104                    proc.thread.profilerControl(start, profilerInfo, profileType);
21105                    fd = null;
21106                    mProfileFd = null;
21107                } else {
21108                    stopProfilerLocked(proc, profileType);
21109                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21110                        try {
21111                            profilerInfo.profileFd.close();
21112                        } catch (IOException e) {
21113                        }
21114                    }
21115                }
21116
21117                return true;
21118            }
21119        } catch (RemoteException e) {
21120            throw new IllegalStateException("Process disappeared");
21121        } finally {
21122            if (profilerInfo != null && profilerInfo.profileFd != null) {
21123                try {
21124                    profilerInfo.profileFd.close();
21125                } catch (IOException e) {
21126                }
21127            }
21128        }
21129    }
21130
21131    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21132        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21133                userId, true, ALLOW_FULL_ONLY, callName, null);
21134        ProcessRecord proc = null;
21135        try {
21136            int pid = Integer.parseInt(process);
21137            synchronized (mPidsSelfLocked) {
21138                proc = mPidsSelfLocked.get(pid);
21139            }
21140        } catch (NumberFormatException e) {
21141        }
21142
21143        if (proc == null) {
21144            ArrayMap<String, SparseArray<ProcessRecord>> all
21145                    = mProcessNames.getMap();
21146            SparseArray<ProcessRecord> procs = all.get(process);
21147            if (procs != null && procs.size() > 0) {
21148                proc = procs.valueAt(0);
21149                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21150                    for (int i=1; i<procs.size(); i++) {
21151                        ProcessRecord thisProc = procs.valueAt(i);
21152                        if (thisProc.userId == userId) {
21153                            proc = thisProc;
21154                            break;
21155                        }
21156                    }
21157                }
21158            }
21159        }
21160
21161        return proc;
21162    }
21163
21164    public boolean dumpHeap(String process, int userId, boolean managed,
21165            String path, ParcelFileDescriptor fd) throws RemoteException {
21166
21167        try {
21168            synchronized (this) {
21169                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21170                // its own permission (same as profileControl).
21171                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21172                        != PackageManager.PERMISSION_GRANTED) {
21173                    throw new SecurityException("Requires permission "
21174                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21175                }
21176
21177                if (fd == null) {
21178                    throw new IllegalArgumentException("null fd");
21179                }
21180
21181                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21182                if (proc == null || proc.thread == null) {
21183                    throw new IllegalArgumentException("Unknown process: " + process);
21184                }
21185
21186                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21187                if (!isDebuggable) {
21188                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21189                        throw new SecurityException("Process not debuggable: " + proc);
21190                    }
21191                }
21192
21193                proc.thread.dumpHeap(managed, path, fd);
21194                fd = null;
21195                return true;
21196            }
21197        } catch (RemoteException e) {
21198            throw new IllegalStateException("Process disappeared");
21199        } finally {
21200            if (fd != null) {
21201                try {
21202                    fd.close();
21203                } catch (IOException e) {
21204                }
21205            }
21206        }
21207    }
21208
21209    @Override
21210    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21211            String reportPackage) {
21212        if (processName != null) {
21213            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21214                    "setDumpHeapDebugLimit()");
21215        } else {
21216            synchronized (mPidsSelfLocked) {
21217                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21218                if (proc == null) {
21219                    throw new SecurityException("No process found for calling pid "
21220                            + Binder.getCallingPid());
21221                }
21222                if (!Build.IS_DEBUGGABLE
21223                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21224                    throw new SecurityException("Not running a debuggable build");
21225                }
21226                processName = proc.processName;
21227                uid = proc.uid;
21228                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21229                    throw new SecurityException("Package " + reportPackage + " is not running in "
21230                            + proc);
21231                }
21232            }
21233        }
21234        synchronized (this) {
21235            if (maxMemSize > 0) {
21236                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21237            } else {
21238                if (uid != 0) {
21239                    mMemWatchProcesses.remove(processName, uid);
21240                } else {
21241                    mMemWatchProcesses.getMap().remove(processName);
21242                }
21243            }
21244        }
21245    }
21246
21247    @Override
21248    public void dumpHeapFinished(String path) {
21249        synchronized (this) {
21250            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21251                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21252                        + " does not match last pid " + mMemWatchDumpPid);
21253                return;
21254            }
21255            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21256                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21257                        + " does not match last path " + mMemWatchDumpFile);
21258                return;
21259            }
21260            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21261            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21262        }
21263    }
21264
21265    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21266    public void monitor() {
21267        synchronized (this) { }
21268    }
21269
21270    void onCoreSettingsChange(Bundle settings) {
21271        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21272            ProcessRecord processRecord = mLruProcesses.get(i);
21273            try {
21274                if (processRecord.thread != null) {
21275                    processRecord.thread.setCoreSettings(settings);
21276                }
21277            } catch (RemoteException re) {
21278                /* ignore */
21279            }
21280        }
21281    }
21282
21283    // Multi-user methods
21284
21285    /**
21286     * Start user, if its not already running, but don't bring it to foreground.
21287     */
21288    @Override
21289    public boolean startUserInBackground(final int userId) {
21290        return mUserController.startUser(userId, /* foreground */ false);
21291    }
21292
21293    @Override
21294    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21295        return mUserController.unlockUser(userId, token, secret, listener);
21296    }
21297
21298    @Override
21299    public boolean switchUser(final int targetUserId) {
21300        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21301        UserInfo currentUserInfo;
21302        UserInfo targetUserInfo;
21303        synchronized (this) {
21304            int currentUserId = mUserController.getCurrentUserIdLocked();
21305            currentUserInfo = mUserController.getUserInfo(currentUserId);
21306            targetUserInfo = mUserController.getUserInfo(targetUserId);
21307            if (targetUserInfo == null) {
21308                Slog.w(TAG, "No user info for user #" + targetUserId);
21309                return false;
21310            }
21311            if (!targetUserInfo.supportsSwitchTo()) {
21312                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21313                return false;
21314            }
21315            if (targetUserInfo.isManagedProfile()) {
21316                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21317                return false;
21318            }
21319            mUserController.setTargetUserIdLocked(targetUserId);
21320        }
21321        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21322        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21323        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21324        return true;
21325    }
21326
21327    void scheduleStartProfilesLocked() {
21328        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21329            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21330                    DateUtils.SECOND_IN_MILLIS);
21331        }
21332    }
21333
21334    @Override
21335    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21336        return mUserController.stopUser(userId, force, callback);
21337    }
21338
21339    @Override
21340    public UserInfo getCurrentUser() {
21341        return mUserController.getCurrentUser();
21342    }
21343
21344    @Override
21345    public boolean isUserRunning(int userId, int flags) {
21346        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21347                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21348            String msg = "Permission Denial: isUserRunning() from pid="
21349                    + Binder.getCallingPid()
21350                    + ", uid=" + Binder.getCallingUid()
21351                    + " requires " + INTERACT_ACROSS_USERS;
21352            Slog.w(TAG, msg);
21353            throw new SecurityException(msg);
21354        }
21355        synchronized (this) {
21356            return mUserController.isUserRunningLocked(userId, flags);
21357        }
21358    }
21359
21360    @Override
21361    public int[] getRunningUserIds() {
21362        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21363                != PackageManager.PERMISSION_GRANTED) {
21364            String msg = "Permission Denial: isUserRunning() from pid="
21365                    + Binder.getCallingPid()
21366                    + ", uid=" + Binder.getCallingUid()
21367                    + " requires " + INTERACT_ACROSS_USERS;
21368            Slog.w(TAG, msg);
21369            throw new SecurityException(msg);
21370        }
21371        synchronized (this) {
21372            return mUserController.getStartedUserArrayLocked();
21373        }
21374    }
21375
21376    @Override
21377    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21378        mUserController.registerUserSwitchObserver(observer);
21379    }
21380
21381    @Override
21382    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21383        mUserController.unregisterUserSwitchObserver(observer);
21384    }
21385
21386    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21387        if (info == null) return null;
21388        ApplicationInfo newInfo = new ApplicationInfo(info);
21389        newInfo.initForUser(userId);
21390        return newInfo;
21391    }
21392
21393    public boolean isUserStopped(int userId) {
21394        synchronized (this) {
21395            return mUserController.getStartedUserStateLocked(userId) == null;
21396        }
21397    }
21398
21399    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21400        if (aInfo == null
21401                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21402            return aInfo;
21403        }
21404
21405        ActivityInfo info = new ActivityInfo(aInfo);
21406        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21407        return info;
21408    }
21409
21410    private boolean processSanityChecksLocked(ProcessRecord process) {
21411        if (process == null || process.thread == null) {
21412            return false;
21413        }
21414
21415        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21416        if (!isDebuggable) {
21417            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21418                return false;
21419            }
21420        }
21421
21422        return true;
21423    }
21424
21425    public boolean startBinderTracking() throws RemoteException {
21426        synchronized (this) {
21427            mBinderTransactionTrackingEnabled = true;
21428            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21429            // permission (same as profileControl).
21430            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21431                    != PackageManager.PERMISSION_GRANTED) {
21432                throw new SecurityException("Requires permission "
21433                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21434            }
21435
21436            for (int i = 0; i < mLruProcesses.size(); i++) {
21437                ProcessRecord process = mLruProcesses.get(i);
21438                if (!processSanityChecksLocked(process)) {
21439                    continue;
21440                }
21441                try {
21442                    process.thread.startBinderTracking();
21443                } catch (RemoteException e) {
21444                    Log.v(TAG, "Process disappared");
21445                }
21446            }
21447            return true;
21448        }
21449    }
21450
21451    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21452        try {
21453            synchronized (this) {
21454                mBinderTransactionTrackingEnabled = false;
21455                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21456                // permission (same as profileControl).
21457                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21458                        != PackageManager.PERMISSION_GRANTED) {
21459                    throw new SecurityException("Requires permission "
21460                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21461                }
21462
21463                if (fd == null) {
21464                    throw new IllegalArgumentException("null fd");
21465                }
21466
21467                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21468                pw.println("Binder transaction traces for all processes.\n");
21469                for (ProcessRecord process : mLruProcesses) {
21470                    if (!processSanityChecksLocked(process)) {
21471                        continue;
21472                    }
21473
21474                    pw.println("Traces for process: " + process.processName);
21475                    pw.flush();
21476                    try {
21477                        TransferPipe tp = new TransferPipe();
21478                        try {
21479                            process.thread.stopBinderTrackingAndDump(
21480                                    tp.getWriteFd().getFileDescriptor());
21481                            tp.go(fd.getFileDescriptor());
21482                        } finally {
21483                            tp.kill();
21484                        }
21485                    } catch (IOException e) {
21486                        pw.println("Failure while dumping IPC traces from " + process +
21487                                ".  Exception: " + e);
21488                        pw.flush();
21489                    } catch (RemoteException e) {
21490                        pw.println("Got a RemoteException while dumping IPC traces from " +
21491                                process + ".  Exception: " + e);
21492                        pw.flush();
21493                    }
21494                }
21495                fd = null;
21496                return true;
21497            }
21498        } finally {
21499            if (fd != null) {
21500                try {
21501                    fd.close();
21502                } catch (IOException e) {
21503                }
21504            }
21505        }
21506    }
21507
21508    private final class LocalService extends ActivityManagerInternal {
21509        @Override
21510        public void onWakefulnessChanged(int wakefulness) {
21511            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21512        }
21513
21514        @Override
21515        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21516                String processName, String abiOverride, int uid, Runnable crashHandler) {
21517            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21518                    processName, abiOverride, uid, crashHandler);
21519        }
21520
21521        @Override
21522        public SleepToken acquireSleepToken(String tag) {
21523            Preconditions.checkNotNull(tag);
21524
21525            ComponentName requestedVrService = null;
21526            ComponentName callingVrActivity = null;
21527            int userId = -1;
21528            synchronized (ActivityManagerService.this) {
21529                if (mFocusedActivity != null) {
21530                    requestedVrService = mFocusedActivity.requestedVrComponent;
21531                    callingVrActivity = mFocusedActivity.info.getComponentName();
21532                    userId = mFocusedActivity.userId;
21533                }
21534            }
21535
21536            if (requestedVrService != null) {
21537                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21538            }
21539
21540            synchronized (ActivityManagerService.this) {
21541                SleepTokenImpl token = new SleepTokenImpl(tag);
21542                mSleepTokens.add(token);
21543                updateSleepIfNeededLocked();
21544                return token;
21545            }
21546        }
21547
21548        @Override
21549        public ComponentName getHomeActivityForUser(int userId) {
21550            synchronized (ActivityManagerService.this) {
21551                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21552                return homeActivity == null ? null : homeActivity.realActivity;
21553            }
21554        }
21555
21556        @Override
21557        public void onUserRemoved(int userId) {
21558            synchronized (ActivityManagerService.this) {
21559                ActivityManagerService.this.onUserStoppedLocked(userId);
21560            }
21561        }
21562
21563        @Override
21564        public void onLocalVoiceInteractionStarted(IBinder activity,
21565                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21566            synchronized (ActivityManagerService.this) {
21567                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21568                        voiceSession, voiceInteractor);
21569            }
21570        }
21571
21572        @Override
21573        public void notifyStartingWindowDrawn() {
21574            synchronized (ActivityManagerService.this) {
21575                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21576            }
21577        }
21578
21579        @Override
21580        public void notifyAppTransitionStarting(int reason) {
21581            synchronized (ActivityManagerService.this) {
21582                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21583            }
21584        }
21585
21586        @Override
21587        public void notifyAppTransitionFinished() {
21588            synchronized (ActivityManagerService.this) {
21589                mStackSupervisor.notifyAppTransitionDone();
21590            }
21591        }
21592
21593        @Override
21594        public void notifyAppTransitionCancelled() {
21595            synchronized (ActivityManagerService.this) {
21596                mStackSupervisor.notifyAppTransitionDone();
21597            }
21598        }
21599
21600        @Override
21601        public List<IBinder> getTopVisibleActivities() {
21602            synchronized (ActivityManagerService.this) {
21603                return mStackSupervisor.getTopVisibleActivities();
21604            }
21605        }
21606
21607        @Override
21608        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21609            synchronized (ActivityManagerService.this) {
21610                mStackSupervisor.setDockedStackMinimized(minimized);
21611            }
21612        }
21613
21614        @Override
21615        public void killForegroundAppsForUser(int userHandle) {
21616            synchronized (ActivityManagerService.this) {
21617                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21618                final int NP = mProcessNames.getMap().size();
21619                for (int ip = 0; ip < NP; ip++) {
21620                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21621                    final int NA = apps.size();
21622                    for (int ia = 0; ia < NA; ia++) {
21623                        final ProcessRecord app = apps.valueAt(ia);
21624                        if (app.persistent) {
21625                            // We don't kill persistent processes.
21626                            continue;
21627                        }
21628                        if (app.removed) {
21629                            procs.add(app);
21630                        } else if (app.userId == userHandle && app.foregroundActivities) {
21631                            app.removed = true;
21632                            procs.add(app);
21633                        }
21634                    }
21635                }
21636
21637                final int N = procs.size();
21638                for (int i = 0; i < N; i++) {
21639                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21640                }
21641            }
21642        }
21643
21644        @Override
21645        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21646            if (!(target instanceof PendingIntentRecord)) {
21647                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21648                return;
21649            }
21650            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21651        }
21652    }
21653
21654    private final class SleepTokenImpl extends SleepToken {
21655        private final String mTag;
21656        private final long mAcquireTime;
21657
21658        public SleepTokenImpl(String tag) {
21659            mTag = tag;
21660            mAcquireTime = SystemClock.uptimeMillis();
21661        }
21662
21663        @Override
21664        public void release() {
21665            synchronized (ActivityManagerService.this) {
21666                if (mSleepTokens.remove(this)) {
21667                    updateSleepIfNeededLocked();
21668                }
21669            }
21670        }
21671
21672        @Override
21673        public String toString() {
21674            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21675        }
21676    }
21677
21678    /**
21679     * An implementation of IAppTask, that allows an app to manage its own tasks via
21680     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21681     * only the process that calls getAppTasks() can call the AppTask methods.
21682     */
21683    class AppTaskImpl extends IAppTask.Stub {
21684        private int mTaskId;
21685        private int mCallingUid;
21686
21687        public AppTaskImpl(int taskId, int callingUid) {
21688            mTaskId = taskId;
21689            mCallingUid = callingUid;
21690        }
21691
21692        private void checkCaller() {
21693            if (mCallingUid != Binder.getCallingUid()) {
21694                throw new SecurityException("Caller " + mCallingUid
21695                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21696            }
21697        }
21698
21699        @Override
21700        public void finishAndRemoveTask() {
21701            checkCaller();
21702
21703            synchronized (ActivityManagerService.this) {
21704                long origId = Binder.clearCallingIdentity();
21705                try {
21706                    // We remove the task from recents to preserve backwards
21707                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21708                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21709                    }
21710                } finally {
21711                    Binder.restoreCallingIdentity(origId);
21712                }
21713            }
21714        }
21715
21716        @Override
21717        public ActivityManager.RecentTaskInfo getTaskInfo() {
21718            checkCaller();
21719
21720            synchronized (ActivityManagerService.this) {
21721                long origId = Binder.clearCallingIdentity();
21722                try {
21723                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21724                    if (tr == null) {
21725                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21726                    }
21727                    return createRecentTaskInfoFromTaskRecord(tr);
21728                } finally {
21729                    Binder.restoreCallingIdentity(origId);
21730                }
21731            }
21732        }
21733
21734        @Override
21735        public void moveToFront() {
21736            checkCaller();
21737            // Will bring task to front if it already has a root activity.
21738            final long origId = Binder.clearCallingIdentity();
21739            try {
21740                synchronized (this) {
21741                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21742                }
21743            } finally {
21744                Binder.restoreCallingIdentity(origId);
21745            }
21746        }
21747
21748        @Override
21749        public int startActivity(IBinder whoThread, String callingPackage,
21750                Intent intent, String resolvedType, Bundle bOptions) {
21751            checkCaller();
21752
21753            int callingUser = UserHandle.getCallingUserId();
21754            TaskRecord tr;
21755            IApplicationThread appThread;
21756            synchronized (ActivityManagerService.this) {
21757                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21758                if (tr == null) {
21759                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21760                }
21761                appThread = ApplicationThreadNative.asInterface(whoThread);
21762                if (appThread == null) {
21763                    throw new IllegalArgumentException("Bad app thread " + appThread);
21764                }
21765            }
21766            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21767                    resolvedType, null, null, null, null, 0, 0, null, null,
21768                    null, bOptions, false, callingUser, null, tr);
21769        }
21770
21771        @Override
21772        public void setExcludeFromRecents(boolean exclude) {
21773            checkCaller();
21774
21775            synchronized (ActivityManagerService.this) {
21776                long origId = Binder.clearCallingIdentity();
21777                try {
21778                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21779                    if (tr == null) {
21780                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21781                    }
21782                    Intent intent = tr.getBaseIntent();
21783                    if (exclude) {
21784                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21785                    } else {
21786                        intent.setFlags(intent.getFlags()
21787                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21788                    }
21789                } finally {
21790                    Binder.restoreCallingIdentity(origId);
21791                }
21792            }
21793        }
21794    }
21795
21796    /**
21797     * Kill processes for the user with id userId and that depend on the package named packageName
21798     */
21799    @Override
21800    public void killPackageDependents(String packageName, int userId) {
21801        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21802        if (packageName == null) {
21803            throw new NullPointerException(
21804                    "Cannot kill the dependents of a package without its name.");
21805        }
21806
21807        long callingId = Binder.clearCallingIdentity();
21808        IPackageManager pm = AppGlobals.getPackageManager();
21809        int pkgUid = -1;
21810        try {
21811            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21812        } catch (RemoteException e) {
21813        }
21814        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21815            throw new IllegalArgumentException(
21816                    "Cannot kill dependents of non-existing package " + packageName);
21817        }
21818        try {
21819            synchronized(this) {
21820                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21821                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21822                        "dep: " + packageName);
21823            }
21824        } finally {
21825            Binder.restoreCallingIdentity(callingId);
21826        }
21827    }
21828}
21829